UNPKG

@graphql-codegen/kotlin

Version:

GraphQL Code Generator plugin for generating Kotlin code based on a GraphQL schema

228 lines (226 loc) • 9.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KotlinResolversVisitor = exports.KOTLIN_SCALARS = void 0; const graphql_1 = require("graphql"); const java_common_1 = require("@graphql-codegen/java-common"); const visitor_plugin_common_1 = require("@graphql-codegen/visitor-plugin-common"); exports.KOTLIN_SCALARS = { ID: 'Any', String: 'String', Boolean: 'Boolean', Int: 'Int', Float: 'Float', }; class KotlinResolversVisitor extends visitor_plugin_common_1.BaseVisitor { constructor(rawConfig, _schema, defaultPackageName) { super(rawConfig, { enumValues: rawConfig.enumValues || {}, listType: rawConfig.listType || 'Iterable', withTypes: rawConfig.withTypes || false, package: rawConfig.package || defaultPackageName, scalars: (0, visitor_plugin_common_1.buildScalarsFromConfig)(_schema, rawConfig, exports.KOTLIN_SCALARS), omitJvmStatic: rawConfig.omitJvmStatic || false, }); this._schema = _schema; } getPackageName() { return `package ${this.config.package}\n`; } getEnumValue(enumName, enumOption) { if (this.config.enumValues[enumName] && typeof this.config.enumValues[enumName] === 'object' && this.config.enumValues[enumName][enumOption]) { return this.config.enumValues[enumName][enumOption]; } return enumOption; } EnumValueDefinition(node) { return (enumName) => { return (0, visitor_plugin_common_1.indent)(`${this.convertName(node, { useTypesPrefix: false, transformUnderscore: true, })}("${this.getEnumValue(enumName, node.name.value)}")`); }; } EnumTypeDefinition(node) { const comment = (0, visitor_plugin_common_1.transformComment)(node.description, 0); const enumName = this.convertName(node.name); const enumValues = (0, visitor_plugin_common_1.indentMultiline)(node.values.map(enumValue => enumValue(node.name.value)).join(',\n') + ';', 2); return `${comment}enum class ${enumName}(val label: String) { ${enumValues} companion object { ${this.config.omitJvmStatic ? '' : '@JvmStatic'} fun valueOfLabel(label: String): ${enumName}? { return values().find { it.label == label } } } }`; } resolveInputFieldType(typeNode) { const innerType = (0, visitor_plugin_common_1.getBaseTypeNode)(typeNode); const schemaType = this._schema.getType(innerType.name.value); const isArray = typeNode.kind === graphql_1.Kind.LIST_TYPE || (typeNode.kind === graphql_1.Kind.NON_NULL_TYPE && typeNode.type.kind === graphql_1.Kind.LIST_TYPE); let result = null; const nullable = typeNode.kind !== graphql_1.Kind.NON_NULL_TYPE; if ((0, graphql_1.isScalarType)(schemaType)) { if (this.config.scalars[schemaType.name]) { result = { baseType: this.scalars[schemaType.name], typeName: this.scalars[schemaType.name], isScalar: true, isArray, nullable, }; } else { result = { isArray, baseType: 'Any', typeName: 'Any', isScalar: true, nullable }; } } else if ((0, graphql_1.isInputObjectType)(schemaType)) { const convertedName = this.convertName(schemaType.name); const typeName = convertedName.endsWith('Input') ? convertedName : `${convertedName}Input`; result = { baseType: typeName, typeName, isScalar: false, isArray, nullable, }; } else if ((0, graphql_1.isEnumType)(schemaType) || (0, graphql_1.isObjectType)(schemaType)) { result = { isArray, baseType: this.convertName(schemaType.name), typeName: this.convertName(schemaType.name), isScalar: true, nullable, }; } else { result = { isArray, baseType: 'Any', typeName: 'Any', isScalar: true, nullable }; } if (result) { result.typeName = (0, java_common_1.wrapTypeWithModifiers)(result.typeName, typeNode, this.config.listType); } return result; } buildInputTransfomer(name, inputValueArray) { const classMembers = inputValueArray .map(arg => { const typeToUse = this.resolveInputFieldType(arg.type); const initialValue = this.initialValue(typeToUse.typeName, arg.defaultValue); const initial = initialValue ? ` = ${initialValue}` : typeToUse.nullable ? ' = null' : ''; return (0, visitor_plugin_common_1.indent)(`val ${arg.name.value}: ${typeToUse.typeName}${typeToUse.nullable ? '?' : ''}${initial}`, 2); }) .join(',\n'); let suppress = ''; const ctorSet = inputValueArray .map(arg => { const typeToUse = this.resolveInputFieldType(arg.type); const initialValue = this.initialValue(typeToUse.typeName, arg.defaultValue); const fallback = initialValue ? ` ?: ${initialValue}` : ''; if (typeToUse.isArray && !typeToUse.isScalar) { suppress = '@Suppress("UNCHECKED_CAST")\n '; return (0, visitor_plugin_common_1.indent)(`args["${arg.name.value}"]${typeToUse.nullable || fallback ? '?' : '!!'}.let { ${arg.name.value} -> (${arg.name.value} as List<Map<String, Any>>).map { ${typeToUse.baseType}(it) } }${fallback}`, 3); } if (typeToUse.isScalar) { return (0, visitor_plugin_common_1.indent)(`args["${arg.name.value}"] as ${typeToUse.typeName}${typeToUse.nullable || fallback ? '?' : ''}${fallback}`, 3); } if (typeToUse.nullable || fallback) { suppress = '@Suppress("UNCHECKED_CAST")\n '; return (0, visitor_plugin_common_1.indent)(`args["${arg.name.value}"]?.let { ${typeToUse.typeName}(it as Map<String, Any>) }${fallback}`, 3); } suppress = '@Suppress("UNCHECKED_CAST")\n '; return (0, visitor_plugin_common_1.indent)(`${typeToUse.typeName}(args["${arg.name.value}"] as Map<String, Any>)`, 3); }) .join(',\n'); // language=kotlin return `data class ${name}( ${classMembers} ) { ${suppress}constructor(args: Map<String, Any>) : this( ${ctorSet} ) }`; } buildTypeTransfomer(name, typeValueArray) { const classMembers = typeValueArray .map(arg => { if (!arg.type) { return ''; } const typeToUse = this.resolveInputFieldType(arg.type); return (0, visitor_plugin_common_1.indent)(`val ${arg.name.value}: ${typeToUse.typeName}${typeToUse.nullable ? '?' : ''}`, 2); }) .join(',\n'); // language=kotlin return `data class ${name}( ${classMembers} )`; } initialValue(typeName, defaultValue) { if (defaultValue) { if (defaultValue.kind === 'IntValue' || defaultValue.kind === 'FloatValue' || defaultValue.kind === 'BooleanValue') { return `${defaultValue.value}`; } if (defaultValue.kind === 'StringValue') { return `"""${defaultValue.value}""".trimIndent()`; } if (defaultValue.kind === 'EnumValue') { return `${typeName}.${defaultValue.value}`; } if (defaultValue.kind === 'ListValue') { const list = defaultValue.values .map(value => { return this.initialValue(typeName, value); }) .join(', '); return `listOf(${list})`; } // Variable // ObjectValue // ObjectField } return undefined; } FieldDefinition(node) { if (node.arguments.length > 0) { const inputTransformer = (typeName) => { const transformerName = `${this.convertName(typeName, { useTypesPrefix: true, })}${this.convertName(node.name.value, { useTypesPrefix: false })}Args`; return this.buildInputTransfomer(transformerName, node.arguments); }; return { node, inputTransformer }; } return { node }; } InputObjectTypeDefinition(node) { const convertedName = this.convertName(node); const name = convertedName.endsWith('Input') ? convertedName : `${convertedName}Input`; return this.buildInputTransfomer(name, node.fields); } ObjectTypeDefinition(node) { const name = this.convertName(node); const fields = node.fields; const fieldNodes = []; const argsTypes = []; fields.forEach(({ node, inputTransformer }) => { if (node) { fieldNodes.push(node); } if (inputTransformer) { argsTypes.push(inputTransformer); } }); let types = argsTypes.map(f => f(node.name.value)).filter(r => r); if (this.config.withTypes) { types = types.concat([this.buildTypeTransfomer(name, fieldNodes)]); } return types.join('\n'); } } exports.KotlinResolversVisitor = KotlinResolversVisitor;