From b5f330181bcf6d18b41b6166c8a86159638e1cfa Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Mon, 29 Apr 2024 07:53:58 -0500 Subject: [PATCH 1/2] feat: include DataFetchingEnvironment in all resolver interface functions --- src/helpers/build-config-with-defaults.ts | 9 ++- src/helpers/build-field-definition.ts | 14 +++-- .../expected.kt | 4 +- .../expected.kt | 56 +++++++++---------- .../codegen.config.ts | 4 +- .../expected.kt | 24 ++++---- .../expected.kt | 26 ++++----- .../expected.kt | 4 +- 8 files changed, 77 insertions(+), 64 deletions(-) diff --git a/src/helpers/build-config-with-defaults.ts b/src/helpers/build-config-with-defaults.ts index e58fd41..644ec93 100644 --- a/src/helpers/build-config-with-defaults.ts +++ b/src/helpers/build-config-with-defaults.ts @@ -15,7 +15,14 @@ export function buildConfigWithDefaults( "com.expediagroup.graphql.generator.annotations.*", ...(config.extraImports ?? []), ], - } as const; + extraResolverArguments: [ + { + argumentName: "dataFetchingEnvironment", + argumentType: "graphql.schema.DataFetchingEnvironment", + }, + ...(config.extraResolverArguments ?? []), + ], + } as const satisfies GraphQLKotlinCodegenConfig; } export type CodegenConfigWithDefaults = ReturnType< diff --git a/src/helpers/build-field-definition.ts b/src/helpers/build-field-definition.ts index 8d4ddcb..e368172 100644 --- a/src/helpers/build-field-definition.ts +++ b/src/helpers/build-field-definition.ts @@ -42,11 +42,17 @@ export function buildFieldDefinition( return `${arg.name.value}: ${typeMetadata.typeName}${arg.type.kind === Kind.NON_NULL_TYPE ? "" : "?"}`; }); const additionalFieldArguments = config.extraResolverArguments - ?.map(({ typeNames, argumentType, argumentName }) => { + ?.map((resolverArgument) => { + const { argumentName, argumentType } = resolverArgument; const shouldIncludeArg = - !typeNames || - typeNames.some((typeName) => typeName === definitionNode.name.value); - return shouldIncludeArg ? `${argumentName}: ${argumentType}` : undefined; + !("typeNames" in resolverArgument) || + !resolverArgument.typeNames || + resolverArgument.typeNames.some( + (typeName) => typeName === definitionNode.name.value, + ); + return shouldUseFunction && shouldIncludeArg + ? `${argumentName}: ${argumentType}` + : undefined; }) .filter(Boolean); const allFieldArguments = existingFieldArguments?.concat( diff --git a/test/unit/should_consolidate_input_and_output_types/expected.kt b/test/unit/should_consolidate_input_and_output_types/expected.kt index 984b0e8..366755a 100644 --- a/test/unit/should_consolidate_input_and_output_types/expected.kt +++ b/test/unit/should_consolidate_input_and_output_types/expected.kt @@ -70,12 +70,12 @@ data class MyTypeToConsolidateInputParent( @GraphQLIgnore interface MyTypeToConsolidateParent2 { - suspend fun field(input: MyTypeToConsolidate): String? = null + suspend fun field(input: MyTypeToConsolidate, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null } @GraphQLIgnore interface MyTypeToConsolidateParent2CompletableFuture { - fun field(input: MyTypeToConsolidate): java.util.concurrent.CompletableFuture + fun field(input: MyTypeToConsolidate, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture } @GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) diff --git a/test/unit/should_generate_field_resolver_interfaces/expected.kt b/test/unit/should_generate_field_resolver_interfaces/expected.kt index f0a6055..310a944 100644 --- a/test/unit/should_generate_field_resolver_interfaces/expected.kt +++ b/test/unit/should_generate_field_resolver_interfaces/expected.kt @@ -4,18 +4,18 @@ import com.expediagroup.graphql.generator.annotations.* @GraphQLIgnore interface Query { - suspend fun nullableField(): FieldType? = null - suspend fun nonNullableField(): FieldType - suspend fun nullableResolver(arg: String): String? = null - suspend fun nonNullableResolver(arg: InputTypeGenerateFieldResolverInterfaces): String + suspend fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): FieldType? = null + suspend fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): FieldType + suspend fun nullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + suspend fun nonNullableResolver(arg: InputTypeGenerateFieldResolverInterfaces, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String } @GraphQLIgnore interface QueryCompletableFuture { - fun nullableField(): java.util.concurrent.CompletableFuture - fun nonNullableField(): java.util.concurrent.CompletableFuture - fun nullableResolver(arg: String): java.util.concurrent.CompletableFuture - fun nonNullableResolver(arg: InputTypeGenerateFieldResolverInterfaces): java.util.concurrent.CompletableFuture + fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nonNullableResolver(arg: InputTypeGenerateFieldResolverInterfaces, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture } @GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.INPUT_OBJECT]) @@ -24,32 +24,32 @@ data class InputTypeGenerateFieldResolverInterfaces( ) interface MyFieldInterface { - suspend fun field1(): String? - suspend fun field2(): String - suspend fun nullableListResolver(arg1: Int?, arg2: Int): List? - suspend fun nonNullableListResolver(arg1: Int, arg2: Int?): List + suspend fun field1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? + suspend fun field2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String + suspend fun nullableListResolver(arg1: Int?, arg2: Int, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): List? + suspend fun nonNullableListResolver(arg1: Int, arg2: Int?, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): List } @GraphQLIgnore interface FieldType : MyFieldInterface { - override suspend fun field1(): String? = null - override suspend fun field2(): String - suspend fun booleanField1(): Boolean? = null - suspend fun booleanField2(): Boolean = false - suspend fun integerField1(): Int? = null - suspend fun integerField2(): Int - override suspend fun nullableListResolver(arg1: Int?, arg2: Int): List? = null - override suspend fun nonNullableListResolver(arg1: Int, arg2: Int?): List = emptyList() + override suspend fun field1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + override suspend fun field2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String + suspend fun booleanField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): Boolean? = null + suspend fun booleanField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): Boolean = false + suspend fun integerField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): Int? = null + suspend fun integerField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): Int + override suspend fun nullableListResolver(arg1: Int?, arg2: Int, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): List? = null + override suspend fun nonNullableListResolver(arg1: Int, arg2: Int?, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): List = emptyList() } @GraphQLIgnore interface FieldTypeCompletableFuture { - fun field1(): java.util.concurrent.CompletableFuture - fun field2(): java.util.concurrent.CompletableFuture - fun booleanField1(): java.util.concurrent.CompletableFuture - fun booleanField2(): java.util.concurrent.CompletableFuture - fun integerField1(): java.util.concurrent.CompletableFuture - fun integerField2(): java.util.concurrent.CompletableFuture - fun nullableListResolver(arg1: Int?, arg2: Int): java.util.concurrent.CompletableFuture?> - fun nonNullableListResolver(arg1: Int, arg2: Int?): java.util.concurrent.CompletableFuture> + fun field1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun field2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun booleanField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun booleanField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun integerField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun integerField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nullableListResolver(arg1: Int?, arg2: Int, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture?> + fun nonNullableListResolver(arg1: Int, arg2: Int?, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture> } diff --git a/test/unit/should_honor_extraResolverArguments_config/codegen.config.ts b/test/unit/should_honor_extraResolverArguments_config/codegen.config.ts index 3556b7e..6906094 100644 --- a/test/unit/should_honor_extraResolverArguments_config/codegen.config.ts +++ b/test/unit/should_honor_extraResolverArguments_config/codegen.config.ts @@ -4,8 +4,8 @@ export default { resolverTypes: ["MyIncludedExtraFieldArgsType"], extraResolverArguments: [ { - argumentName: "dataFetchingEnvironment", - argumentType: "graphql.schema.DataFetchingEnvironment", + argumentName: "myExtraFieldArg", + argumentType: "String", typeNames: ["MyExtraFieldArgsType", "MyIncludedExtraFieldArgsType"], }, ], diff --git a/test/unit/should_honor_extraResolverArguments_config/expected.kt b/test/unit/should_honor_extraResolverArguments_config/expected.kt index 239f8a0..64a985e 100644 --- a/test/unit/should_honor_extraResolverArguments_config/expected.kt +++ b/test/unit/should_honor_extraResolverArguments_config/expected.kt @@ -4,36 +4,36 @@ import com.expediagroup.graphql.generator.annotations.* @GraphQLIgnore interface MyExtraFieldArgsType { - suspend fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null - suspend fun fieldWithArgs(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String + suspend fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): String? = null + suspend fun fieldWithArgs(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): String } @GraphQLIgnore interface MyExtraFieldArgsTypeCompletableFuture { - fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture - fun fieldWithArgs(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): java.util.concurrent.CompletableFuture + fun fieldWithArgs(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): java.util.concurrent.CompletableFuture } @GraphQLIgnore interface MyIncludedExtraFieldArgsType { - suspend fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null - suspend fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + suspend fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): String? = null + suspend fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): String? = null } @GraphQLIgnore interface MyIncludedExtraFieldArgsTypeCompletableFuture { - fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture - fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun myField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): java.util.concurrent.CompletableFuture + fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment, myExtraFieldArg: String): java.util.concurrent.CompletableFuture } @GraphQLIgnore interface MyOtherType { - suspend fun myField(arg: String): String - suspend fun myOtherField(): String? = null + suspend fun myField(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String + suspend fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null } @GraphQLIgnore interface MyOtherTypeCompletableFuture { - fun myField(arg: String): java.util.concurrent.CompletableFuture - fun myOtherField(): java.util.concurrent.CompletableFuture + fun myField(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun myOtherField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture } diff --git a/test/unit/should_honor_resolverTypes_config/expected.kt b/test/unit/should_honor_resolverTypes_config/expected.kt index efa09f7..6dfa8d9 100644 --- a/test/unit/should_honor_resolverTypes_config/expected.kt +++ b/test/unit/should_honor_resolverTypes_config/expected.kt @@ -4,30 +4,30 @@ import com.expediagroup.graphql.generator.annotations.* @GraphQLIgnore interface MyResolverType { - suspend fun nullableField(): String? = null - suspend fun nonNullableField(): String - suspend fun nullableResolver(arg: String): String? = null - suspend fun nonNullableResolver(arg: String): String + suspend fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + suspend fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String + suspend fun nullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + suspend fun nonNullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String } @GraphQLIgnore interface MyResolverTypeCompletableFuture { - fun nullableField(): java.util.concurrent.CompletableFuture - fun nonNullableField(): java.util.concurrent.CompletableFuture - fun nullableResolver(arg: String): java.util.concurrent.CompletableFuture - fun nonNullableResolver(arg: String): java.util.concurrent.CompletableFuture + fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nonNullableResolver(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture } @GraphQLIgnore interface MyIncludedResolverType { - suspend fun nullableField(): String? = null - suspend fun nonNullableField(): String + suspend fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? = null + suspend fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String } @GraphQLIgnore interface MyIncludedResolverTypeCompletableFuture { - fun nullableField(): java.util.concurrent.CompletableFuture - fun nonNullableField(): java.util.concurrent.CompletableFuture + fun nullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture + fun nonNullableField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture } @GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT]) @@ -37,7 +37,7 @@ data class MyExcludedResolverType( ) interface MyIncludedInterface { - suspend fun field(): String? + suspend fun field(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String? } interface MyExcludedInterface { diff --git a/test/unit/should_replace_federation_directives/expected.kt b/test/unit/should_replace_federation_directives/expected.kt index fb52b50..23d18c0 100644 --- a/test/unit/should_replace_federation_directives/expected.kt +++ b/test/unit/should_replace_federation_directives/expected.kt @@ -14,7 +14,7 @@ data class FederatedType( @com.expediagroup.graphql.generator.federation.directives.KeyDirective(com.expediagroup.graphql.generator.federation.directives.FieldSet("some other field")) @GraphQLIgnore interface FederatedTypeResolver { - suspend fun field(arg: String): String + suspend fun field(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): String @com.expediagroup.graphql.generator.federation.directives.ExternalDirective val field2: String? } @@ -23,7 +23,7 @@ interface FederatedTypeResolver { @com.expediagroup.graphql.generator.federation.directives.KeyDirective(com.expediagroup.graphql.generator.federation.directives.FieldSet("some other field")) @GraphQLIgnore interface FederatedTypeResolverCompletableFuture { - fun field(arg: String): java.util.concurrent.CompletableFuture + fun field(arg: String, dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture @com.expediagroup.graphql.generator.federation.directives.ExternalDirective val field2: java.util.concurrent.CompletableFuture } From 79f2ed60962e77d484b423b3a871b9c546036c62 Mon Sep 17 00:00:00 2001 From: Dan Adajian Date: Mon, 29 Apr 2024 08:01:13 -0500 Subject: [PATCH 2/2] add deprecation note --- src/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config.ts b/src/config.ts index fa9f41b..2ee2e23 100644 --- a/src/config.ts +++ b/src/config.ts @@ -111,6 +111,7 @@ export const configSchema = object({ /** * Denotes extra arguments that should be added to functions on resolver classes. * @example [{ typeNames: ["MyType", "MyType2"], argumentName: "myArgument", argumentValue: "myValue" }] + * @deprecated This will be removed in a future release now that DataFetchingEnvironment is added to functions by default. */ extraResolverArguments: optional( array(