Skip to content

Commit

Permalink
[Fusion] Added pre-merge validation rule "ExternalOnInterfaceRule" (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
danielreynolds1 authored Jan 1, 2025
1 parent 9a34a3b commit 1a6811b
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public static class LogEntryCodes
public const string DisallowedInaccessible = "DISALLOWED_INACCESSIBLE";
public const string ExternalArgumentDefaultMismatch = "EXTERNAL_ARGUMENT_DEFAULT_MISMATCH";
public const string ExternalMissingOnBase = "EXTERNAL_MISSING_ON_BASE";
public const string ExternalOnInterface = "EXTERNAL_ON_INTERFACE";
public const string ExternalUnused = "EXTERNAL_UNUSED";
public const string KeyDirectiveInFieldsArg = "KEY_DIRECTIVE_IN_FIELDS_ARG";
public const string KeyFieldsHasArgs = "KEY_FIELDS_HAS_ARGS";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ public static LogEntry ExternalMissingOnBase(
schema);
}

public static LogEntry ExternalOnInterface(
OutputFieldDefinition externalField,
INamedTypeDefinition type,
SchemaDefinition schema)
{
var coordinate = new SchemaCoordinate(type.Name, externalField.Name);

return new LogEntry(
string.Format(LogEntryHelper_ExternalOnInterface, coordinate, schema.Name),
LogEntryCodes.ExternalOnInterface,
LogSeverity.Error,
coordinate,
externalField,
schema);
}

public static LogEntry ExternalUnused(
OutputFieldDefinition externalField,
INamedTypeDefinition type,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using HotChocolate.Fusion.Events;
using HotChocolate.Skimmed;
using static HotChocolate.Fusion.Logging.LogEntryHelper;

namespace HotChocolate.Fusion.PreMergeValidation.Rules;

/// <summary>
/// The <c>@external</c> directive indicates that a field is defined and resolved elsewhere, not in
/// the current schema. In the case of an interface type, fields are abstract - they do not have
/// direct resolutions at the interface level. Instead, each implementing object type provides the
/// concrete field implementations. Marking an interface field with <c>@external</c> is therefore
/// nonsensical, as there is no actual field resolution in the interface itself to “borrow” from
/// another schema. Such usage raises an <c>EXTERNAL_ON_INTERFACE</c> error.
/// </summary>
/// <seealso href="https://graphql.github.io/composite-schemas-spec/draft/#sec-External-on-Interface">
/// Specification
/// </seealso>
internal sealed class ExternalOnInterfaceRule : IEventHandler<OutputFieldEvent>
{
public void Handle(OutputFieldEvent @event, CompositionContext context)
{
var (field, type, schema) = @event;

if (type is InterfaceTypeDefinition && ValidationHelper.IsExternal(field))
{
context.Log.Write(ExternalOnInterface(field, type, schema));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
<data name="LogEntryHelper_ExternalMissingOnBase" xml:space="preserve">
<value>External field '{0}' in schema '{1}' is not defined (non-external) in any other schema.</value>
</data>
<data name="LogEntryHelper_ExternalOnInterface" xml:space="preserve">
<value>Interface field '{0}' in schema '{1}' must not be marked as external.</value>
</data>
<data name="LogEntryHelper_ExternalUnused" xml:space="preserve">
<value>External field '{0}' in schema '{1}' is not referenced by a @provides directive in the schema.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ private CompositionResult<SchemaDefinition> MergeSchemaDefinitions(CompositionCo
new DisallowedInaccessibleElementsRule(),
new ExternalArgumentDefaultMismatchRule(),
new ExternalMissingOnBaseRule(),
new ExternalOnInterfaceRule(),
new ExternalUnusedRule(),
new KeyDirectiveInFieldsArgumentRule(),
new KeyFieldsHasArgumentsRule(),
Expand Down
Loading

0 comments on commit 1a6811b

Please sign in to comment.