From cb48d1d8397151a8d91cfc39643b812c247190fd Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Thu, 14 Mar 2024 15:22:26 -0500 Subject: [PATCH] feat: add externalUnionsAsInterfaces config (#13) --- src/config.ts | 5 +++++ src/helpers/build-annotations.ts | 4 ++-- src/helpers/build-type-metadata.ts | 13 ++++++++++--- .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../expected.kt | 0 .../schema.graphql | 0 .../codegen.config.ts | 2 ++ .../expected.kt | 4 +++- .../schema.graphql | 3 +++ 18 files changed, 25 insertions(+), 6 deletions(-) rename test/unit/{should_annotate_enums_properly => should_generate_enums_properly}/expected.kt (100%) rename test/unit/{should_annotate_enums_properly => should_generate_enums_properly}/schema.graphql (100%) rename test/unit/{should_annotate_input_types_properly => should_generate_input_types_properly}/expected.kt (100%) rename test/unit/{should_annotate_input_types_properly => should_generate_input_types_properly}/schema.graphql (100%) rename test/unit/{should_annotate_multi-union_types_properly => should_generate_multi-union_types_properly}/expected.kt (100%) rename test/unit/{should_annotate_multi-union_types_properly => should_generate_multi-union_types_properly}/schema.graphql (100%) rename test/unit/{should_annotate_non-nullable_union_list_types_properly => should_generate_non-nullable_union_list_types_properly}/expected.kt (100%) rename test/unit/{should_annotate_non-nullable_union_list_types_properly => should_generate_non-nullable_union_list_types_properly}/schema.graphql (100%) rename test/unit/{should_annotate_union_list_types_properly => should_generate_union_list_types_properly}/expected.kt (100%) rename test/unit/{should_annotate_union_list_types_properly => should_generate_union_list_types_properly}/schema.graphql (100%) rename test/unit/{should_annotate_union_types_properly => should_generate_union_types_properly}/expected.kt (100%) rename test/unit/{should_annotate_union_types_properly => should_generate_union_types_properly}/schema.graphql (100%) diff --git a/src/config.ts b/src/config.ts index 91892c6..f0c214a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -34,6 +34,11 @@ export const configSchema = object({ * @description If `MyType` depends on `MyDependentType1` and `MyDependentType2`, we can allow `MyDependentType2` to be imported externally by including its import in `extraImports` and omitting it in the `dependentTypesInScope` list: `["MyType", "MyDependentType1"]` */ dependentTypesInScope: optional(array(string())), + /** + * Denotes Kotlin classes representing union types to be treated as interfaces rather than annotation classes. + * This should be used for types outside `dependentTypesInScope` that are not generated by the plugin. + */ + externalUnionsAsInterfaces: optional(array(string())), /** * Additional imports to add to the generated file. * @example ["com.example.additional.import.*"] diff --git a/src/helpers/build-annotations.ts b/src/helpers/build-annotations.ts index f396ac2..bd02659 100644 --- a/src/helpers/build-annotations.ts +++ b/src/helpers/build-annotations.ts @@ -55,8 +55,8 @@ export function buildAnnotations({ const directiveAnnotations = definitionNode ? buildDirectiveAnnotations(definitionNode, config, description) : ""; - const unionAnnotation = resolvedType?.annotation - ? `@${resolvedType.annotation}\n` + const unionAnnotation = resolvedType?.unionAnnotation + ? `@${resolvedType.unionAnnotation}\n` : ""; const annotations = [ diff --git a/src/helpers/build-type-metadata.ts b/src/helpers/build-type-metadata.ts index 4509ae9..637555b 100644 --- a/src/helpers/build-type-metadata.ts +++ b/src/helpers/build-type-metadata.ts @@ -25,7 +25,7 @@ import { CodegenConfig } from "../plugin"; export interface TypeMetadata { typeName: string; - annotation?: string; + unionAnnotation?: string; defaultValue: string; isNullable: boolean; } @@ -59,10 +59,17 @@ export function buildTypeMetadata( typeName: buildListType(typeNode, scalarTypeName), }; } else if (isUnionType(schemaType)) { + const shouldTreatUnionAsInterface = + config.externalUnionsAsInterfaces?.includes(schemaType.name); return { ...commonMetadata, - annotation: schemaType.name, - typeName: buildListType(typeNode, "Any"), + unionAnnotation: shouldTreatUnionAsInterface + ? undefined + : schemaType.name, + typeName: buildListType( + typeNode, + shouldTreatUnionAsInterface ? schemaType.name : "Any", + ), }; } else { return { diff --git a/test/unit/should_annotate_enums_properly/expected.kt b/test/unit/should_generate_enums_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_enums_properly/expected.kt rename to test/unit/should_generate_enums_properly/expected.kt diff --git a/test/unit/should_annotate_enums_properly/schema.graphql b/test/unit/should_generate_enums_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_enums_properly/schema.graphql rename to test/unit/should_generate_enums_properly/schema.graphql diff --git a/test/unit/should_annotate_input_types_properly/expected.kt b/test/unit/should_generate_input_types_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_input_types_properly/expected.kt rename to test/unit/should_generate_input_types_properly/expected.kt diff --git a/test/unit/should_annotate_input_types_properly/schema.graphql b/test/unit/should_generate_input_types_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_input_types_properly/schema.graphql rename to test/unit/should_generate_input_types_properly/schema.graphql diff --git a/test/unit/should_annotate_multi-union_types_properly/expected.kt b/test/unit/should_generate_multi-union_types_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_multi-union_types_properly/expected.kt rename to test/unit/should_generate_multi-union_types_properly/expected.kt diff --git a/test/unit/should_annotate_multi-union_types_properly/schema.graphql b/test/unit/should_generate_multi-union_types_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_multi-union_types_properly/schema.graphql rename to test/unit/should_generate_multi-union_types_properly/schema.graphql diff --git a/test/unit/should_annotate_non-nullable_union_list_types_properly/expected.kt b/test/unit/should_generate_non-nullable_union_list_types_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_non-nullable_union_list_types_properly/expected.kt rename to test/unit/should_generate_non-nullable_union_list_types_properly/expected.kt diff --git a/test/unit/should_annotate_non-nullable_union_list_types_properly/schema.graphql b/test/unit/should_generate_non-nullable_union_list_types_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_non-nullable_union_list_types_properly/schema.graphql rename to test/unit/should_generate_non-nullable_union_list_types_properly/schema.graphql diff --git a/test/unit/should_annotate_union_list_types_properly/expected.kt b/test/unit/should_generate_union_list_types_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_union_list_types_properly/expected.kt rename to test/unit/should_generate_union_list_types_properly/expected.kt diff --git a/test/unit/should_annotate_union_list_types_properly/schema.graphql b/test/unit/should_generate_union_list_types_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_union_list_types_properly/schema.graphql rename to test/unit/should_generate_union_list_types_properly/schema.graphql diff --git a/test/unit/should_annotate_union_types_properly/expected.kt b/test/unit/should_generate_union_types_properly/expected.kt similarity index 100% rename from test/unit/should_annotate_union_types_properly/expected.kt rename to test/unit/should_generate_union_types_properly/expected.kt diff --git a/test/unit/should_annotate_union_types_properly/schema.graphql b/test/unit/should_generate_union_types_properly/schema.graphql similarity index 100% rename from test/unit/should_annotate_union_types_properly/schema.graphql rename to test/unit/should_generate_union_types_properly/schema.graphql diff --git a/test/unit/should_honor_dependentTypesInScope_config/codegen.config.ts b/test/unit/should_honor_dependentTypesInScope_config/codegen.config.ts index 12df495..0403aab 100644 --- a/test/unit/should_honor_dependentTypesInScope_config/codegen.config.ts +++ b/test/unit/should_honor_dependentTypesInScope_config/codegen.config.ts @@ -4,7 +4,9 @@ export default { extraImports: [ "com.some.import.TypeOutOfScope", "com.some.import.UnionOutOfScope", + "com.some.import.ExternalUnionAsInterface", ], onlyTypes: ["MyTypeInOnlyTypes"], dependentTypesInScope: ["TypeInScope", "UnionInScope", "Type1"], + externalUnionsAsInterfaces: ["ExternalUnionAsInterface"], } satisfies GraphQLKotlinCodegenConfig; diff --git a/test/unit/should_honor_dependentTypesInScope_config/expected.kt b/test/unit/should_honor_dependentTypesInScope_config/expected.kt index bdc46d9..f36e946 100644 --- a/test/unit/should_honor_dependentTypesInScope_config/expected.kt +++ b/test/unit/should_honor_dependentTypesInScope_config/expected.kt @@ -3,6 +3,7 @@ package com.kotlin.generated import com.expediagroup.graphql.generator.annotations.* import com.some.import.TypeOutOfScope import com.some.import.UnionOutOfScope +import com.some.import.ExternalUnionAsInterface data class MyTypeInOnlyTypes( val field: TypeInScope, @@ -14,7 +15,8 @@ data class TypeInScope( @UnionInScope val unionInScopeField: Any? = null, @UnionOutOfScope - val unionOutOfScopeField: Any? = null + val unionOutOfScopeField: Any? = null, + val externalUnionAsInterfaceField: ExternalUnionAsInterface? = null ) @GraphQLUnion( diff --git a/test/unit/should_honor_dependentTypesInScope_config/schema.graphql b/test/unit/should_honor_dependentTypesInScope_config/schema.graphql index 1d18d54..1d8564a 100644 --- a/test/unit/should_honor_dependentTypesInScope_config/schema.graphql +++ b/test/unit/should_honor_dependentTypesInScope_config/schema.graphql @@ -7,6 +7,7 @@ type TypeInScope { field: String unionInScopeField: UnionInScope unionOutOfScopeField: UnionOutOfScope + externalUnionAsInterfaceField: ExternalUnionAsInterface } type TypeOutOfScope { @@ -17,6 +18,8 @@ union UnionInScope = Type1 union UnionOutOfScope = Type2 +union ExternalUnionAsInterface = Type1 | Type2 + type Type1 { field: String }