From 7167aa988f2455d3d7ffefea1b160136288f5cde Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Thu, 2 Dec 2021 19:14:13 +0200 Subject: [PATCH 1/7] Add support for directives on directives --- spec/Appendix C -- Grammar Summary.md | 3 ++- spec/Section 3 -- Type System.md | 3 ++- spec/Section 4 -- Introspection.md | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index cc464a4a6..01dc7be99 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -377,7 +377,7 @@ InputObjectTypeExtension : - extend input Name Directives[Const] [lookahead != `{`] DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? -`repeatable`? on DirectiveLocations +`repeatable`? on DirectiveLocations Directives? DirectiveLocations : @@ -413,6 +413,7 @@ TypeSystemDirectiveLocation : one of - `ENUM_VALUE` - `INPUT_OBJECT` - `INPUT_FIELD_DEFINITION` +- `DIRECTIVE_DEFINITION` ## Schema Coordinate Syntax diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 44760852c..3b275567a 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2033,7 +2033,7 @@ Following are examples of result coercion with various types and values: ## Directives DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? -`repeatable`? on DirectiveLocations +`repeatable`? on DirectiveLocations Directives? DirectiveLocations : @@ -2069,6 +2069,7 @@ TypeSystemDirectiveLocation : one of - `ENUM_VALUE` - `INPUT_OBJECT` - `INPUT_FIELD_DEFINITION` +- `DIRECTIVE_DEFINITION` A GraphQL schema describes directives which are used to annotate various parts of a GraphQL document as an indicator that they should be evaluated differently diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 8963a3e9c..0565ad30f 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -227,6 +227,7 @@ enum __DirectiveLocation { ENUM_VALUE INPUT_OBJECT INPUT_FIELD_DEFINITION + DIRECTIVE_DEFINITION } ``` From 40fc00a94857e58f4865026c771ce4cf7349225f Mon Sep 17 00:00:00 2001 From: BoD Date: Tue, 2 Dec 2025 10:51:42 +0100 Subject: [PATCH 2/7] Change the directive definition syntax to have applied directives after the directive's name --- spec/Appendix C -- Grammar Summary.md | 2 +- spec/Section 3 -- Type System.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 01dc7be99..20713d10c 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -377,7 +377,7 @@ InputObjectTypeExtension : - extend input Name Directives[Const] [lookahead != `{`] DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? -`repeatable`? on DirectiveLocations Directives? +Directives[Const]? `repeatable`? on DirectiveLocations DirectiveLocations : diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 3b275567a..ccaf35c62 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2033,7 +2033,7 @@ Following are examples of result coercion with various types and values: ## Directives DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? -`repeatable`? on DirectiveLocations Directives? +Directives[Const]? `repeatable`? on DirectiveLocations DirectiveLocations : From 5595ab35fcdbf3aa256738900c4a34e0c6b8ea34 Mon Sep 17 00:00:00 2001 From: BoD Date: Thu, 27 Nov 2025 16:57:11 +0100 Subject: [PATCH 3/7] Add directive extensions --- spec/Appendix C -- Grammar Summary.md | 3 +++ spec/Section 3 -- Type System.md | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 20713d10c..050727329 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -288,6 +288,7 @@ TypeExtension : - UnionTypeExtension - EnumTypeExtension - InputObjectTypeExtension +- DirectiveExtension ScalarTypeDefinition : Description? scalar Name Directives[Const]? @@ -379,6 +380,8 @@ InputObjectTypeExtension : DirectiveDefinition : Description? directive @ Name ArgumentsDefinition? Directives[Const]? `repeatable`? on DirectiveLocations +DirectiveExtension : extend directive @ Name Directives[Const] + DirectiveLocations : - DirectiveLocations | DirectiveLocation diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index ccaf35c62..4123c433e 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -393,6 +393,7 @@ TypeExtension : - UnionTypeExtension - EnumTypeExtension - InputObjectTypeExtension +- DirectiveExtension Type extensions are used to represent a GraphQL type which has been extended from some previous type. For example, this might be used by a local service to @@ -2322,3 +2323,25 @@ input UserUniqueCondition @oneOf { organizationAndEmail: OrganizationAndEmailInput } ``` + +### Directive Extensions + +DirectiveExtension : extend directive @ Name Directives[Const] + +Directive extensions are used to represent a directive which has been +extended from some previous directive. For example, this might be used by a +GraphQL tool or service which adds directives to an existing directive. + +**Type Validation** + +Directive extensions have the potential to be invalid if incorrectly defined. + +1. The previous directive must already be defined. +2. Any non-repeatable directives provided must not already apply to the + previous directive. +3. Any directives provided must not contain the use of a Directive which + references the previous directive directly. +4. Any directives provided must not contain the use of a Directive which + references the previous directive indirectly by referencing a Type or + Directive which transitively includes a reference to the previous + Directive. From 0ef522279a5fef12554944e1ba162e23ccfbcb9e Mon Sep 17 00:00:00 2001 From: BoD Date: Thu, 27 Nov 2025 17:44:43 +0100 Subject: [PATCH 4/7] Make @deprecated applicable to DIRECTIVE_DEFINITION --- spec/Appendix D -- Specified Definitions.md | 2 +- spec/Section 3 -- Type System.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/Appendix D -- Specified Definitions.md b/spec/Appendix D -- Specified Definitions.md index d2242025c..f2c506d2a 100644 --- a/spec/Appendix D -- Specified Definitions.md +++ b/spec/Appendix D -- Specified Definitions.md @@ -21,7 +21,7 @@ directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT directive @deprecated( reason: String! = "No longer supported" -) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE +) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE | DIRECTIVE_DEFINITION directive @specifiedBy(url: String!) on SCALAR diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 4123c433e..8609b1dbf 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2244,13 +2244,13 @@ condition is false. ```graphql directive @deprecated( reason: String! = "No longer supported" -) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE +) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION | ENUM_VALUE | DIRECTIVE_DEFINITION ``` The `@deprecated` _built-in directive_ is used within the type system definition language to indicate deprecated portions of a GraphQL service's schema, such as deprecated fields on a type, arguments on a field, input fields on an input -type, or values of an enum type. +type, values of an enum type, or directives. Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by [CommonMark](https://commonmark.org/)). From d2c5424b97aedbce381d3340797cf2d31c71fe88 Mon Sep 17 00:00:00 2001 From: BoD Date: Thu, 27 Nov 2025 17:55:04 +0100 Subject: [PATCH 5/7] Update introspection --- spec/Appendix D -- Specified Definitions.md | 5 ++++- spec/Section 4 -- Introspection.md | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/spec/Appendix D -- Specified Definitions.md b/spec/Appendix D -- Specified Definitions.md index f2c506d2a..e4a14986b 100644 --- a/spec/Appendix D -- Specified Definitions.md +++ b/spec/Appendix D -- Specified Definitions.md @@ -33,7 +33,7 @@ type __Schema { queryType: __Type! mutationType: __Type subscriptionType: __Type - directives: [__Directive!]! + directives(includeDeprecated: Boolean! = false): [__Directive!]! } type __Type { @@ -92,6 +92,8 @@ type __Directive { isRepeatable: Boolean! locations: [__DirectiveLocation!]! args(includeDeprecated: Boolean! = false): [__InputValue!]! + isDeprecated: Boolean! + deprecationReason: String } enum __DirectiveLocation { @@ -114,5 +116,6 @@ enum __DirectiveLocation { ENUM_VALUE INPUT_OBJECT INPUT_FIELD_DEFINITION + DIRECTIVE_DEFINITION } ``` diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index 0565ad30f..a70d856a0 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -138,7 +138,7 @@ type __Schema { queryType: __Type! mutationType: __Type subscriptionType: __Type - directives: [__Directive!]! + directives(includeDeprecated: Boolean! = false): [__Directive!]! } type __Type { @@ -205,6 +205,8 @@ type __Directive { isRepeatable: Boolean! locations: [__DirectiveLocation!]! args(includeDeprecated: Boolean! = false): [__InputValue!]! + isDeprecated: Boolean! + deprecationReason: String } enum __DirectiveLocation { @@ -249,6 +251,8 @@ Fields\: must be included in this set. - `directives` must return the set of all directives available within this schema including all built-in directives. + - Accepts the argument `includeDeprecated` which defaults to {false}. If + {true}, deprecated directives are also returned. ### The \_\_Type Type @@ -500,6 +504,7 @@ supported. All possible locations are listed in the `__DirectiveLocation` enum: - {"ENUM_VALUE"} - {"INPUT_OBJECT"} - {"INPUT_FIELD_DEFINITION"} +- {"DIRECTIVE_DEFINITION"} Fields\: @@ -513,3 +518,7 @@ Fields\: {true}, deprecated arguments are also returned. - `isRepeatable` must return a Boolean that indicates if the directive may be used repeatedly at a single location. +- `isDeprecated` returns {true} if this directive should no longer be used, + otherwise {false}. +- `deprecationReason` returns the reason why this directive is deprecated, or null + if this directive is not deprecated. From 610d8db870b106049aa7a5c21ddc2d34a174e7df Mon Sep 17 00:00:00 2001 From: BoD Date: Thu, 18 Dec 2025 15:14:29 +0100 Subject: [PATCH 6/7] Reformat with prettier --- spec/Section 3 -- Type System.md | 13 ++++++------- spec/Section 4 -- Introspection.md | 4 ++-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index 8609b1dbf..fb71cf967 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -2328,20 +2328,19 @@ input UserUniqueCondition @oneOf { DirectiveExtension : extend directive @ Name Directives[Const] -Directive extensions are used to represent a directive which has been -extended from some previous directive. For example, this might be used by a -GraphQL tool or service which adds directives to an existing directive. +Directive extensions are used to represent a directive which has been extended +from some previous directive. For example, this might be used by a GraphQL tool +or service which adds directives to an existing directive. **Type Validation** Directive extensions have the potential to be invalid if incorrectly defined. 1. The previous directive must already be defined. -2. Any non-repeatable directives provided must not already apply to the - previous directive. +2. Any non-repeatable directives provided must not already apply to the previous + directive. 3. Any directives provided must not contain the use of a Directive which references the previous directive directly. 4. Any directives provided must not contain the use of a Directive which references the previous directive indirectly by referencing a Type or - Directive which transitively includes a reference to the previous - Directive. + Directive which transitively includes a reference to the previous Directive. diff --git a/spec/Section 4 -- Introspection.md b/spec/Section 4 -- Introspection.md index a70d856a0..2138e7e70 100644 --- a/spec/Section 4 -- Introspection.md +++ b/spec/Section 4 -- Introspection.md @@ -520,5 +520,5 @@ Fields\: used repeatedly at a single location. - `isDeprecated` returns {true} if this directive should no longer be used, otherwise {false}. -- `deprecationReason` returns the reason why this directive is deprecated, or null - if this directive is not deprecated. +- `deprecationReason` returns the reason why this directive is deprecated, or + null if this directive is not deprecated. From a25789467caf85cbc2e6f63a1cb8091bec0837f8 Mon Sep 17 00:00:00 2001 From: BoD Date: Fri, 19 Dec 2025 17:32:56 +0100 Subject: [PATCH 7/7] Directives are not types --- spec/Appendix C -- Grammar Summary.md | 2 +- spec/Section 3 -- Type System.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/Appendix C -- Grammar Summary.md b/spec/Appendix C -- Grammar Summary.md index 050727329..3ac20466a 100644 --- a/spec/Appendix C -- Grammar Summary.md +++ b/spec/Appendix C -- Grammar Summary.md @@ -260,6 +260,7 @@ TypeSystemExtension : - SchemaExtension - TypeExtension +- DirectiveExtension SchemaDefinition : Description? schema Directives[Const]? { RootOperationTypeDefinition+ } @@ -288,7 +289,6 @@ TypeExtension : - UnionTypeExtension - EnumTypeExtension - InputObjectTypeExtension -- DirectiveExtension ScalarTypeDefinition : Description? scalar Name Directives[Const]? diff --git a/spec/Section 3 -- Type System.md b/spec/Section 3 -- Type System.md index fb71cf967..00216acea 100644 --- a/spec/Section 3 -- Type System.md +++ b/spec/Section 3 -- Type System.md @@ -40,6 +40,7 @@ TypeSystemExtension : - SchemaExtension - TypeExtension +- DirectiveExtension Type system extensions are used to represent a GraphQL type system which has been extended from some previous type system. For example, this might be used by @@ -393,7 +394,6 @@ TypeExtension : - UnionTypeExtension - EnumTypeExtension - InputObjectTypeExtension -- DirectiveExtension Type extensions are used to represent a GraphQL type which has been extended from some previous type. For example, this might be used by a local service to