Skip to content

Commit b540db7

Browse files
authored
[Fusion] Excluded overridden fields when merging (#8298)
1 parent 57a1219 commit b540db7

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Collections.Immutable;
2+
using HotChocolate.Fusion.Info;
3+
using static HotChocolate.Fusion.WellKnownArgumentNames;
4+
using static HotChocolate.Fusion.WellKnownDirectiveNames;
5+
6+
namespace HotChocolate.Fusion.Extensions;
7+
8+
internal static class OutputFieldInfoExtensions
9+
{
10+
public static bool IsOverridden(
11+
this OutputFieldInfo fieldInfo,
12+
ImmutableArray<OutputFieldInfo> fieldGroup)
13+
{
14+
var overriddenInSchemaNames =
15+
fieldGroup
16+
.Where(i => i.Field.Directives.ContainsName(Override))
17+
.Select(i => (string)i.Field.Directives[Override].First().Arguments[From].Value!)
18+
.ToImmutableArray();
19+
20+
return overriddenInSchemaNames.Contains(fieldInfo.Schema.Name);
21+
}
22+
}

src/HotChocolate/Fusion-vnext/src/Fusion.Composition/SourceSchemaMerger.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,12 @@ .. typeGroup.Where(
531531
ImmutableArray<OutputFieldInfo> fieldGroup,
532532
MutableSchemaDefinition mergedSchema)
533533
{
534-
// Filter out all fields marked with @internal.
535-
fieldGroup = [.. fieldGroup.Where(i => !i.Field.HasInternalDirective())];
534+
// Filter out internal or overridden fields.
535+
var group = fieldGroup;
536+
fieldGroup =
537+
[
538+
.. fieldGroup.Where(i => !i.Field.HasInternalDirective() && !i.IsOverridden(group))
539+
];
536540

537541
if (fieldGroup.Length == 0)
538542
{

src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/SourceSchemaMerger.OutputField.Tests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,50 @@ type Product
236236
}
237237
"""
238238
},
239+
// The field "price" is only available in Schema C, it is overridden elsewhere.
240+
{
241+
[
242+
"""
243+
type Product @key(fields: "id") {
244+
id: ID!
245+
name: String!
246+
price: Float!
247+
}
248+
""",
249+
"""
250+
type Product @key(fields: "id") {
251+
id: ID! @external
252+
price: Float! @override(from: "A")
253+
tax: Float!
254+
}
255+
""",
256+
"""
257+
type Product @key(fields: "id") {
258+
id: ID! @external
259+
price: Float! @override(from: "B")
260+
tax: Float!
261+
}
262+
"""
263+
],
264+
"""
265+
type Product
266+
@fusion__type(schema: A)
267+
@fusion__type(schema: B)
268+
@fusion__type(schema: C) {
269+
id: ID!
270+
@fusion__field(schema: A)
271+
@fusion__field(schema: B, partial: true)
272+
@fusion__field(schema: C, partial: true)
273+
name: String!
274+
@fusion__field(schema: A)
275+
price: Float!
276+
@fusion__field(schema: C)
277+
tax: Float!
278+
@fusion__field(schema: B)
279+
@fusion__field(schema: C)
280+
}
281+
"""
282+
},
239283
// @provides/@external
240284
{
241285
[

0 commit comments

Comments
 (0)