Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
release type: minor
social_messages:
x: >-
{project_name} {version} is out! Custom schema directives attached to types and
fields now appear in GraphQL introspection. 🍓
https://strawberry.rocks/release/{version}
linkedin: >-
{project_name} {version} is out. GraphQL tools can now discover custom schema
directives attached throughout a Strawberry schema using standard
introspection. 🍓
---

This release fixes introspection for custom schema directives.

Schema directives attached to types, fields, arguments, and other schema elements
now appear in standard GraphQL introspection. Schema explorers, IDEs, code
generators, and other tools can discover each directive's description, arguments,
allowed locations, repeatability, and any input types it uses.

A directive reused across the schema is defined only once. Input, enum, and scalar
types referenced by directive arguments are now part of the schema and may appear
in generated SDL even when they are not used by fields.
15 changes: 13 additions & 2 deletions strawberry/federation/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,17 @@ def __init__( # noqa: PLR0917
FederationAny: scalar(
name="_Any", serialize=lambda v: v, parse_value=lambda v: v
),
FieldSet: scalar(name="_FieldSet", serialize=lambda v: v, parse_value=str),
FieldSet: scalar(
name="_FieldSet",
serialize=lambda v: v,
parse_value=str,
print_definition=False,
),
LinkImport: scalar(
name="link__Import", serialize=lambda v: v, parse_value=lambda v: v
name="link__Import",
serialize=lambda v: v,
parse_value=lambda v: v,
print_definition=False,
),
}
if scalar_overrides:
Expand Down Expand Up @@ -367,6 +375,9 @@ def _warn_for_federation_directives(self) -> None:

pass

def _should_register_schema_directive(self, directive: object) -> bool:
return True


def _get_entity_type(
query: type[WithStrawberryObjectDefinition] | None,
Expand Down
2 changes: 1 addition & 1 deletion strawberry/federation/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"""Represents an import for the @link directive."""


@enum(name="link__Purpose")
@enum(name="link__Purpose", print_definition=False)
class LinkPurpose(Enum):
SECURITY = "SECURITY"
EXECUTION = "EXECUTION"
Expand Down
19 changes: 17 additions & 2 deletions strawberry/printer/printer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
overload,
)

from graphql import GraphQLInputField, GraphQLObjectType, GraphQLSchema, is_union_type
from graphql import (
GraphQLInputField,
GraphQLObjectType,
GraphQLSchema,
is_union_type,
)
from graphql.language.printer import print_ast
from graphql.type import (
is_enum_type,
Expand Down Expand Up @@ -592,6 +597,12 @@ def is_builtin_directive(directive: GraphQLDirective) -> bool:
return False


def _should_print_type(type_: GraphQLNamedType) -> bool:
strawberry_definition = type_.extensions.get("strawberry-definition")

return getattr(strawberry_definition, "print_definition", True)


def print_schema(schema: BaseSchema) -> str:
graphql_core_schema = cast(
"GraphQLSchema",
Expand All @@ -609,7 +620,7 @@ def print_schema(schema: BaseSchema) -> str:
types = [
type_
for type_name in sorted(type_map)
if is_defined_type(type_ := type_map[type_name])
if is_defined_type(type_ := type_map[type_name]) and _should_print_type(type_)
]

types_printed = [_print_type(type_, schema, extras=extras) for type_ in types]
Expand All @@ -619,6 +630,7 @@ def print_schema(schema: BaseSchema) -> str:
printed_directive
for directive in filtered_directives
if (printed_directive := print_directive(directive, schema=schema)) is not None
and printed_directive not in extras.directives
]

if schema.config.enable_experimental_incremental_execution:
Expand All @@ -643,6 +655,9 @@ def _print_extra_types() -> Iterable[str]:
"GraphQLNamedType", schema.schema_converter.from_type(type_)
)

if not _should_print_type(graphql_type):
continue

# Skip types that are already part of the schema's type map, otherwise
# they'd be printed twice (e.g. an enum used both as a regular type and
# as a schema directive field), producing invalid SDL.
Expand Down
Loading
Loading