fix(@nestjs/graphql): keep class directive when a field has the same SDL#3952
Merged
kamilmysliwiec merged 1 commit intonestjs:masterfrom Apr 22, 2026
Conversation
`addDirectiveMetadata` deduplicated class-level directives against the set of SDLs already seen on *field* directives, so a class directive was silently dropped whenever any field on the same class had been annotated with the same SDL string. This broke common patterns like tagging both a class and one of its fields with `@tag(name: "public")` for Apollo Contracts. Dedupe against the class's own directive list instead, preserving the original intent of preventing exact duplicates on the same target.
20fb051 to
eb9582d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
addDirectiveMetadatasilently dropping a class-level@Directive(sdl)whenever any field on the same class already has a property@Directive(sdl)with the same SDL.Bug
Because decorators run field-before-class,
fieldDirectives.sdlsalready contained@tag(name: "public")by the time the class decorator fired, and the class directive was skipped. The emitted SDL therefore lacked the class-level@tag, which breaks Apollo Contracts / federation tagging patterns that tag both the entity and one of its fields.Fix
Check
classMetadata.classDirectivesfor an existing SDL match instead of the field-directive set. This still prevents stacking the exact same class directive twice on the same target, but decouples the check from field-directive state.Test plan
class-directive-not-shadowed.spec.tsfails onmaster; passes after the fix.tests/schema-builder/**continues to pass (including the directive inheritance coverage from fix(@nestjs/graphql): inherit class directives from abstract parents #3938).