Skip to content

Commit 1401099

Browse files
authored
BREAKING(feat(federation)): full @link support (#1816)
### 📝 Description Introduce full `@link` support that includes namespacing and renaming of the imported elements. The `@link` directive allows users to link definitions within the document to external schemas. It is the core feature of the Apollo federation v2. While imported elements still need to have their definitions in the local schema, `@link` allows users to namespace and/or rename those items to avoid any local type conflicts. By default, all external types that are not explicitly imported have to be namespaced using the spec name or a provided custom namespace. Updated `@link` definition ```graphql directive @link(url: String!, as: String, import: [link__Import]) repeatable on SCHEMA scalar link__Import ``` * url - external specification url * as - optional custom namespace * import - list of elements to import, can either be simple Strings (e.g. `@key`) or custom imports that rename elements (e.g. `{ name: "@key", as: "@mykey" }`) By default, `graphql-kotlin` will continue to apply `@link` directive using latest supported federation specification but will only auto-import federation specific directives up to version 2.3 and only if they are present (i.e. applied to an element) in the schema. All new fed v2.4+ won't be included in the auto-imports and instead will be namespaced with the spec name, e.g. `@federation__authenticated`. Users can provide custom `@link` information by providing a schema object with `@LinkDirective` information, e.g. ```kotlin @LinkDirective(url = "https://specs.apollo.dev/federation/v2.3", `as`: "fed", import = [LinkImport(name = "@key", `as` = "@mykey"), LinkImport(name = "@requires")]) class MyCustomLinkSchema ``` Will generate following schema ```graphql schema @link(as: "fed", import : [{name : "@key", as : "@mykey"}, "@requires"], url : "https://specs.apollo.dev/federation/v2.3"){ query: Query } // directive imported with custom name "Space separated list of primary keys needed to access federated object" directive @mykey(fields: fed__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE // directive imported with same name "Specifies required input field set from the base type for a resolver" directive @requires(fields: fed__FieldSet!) on FIELD_DEFINITION // type imported with custom namespace "Federation type representing set of fields" scalar fed__FieldSet ``` When importing custom specifications, in order to be able to identify whether element is part of custom specification, we need to annotate it with new `@LinkedSpec` annotation. All federation directives were updated to rely on this mechanism, e.g. ```kotlin @LinkedSpec(FEDERATION_SPEC) @repeatable @GraphQLDirective( name = KEY_DIRECTIVE_NAME, description = KEY_DIRECTIVE_DESCRIPTION, locations = [DirectiveLocation.OBJECT, DirectiveLocation.INTERFACE] ) annotation class KeyDirective(val fields: FieldSet, val resolvable: Boolean = true) ``` ### 🔗 Related Issues
1 parent e64e80f commit 1401099

File tree

43 files changed

+1261
-493
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1261
-493
lines changed

examples/federation/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
services:
22
router:
3-
image: ghcr.io/apollographql/router:v1.10.1
3+
image: ghcr.io/apollographql/router:v1.29.1
44
volumes:
55
- ./router.yaml:/dist/config/router.yaml
66
- ./supergraph.graphql:/dist/config/supergraph.graphql

examples/federation/supergraph.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
federation_version: =2.4.8
1+
federation_version: =2.4.13
22
subgraphs:
33
products:
44
routing_url: http://products:8080/graphql

generator/graphql-kotlin-federation/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ tasks {
1919
limit {
2020
counter = "INSTRUCTION"
2121
value = "COVEREDRATIO"
22-
minimum = "0.96".toBigDecimal()
22+
minimum = "0.95".toBigDecimal()
2323
}
2424
limit {
2525
counter = "BRANCH"
2626
value = "COVEREDRATIO"
27-
minimum = "0.90".toBigDecimal()
27+
minimum = "0.80".toBigDecimal()
2828
}
2929
}
3030
}

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/FederatedSchemaGeneratorHooks.kt

Lines changed: 191 additions & 52 deletions
Large diffs are not rendered by default.

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/ComposeDirective.kt

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
package com.expediagroup.graphql.generator.federation.directives
1818

1919
import com.expediagroup.graphql.generator.annotations.GraphQLDirective
20-
import graphql.Scalars
2120
import graphql.introspection.Introspection
22-
import graphql.schema.GraphQLArgument
23-
import graphql.schema.GraphQLNonNull
2421

2522
/**
2623
* ```graphql
@@ -37,6 +34,7 @@ import graphql.schema.GraphQLNonNull
3734
* annotation class CustomDirective
3835
*
3936
* @ComposeDirective(name = "custom")
37+
* @LinkDirective()
4038
* class CustomSchema
4139
*
4240
* class SimpleQuery {
@@ -48,7 +46,7 @@ import graphql.schema.GraphQLNonNull
4846
* it will generate following schema
4947
*
5048
* ```graphql
51-
* schema @composeDirective(name: "@myDirective") @link(import : ["@composeDirective", "@extends", "@external", "@inaccessible", "@interfaceObject", "@key", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet"], url : "https://specs.apollo.dev/federation/v2.3"){
49+
* schema @composeDirective(name: "@custom") @link(import : ["@composeDirective", "@extends", "@external", "@inaccessible", "@interfaceObject", "@key", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet"], url : "https://specs.apollo.dev/federation/v2.3"){
5250
* query: Query
5351
* }
5452
*
@@ -61,6 +59,7 @@ import graphql.schema.GraphQLNonNull
6159
*
6260
* @see <a href="https://www.apollographql.com/docs/federation/federated-types/federated-directives/#composedirective">@composeDirective definition</a>
6361
*/
62+
@LinkedSpec(FEDERATION_SPEC)
6463
@Repeatable
6564
@GraphQLDirective(
6665
name = COMPOSE_DIRECTIVE_NAME,
@@ -71,15 +70,3 @@ annotation class ComposeDirective(val name: String)
7170

7271
internal const val COMPOSE_DIRECTIVE_NAME = "composeDirective"
7372
private const val COMPOSE_DIRECTIVE_DESCRIPTION = "Marks underlying custom directive to be included in the Supergraph schema"
74-
75-
internal val COMPOSE_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
76-
.name(COMPOSE_DIRECTIVE_NAME)
77-
.description(COMPOSE_DIRECTIVE_DESCRIPTION)
78-
.validLocations(Introspection.DirectiveLocation.SCHEMA)
79-
.argument(
80-
GraphQLArgument.newArgument()
81-
.name("name")
82-
.type(GraphQLNonNull.nonNull(Scalars.GraphQLString))
83-
)
84-
.repeatable(true)
85-
.build()

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/ContactDirective.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2023 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,10 @@
1717
package com.expediagroup.graphql.generator.federation.directives
1818

1919
import com.expediagroup.graphql.generator.annotations.GraphQLDirective
20+
import graphql.Scalars
2021
import graphql.introspection.Introspection.DirectiveLocation
22+
import graphql.schema.GraphQLArgument
23+
import graphql.schema.GraphQLNonNull
2124

2225
/**
2326
* ```graphql
@@ -65,3 +68,27 @@ annotation class ContactDirective(
6568

6669
internal const val CONTACT_DIRECTIVE_NAME = "contact"
6770
private const val CONTACT_DIRECTIVE_DESCRIPTION = "Provides contact information of the owner responsible for this subgraph schema."
71+
72+
internal val CONTACT_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
73+
.name(CONTACT_DIRECTIVE_NAME)
74+
.description(CONTACT_DIRECTIVE_DESCRIPTION)
75+
.validLocations(DirectiveLocation.SCHEMA)
76+
.argument(
77+
GraphQLArgument.newArgument()
78+
.name("name")
79+
.type(GraphQLNonNull.nonNull(Scalars.GraphQLString))
80+
.build()
81+
)
82+
.argument(
83+
GraphQLArgument.newArgument()
84+
.name("url")
85+
.type(Scalars.GraphQLString)
86+
.build()
87+
)
88+
.argument(
89+
GraphQLArgument.newArgument()
90+
.name("description")
91+
.type(Scalars.GraphQLString)
92+
.build()
93+
)
94+
.build()

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/ExtendsDirective.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2023 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@ import graphql.introspection.Introspection.DirectiveLocation
5252
*
5353
* @see KeyDirective
5454
*/
55+
@LinkedSpec(FEDERATION_SPEC)
5556
@Deprecated(message = "@extends is only required in Federation v1 and can be safely omitted from Federation v2 schemas")
5657
@GraphQLDirective(
5758
name = EXTENDS_DIRECTIVE_NAME,

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/ExternalDirective.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import graphql.introspection.Introspection.DirectiveLocation
6161
* @see KeyDirective
6262
* @see RequiresDirective
6363
*/
64+
@LinkedSpec(FEDERATION_SPEC)
6465
@GraphQLDirective(
6566
name = EXTERNAL_DIRECTIVE_NAME,
6667
description = EXTERNAL_DIRECTIVE_DESCRIPTION,

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/FieldSet.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2023 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
1717
package com.expediagroup.graphql.generator.federation.directives
1818

1919
/**
20-
* Annotation representing _FieldSet scalar type that is used to represent a set of fields.
20+
* Annotation representing FieldSet scalar type that is used to represent a set of fields.
2121
*
2222
* Field set can represent:
2323
* - single field, e.g. "id"
@@ -28,4 +28,5 @@ package com.expediagroup.graphql.generator.federation.directives
2828
*
2929
* @see [com.expediagroup.graphql.generator.federation.types.FIELD_SET_SCALAR_TYPE]
3030
*/
31+
@LinkedSpec(FEDERATION_SPEC)
3132
annotation class FieldSet(val value: String)

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/InaccessibleDirective.kt

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2023 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -68,6 +68,7 @@ import graphql.introspection.Introspection.DirectiveLocation
6868
*
6969
* @see <a href="https://specs.apollo.dev/inaccessible/v0.2">@inaccessible specification</a>
7070
*/
71+
@LinkedSpec(FEDERATION_SPEC)
7172
@GraphQLDirective(
7273
name = INACCESSIBLE_DIRECTIVE_NAME,
7374
description = INACESSIBLE_DIRECTIVE_DESCRIPTION,
@@ -88,20 +89,3 @@ annotation class InaccessibleDirective
8889

8990
internal const val INACCESSIBLE_DIRECTIVE_NAME = "inaccessible"
9091
private const val INACESSIBLE_DIRECTIVE_DESCRIPTION = "Marks location within schema as inaccessible from the GraphQL Gateway"
91-
92-
internal val INACCESSIBLE_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
93-
.name(INACCESSIBLE_DIRECTIVE_NAME)
94-
.description(INACESSIBLE_DIRECTIVE_DESCRIPTION)
95-
.validLocations(
96-
DirectiveLocation.FIELD_DEFINITION,
97-
DirectiveLocation.OBJECT,
98-
DirectiveLocation.INTERFACE,
99-
DirectiveLocation.UNION,
100-
DirectiveLocation.ENUM,
101-
DirectiveLocation.ENUM_VALUE,
102-
DirectiveLocation.SCALAR,
103-
DirectiveLocation.INPUT_OBJECT,
104-
DirectiveLocation.INPUT_FIELD_DEFINITION,
105-
DirectiveLocation.ARGUMENT_DEFINITION
106-
)
107-
.build()

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/InterfaceObjectDirective.kt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import graphql.introspection.Introspection
6767
* }
6868
* ```
6969
*/
70+
@LinkedSpec(FEDERATION_SPEC)
7071
@GraphQLDirective(
7172
name = INTERFACE_OBJECT_DIRECTIVE_NAME,
7273
description = INTERFACE_OBJECT_DIRECTIVE_DESCRIPTION,
@@ -76,9 +77,3 @@ annotation class InterfaceObjectDirective
7677

7778
internal const val INTERFACE_OBJECT_DIRECTIVE_NAME = "interfaceObject"
7879
private const val INTERFACE_OBJECT_DIRECTIVE_DESCRIPTION = "Provides meta information to the router that this entity type is an interface in the supergraph."
79-
80-
internal val INTERFACE_OBJECT_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
81-
.name(INTERFACE_OBJECT_DIRECTIVE_NAME)
82-
.description(INTERFACE_OBJECT_DIRECTIVE_DESCRIPTION)
83-
.validLocations(Introspection.DirectiveLocation.OBJECT)
84-
.build()

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/KeyDirective.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 Expedia, Inc
2+
* Copyright 2023 Expedia, Inc
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,9 +18,11 @@ package com.expediagroup.graphql.generator.federation.directives
1818

1919
import com.expediagroup.graphql.generator.annotations.GraphQLDirective
2020
import com.expediagroup.graphql.generator.federation.types.FIELD_SET_ARGUMENT
21+
import com.expediagroup.graphql.generator.federation.types.fieldSetArgumentDefinition
2122
import graphql.Scalars
2223
import graphql.introspection.Introspection.DirectiveLocation
2324
import graphql.schema.GraphQLArgument
25+
import graphql.schema.GraphQLScalarType
2426

2527
/**
2628
* ```graphql
@@ -89,6 +91,7 @@ import graphql.schema.GraphQLArgument
8991
* @see FieldSet
9092
* @see ExternalDirective
9193
*/
94+
@LinkedSpec(FEDERATION_SPEC)
9295
@Repeatable
9396
@GraphQLDirective(
9497
name = KEY_DIRECTIVE_NAME,
@@ -108,11 +111,11 @@ internal val KEY_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schem
108111
.repeatable(true)
109112
.build()
110113

111-
internal val KEY_DIRECTIVE_TYPE_V2: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
114+
internal fun keyDirectiveDefinition(fieldSetScalar: GraphQLScalarType): graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
112115
.name(KEY_DIRECTIVE_NAME)
113116
.description(KEY_DIRECTIVE_DESCRIPTION)
114117
.validLocations(DirectiveLocation.OBJECT, DirectiveLocation.INTERFACE)
115-
.argument(FIELD_SET_ARGUMENT)
118+
.argument(fieldSetArgumentDefinition(fieldSetScalar))
116119
.argument(
117120
GraphQLArgument.newArgument()
118121
.name("resolvable")

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/directives/LinkDirective.kt

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,36 @@ import graphql.introspection.Introspection.DirectiveLocation
2222
import graphql.schema.GraphQLArgument
2323
import graphql.schema.GraphQLList
2424
import graphql.schema.GraphQLNonNull
25+
import graphql.schema.GraphQLScalarType
2526

26-
const val LINK_SPEC_URL = "https://specs.apollo.dev/link/v1.0/"
27-
const val FEDERATION_SPEC_URL = "https://specs.apollo.dev/federation/v2.3"
27+
const val APOLLO_SPEC_URL = "https://specs.apollo.dev"
28+
29+
const val LINK_SPEC = "link"
30+
const val LINK_SPEC_LATEST_VERSION = "1.0"
31+
const val LINK_SPEC_URL_PREFIX = "$APOLLO_SPEC_URL/$LINK_SPEC"
32+
const val LINK_SPEC_LATEST_URL = "$LINK_SPEC_URL_PREFIX/v$LINK_SPEC_LATEST_VERSION"
33+
34+
const val FEDERATION_SPEC = "federation"
35+
const val FEDERATION_SPEC_LATEST_VERSION = "2.3"
36+
const val FEDERATION_SPEC_URL_PREFIX = "$APOLLO_SPEC_URL/$FEDERATION_SPEC"
37+
const val FEDERATION_SPEC_LATEST_URL = "$FEDERATION_SPEC_URL_PREFIX/v$FEDERATION_SPEC_LATEST_VERSION"
2838

2939
/**
3040
* ```graphql
31-
* directive @link(url: String!, import: [Import]) repeatable on SCHEMA
41+
* directive @link(url: String!, as: String, import: [Import]) repeatable on SCHEMA
3242
* ```
3343
*
3444
* The `@link` directive links definitions within the document to external schemas.
3545
*
36-
* External schemas are identified by their url, which optionally ends with a name and version with the following format: `{NAME}/v{MAJOR}.{MINOR}`
46+
* External schemas are identified by their url, which should end with a specification name and version with the following format: `{NAME}/v{MAJOR}.{MINOR}`, e.g. `url = "https://specs.apollo.dev/federation/v2.3"`.
3747
*
38-
* By default, external types should be namespaced (prefixed with namespace__, e.g. key directive should be namespaced as federation__key) unless they are explicitly imported. `graphql-kotlin`
39-
* automatically imports ALL federation directives to avoid the need for namespacing.
40-
*
41-
* >NOTE: We currently DO NOT support full `@link` directive capability as it requires support for namespacing and renaming imports. This functionality may be added in the future releases. See `@link`
42-
* specification for details.
48+
* External types are associated with the target specification by annotating it with `@LinkedSpec` meta annotation. External types defined in the specification will be automatically namespaced
49+
* (prefixed with `{NAME}__`) unless they are explicitly imported. While both custom namespace (`as`) and import arguments are optional, due to https://github.com/ExpediaGroup/graphql-kotlin/issues/1830
50+
* we currently always require those values to be explicitly provided.
4351
*
4452
* @param url external schema URL
53+
* @param as custom namespace, should default to the specification name specified in the url
54+
* @param import list of imported schema elements
4555
*
4656
* @see <a href="https://specs.apollo.dev/link/v1.0/">@link specification</a>
4757
*/
@@ -51,12 +61,12 @@ const val FEDERATION_SPEC_URL = "https://specs.apollo.dev/federation/v2.3"
5161
description = LINK_DIRECTIVE_DESCRIPTION,
5262
locations = [DirectiveLocation.SCHEMA]
5363
)
54-
annotation class LinkDirective(val url: String, val import: Array<String>)
64+
annotation class LinkDirective(val url: String, val `as`: String, val import: Array<LinkImport>)
5565

5666
internal const val LINK_DIRECTIVE_NAME = "link"
5767
private const val LINK_DIRECTIVE_DESCRIPTION = "Links definitions within the document to external schemas."
5868

59-
internal val LINK_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
69+
internal fun linkDirectiveDefinition(importScalarType: GraphQLScalarType): graphql.schema.GraphQLDirective = graphql.schema.GraphQLDirective.newDirective()
6070
.name(LINK_DIRECTIVE_NAME)
6171
.description(LINK_DIRECTIVE_DESCRIPTION)
6272
.validLocations(DirectiveLocation.SCHEMA)
@@ -65,18 +75,23 @@ internal val LINK_DIRECTIVE_TYPE: graphql.schema.GraphQLDirective = graphql.sche
6575
.name("url")
6676
.type(GraphQLNonNull.nonNull(Scalars.GraphQLString))
6777
)
78+
.argument(
79+
GraphQLArgument.newArgument()
80+
.name("as")
81+
.type(Scalars.GraphQLString)
82+
)
6883
.argument(
6984
GraphQLArgument
7085
.newArgument()
7186
.name("import")
72-
.type(GraphQLList.list(Scalars.GraphQLString))
87+
.type(GraphQLList.list(importScalarType))
7388
)
7489
.repeatable(true)
7590
.build()
7691

77-
internal fun appliedLinkDirective(url: String, imports: List<String> = emptyList()) = LINK_DIRECTIVE_TYPE.toAppliedDirective()
92+
internal fun graphql.schema.GraphQLDirective.toAppliedLinkDirective(url: String, namespace: String? = null, imports: List<String> = emptyList()) = this.toAppliedDirective()
7893
.transform { appliedDirectiveBuilder ->
79-
LINK_DIRECTIVE_TYPE.getArgument("url")
94+
this.getArgument("url")
8095
.toAppliedArgument()
8196
.transform { argumentBuilder ->
8297
argumentBuilder.valueProgrammatic(url)
@@ -85,8 +100,19 @@ internal fun appliedLinkDirective(url: String, imports: List<String> = emptyList
85100
appliedDirectiveBuilder.argument(it)
86101
}
87102

103+
if (!namespace.isNullOrBlank()) {
104+
this.getArgument("as")
105+
.toAppliedArgument()
106+
.transform { argumentBuilder ->
107+
argumentBuilder.valueProgrammatic(namespace)
108+
}
109+
.let {
110+
appliedDirectiveBuilder.argument(it)
111+
}
112+
}
113+
88114
if (imports.isNotEmpty()) {
89-
LINK_DIRECTIVE_TYPE.getArgument("import")
115+
this.getArgument("import")
90116
.toAppliedArgument()
91117
.transform { argumentBuilder ->
92118
argumentBuilder.valueProgrammatic(imports)

0 commit comments

Comments
 (0)