Skip to content

Commit e5394f0

Browse files
smyrickdariuszkuc
authored andcommitted
feat: accept list of package and move hooks (#39)
supportedPackages is now a list so you can pass in multiple paths the monadResolver was moved to the hooks as it works the same was as the other hooks
1 parent 7111f0e commit e5394f0

File tree

11 files changed

+42
-32
lines changed

11 files changed

+42
-32
lines changed
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
package com.expedia.graphql.schema
22

3-
import com.expedia.graphql.schema.generator.completableFutureResolver
43
import com.expedia.graphql.schema.hooks.NoopSchemaGeneratorHooks
54
import com.expedia.graphql.schema.hooks.SchemaGeneratorHooks
65
import graphql.schema.DataFetcherFactory
7-
import kotlin.reflect.KType
86

97
/**
108
* Settings for generating the schema.
119
*/
1210
data class SchemaGeneratorConfig(
13-
val supportedPackages: String,
11+
val supportedPackages: List<String>,
1412
val topLevelQueryName: String = "TopLevelQuery",
1513
val topLevelMutationName: String = "TopLevelMutation",
1614
val hooks: SchemaGeneratorHooks = NoopSchemaGeneratorHooks(),
17-
val monadResolver: (KType) -> KType = completableFutureResolver,
1815
val dataFetcherFactory: DataFetcherFactory<*>? = null
1916
)

src/main/kotlin/com/expedia/graphql/schema/exceptions/TypeNotSupportedException.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package com.expedia.graphql.schema.exceptions
33
/**
44
* Thrown when the generator does not have a type to map to in GraphQL or in the hooks.
55
*/
6-
class TypeNotSupportedException(typeName: String, packageName: String)
7-
: RuntimeException("Cannot convert $typeName since it is outside the supported package $packageName")
6+
class TypeNotSupportedException(typeName: String, packageList: List<String>)
7+
: RuntimeException("Cannot convert $typeName since it is outside the supported packages $packageList")

src/main/kotlin/com/expedia/graphql/schema/generator/SchemaGenerator.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ internal class SchemaGenerator(
143143
val hookDataFetcher = config.hooks.didGenerateDataFetcher(fn, dataFetcher)
144144
builder.dataFetcher(hookDataFetcher)
145145
}
146-
builder.type(graphQLTypeOf(config.monadResolver(fn.returnType)) as GraphQLOutputType)
146+
147+
val monadType = config.hooks.willResolveMonad(fn.returnType)
148+
builder.type(graphQLTypeOf(monadType) as GraphQLOutputType)
147149
return builder.build()
148150
}
149151

src/main/kotlin/com/expedia/graphql/schema/generator/TypesCache.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import kotlin.reflect.jvm.jvmErasure
1313

1414
internal data class TypesCacheKey(val type: KType, val inputType: Boolean)
1515

16-
internal class TypesCache(private val supportedPackages: String) {
16+
internal class TypesCache(private val supportedPackages: List<String>) {
1717

1818
private val cache: MutableMap<String, KGraphQLType> = mutableMapOf()
1919

@@ -73,7 +73,11 @@ internal class TypesCache(private val supportedPackages: String) {
7373
@Throws(TypeNotSupportedException::class)
7474
private fun throwIfTypeIsNotSupported(type: KType) {
7575
val qualifiedName = type.jvmErasure.qualifiedName ?: ""
76-
val comesFromSupportedPackageName = qualifiedName.startsWith(supportedPackages)
76+
77+
val comesFromSupportedPackageName = supportedPackages.any {
78+
qualifiedName.startsWith(it)
79+
}
80+
7781
if (!comesFromSupportedPackageName) {
7882
throw TypeNotSupportedException(qualifiedName, supportedPackages)
7983
}

src/main/kotlin/com/expedia/graphql/schema/generator/typeMappers.kt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import graphql.Scalars
44
import graphql.schema.GraphQLType
55
import java.math.BigDecimal
66
import java.math.BigInteger
7-
import java.util.concurrent.CompletableFuture
87
import kotlin.reflect.KClass
98
import kotlin.reflect.KType
109

@@ -27,11 +26,3 @@ internal fun getGraphQLClassName(klass: KClass<*>, inputClass: Boolean): String?
2726
}
2827

2928
private fun getInputClassName(className: String) = "${className}Input"
30-
31-
internal val completableFutureResolver = { type: KType ->
32-
if (type.classifier == CompletableFuture::class) {
33-
type.arguments.firstOrNull()?.type ?: type
34-
} else {
35-
type
36-
}
37-
}

src/main/kotlin/com/expedia/graphql/schema/hooks/NoopSchemaGeneratorHooks.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import graphql.schema.DataFetcher
44
import graphql.schema.GraphQLFieldDefinition
55
import graphql.schema.GraphQLSchema
66
import graphql.schema.GraphQLType
7+
import java.util.concurrent.CompletableFuture
78
import kotlin.reflect.KFunction
89
import kotlin.reflect.KProperty
910
import kotlin.reflect.KType
@@ -20,6 +21,13 @@ open class NoopSchemaGeneratorHooks : SchemaGeneratorHooks {
2021

2122
override fun willGenerateGraphQLType(type: KType): GraphQLType? = null
2223

24+
override fun willResolveMonad(type: KType): KType =
25+
if (type.classifier == CompletableFuture::class) {
26+
type.arguments.firstOrNull()?.type ?: type
27+
} else {
28+
type
29+
}
30+
2331
override fun isValidProperty(property: KProperty<*>) = true
2432

2533
override fun isValidFunction(function: KFunction<*>) = true

src/main/kotlin/com/expedia/graphql/schema/hooks/SchemaGeneratorHooks.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ interface SchemaGeneratorHooks {
2626
*/
2727
fun willGenerateGraphQLType(type: KType): GraphQLType?
2828

29+
/**
30+
* Called before resolving a Monad or Future type to its wrapped KType.
31+
* This allows for a custom resolver on how to extract the wrapped value.
32+
*/
33+
fun willResolveMonad(type: KType): KType
34+
2935
/**
3036
* Called when looking at the KClass properties to determine if it valid for adding to the generated schema.
3137
* If any filter returns false, it is rejected.

src/test/kotlin/com/expedia/graphql/schema/dataFetchers/CustomDataFetcherTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import kotlin.test.assertEquals
1515
class CustomDataFetcherTests {
1616
@Test
1717
fun `Custom DataFetcher can be used on functions`() {
18-
val config = SchemaGeneratorConfig(supportedPackages = "com.expedia", dataFetcherFactory = PetDataFetcherFactory())
18+
val config = SchemaGeneratorConfig(supportedPackages = listOf("com.expedia"), dataFetcherFactory = PetDataFetcherFactory())
1919
val schema = toSchema(listOf(TopLevelObjectDef(AnimalQuery())), config = config)
2020

2121
val animalType = schema.getObjectType("Animal")

src/test/kotlin/com/expedia/graphql/schema/generator/SchemaGeneratorAsyncTests.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.expedia.graphql.schema.generator
22

33
import com.expedia.graphql.TopLevelObjectDef
4-
import com.expedia.graphql.schema.SchemaGeneratorConfig
4+
import com.expedia.graphql.schema.getTestSchemaConfigWithHooks
5+
import com.expedia.graphql.schema.hooks.NoopSchemaGeneratorHooks
56
import com.expedia.graphql.schema.testSchemaConfig
67
import com.expedia.graphql.toSchema
78
import graphql.schema.GraphQLNonNull
@@ -15,14 +16,14 @@ import kotlin.test.assertEquals
1516

1617
class SchemaGeneratorAsyncTests {
1718

18-
private val rxJavaMonadResolver: (KType) -> KType = { type ->
19-
when (type.classifier) {
19+
private class MonadHooks : NoopSchemaGeneratorHooks() {
20+
override fun willResolveMonad(type: KType): KType = when (type.classifier) {
2021
Observable::class, Single::class, Maybe::class -> type.arguments.firstOrNull()?.type
2122
else -> type
2223
} ?: type
2324
}
24-
private val testSchemaConfigWithRxJavaMonads =
25-
SchemaGeneratorConfig(supportedPackages = "com.expedia", monadResolver = rxJavaMonadResolver)
25+
26+
private val configWithRxJavaMonads = getTestSchemaConfigWithHooks(hooks = MonadHooks())
2627

2728
@Test
2829
fun `SchemaGenerator strips type argument from CompletableFuture to support async servlet`() {
@@ -34,23 +35,23 @@ class SchemaGeneratorAsyncTests {
3435

3536
@Test
3637
fun `SchemaGenerator strips type argument from RxJava2 Observable`() {
37-
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = testSchemaConfigWithRxJavaMonads)
38+
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = configWithRxJavaMonads)
3839
val returnTypeName =
3940
(schema.getObjectType("TopLevelQuery").getFieldDefinition("asynchronouslyDo").type as GraphQLNonNull).wrappedType.name
4041
assertEquals("Int", returnTypeName)
4142
}
4243

4344
@Test
4445
fun `SchemaGenerator strips type argument from RxJava2 Single`() {
45-
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = testSchemaConfigWithRxJavaMonads)
46+
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = configWithRxJavaMonads)
4647
val returnTypeName =
4748
(schema.getObjectType("TopLevelQuery").getFieldDefinition("asynchronouslyDoSingle").type as GraphQLNonNull).wrappedType.name
4849
assertEquals("Int", returnTypeName)
4950
}
5051

5152
@Test
5253
fun `SchemaGenerator strips type argument from RxJava2 Maybe`() {
53-
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = testSchemaConfigWithRxJavaMonads)
54+
val schema = toSchema(listOf(TopLevelObjectDef(RxJava2Query())), config = configWithRxJavaMonads)
5455
val returnTypeName =
5556
(schema.getObjectType("TopLevelQuery").getFieldDefinition("maybe").type as GraphQLNonNull).wrappedType.name
5657
assertEquals("Int", returnTypeName)

src/test/kotlin/com/expedia/graphql/schema/generator/TypesCacheTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class TypesCacheTest {
1818

1919
@Test
2020
fun `basic get and put with non input type`() {
21-
val cache = TypesCache("com.expedia.graphql")
21+
val cache = TypesCache(listOf("com.expedia.graphql"))
2222
val cacheKey = TypesCacheKey(MyType::class.starProjectedType, false)
2323
val cacheValue = KGraphQLType(MyType::class, graphQLType)
2424

@@ -31,7 +31,7 @@ class TypesCacheTest {
3131

3232
@Test
3333
fun `basic get and put with input type`() {
34-
val cache = TypesCache("com.expedia.graphql")
34+
val cache = TypesCache(listOf("com.expedia.graphql"))
3535
val cacheKey = TypesCacheKey(MyType::class.starProjectedType, true)
3636
val cacheValue = KGraphQLType(MyType::class, graphQLType)
3737

@@ -44,7 +44,7 @@ class TypesCacheTest {
4444

4545
@Test
4646
fun `verify doesNotContainGraphQLType()`() {
47-
val cache = TypesCache("com.expedia.graphql")
47+
val cache = TypesCache(listOf("com.expedia.graphql"))
4848
val cacheKey = TypesCacheKey(MyType::class.starProjectedType, true)
4949
val cacheValue = KGraphQLType(MyType::class, graphQLType)
5050

0 commit comments

Comments
 (0)