-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add extend schema (AST print) to SchemaPrinter #3471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
44a681f
6922064
0668b82
ae47bd1
32c87b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| import graphql.language.ObjectTypeDefinition; | ||
| import graphql.language.ScalarTypeDefinition; | ||
| import graphql.language.SchemaDefinition; | ||
| import graphql.language.SchemaExtensionDefinition; | ||
| import graphql.language.TypeDefinition; | ||
| import graphql.language.UnionTypeDefinition; | ||
| import graphql.schema.DefaultGraphqlTypeComparatorRegistry; | ||
|
|
@@ -283,7 +284,7 @@ public Options includeDirectiveDefinitions(boolean flag) { | |
| /** | ||
| * This is a Predicate that decides whether a directive definition is printed. | ||
| * | ||
| * @param includeDirectiveDefinition the predicate to decide of a directive defintion is printed | ||
| * @param includeDirectiveDefinition the predicate to decide of a directive definition is printed | ||
| * | ||
| * @return new instance of options | ||
| */ | ||
|
|
@@ -482,7 +483,7 @@ public SchemaPrinter(Options options) { | |
|
|
||
| /** | ||
| * This can print an in memory GraphQL IDL document back to a logical schema definition. | ||
| * If you want to turn a Introspection query result into a Document (and then into a printed | ||
| * If you want to turn an Introspection query result into a Document (and then into a printed | ||
| * schema) then use {@link graphql.introspection.IntrospectionResultToSchema#createSchemaDefinition(java.util.Map)} | ||
| * first to get the {@link graphql.language.Document} and then print that. | ||
| * | ||
|
|
@@ -773,6 +774,17 @@ private boolean shouldPrintAsAst(TypeDefinition<?> definition) { | |
| return options.isUseAstDefinitions() && definition != null; | ||
| } | ||
|
|
||
| /** | ||
| * This will return true if the options say to use the AST and we have an AST element | ||
| * | ||
| * @param definition the AST schema definition | ||
| * | ||
| * @return true if we should print using AST nodes | ||
| */ | ||
| private boolean shouldPrintAsAst(SchemaDefinition definition) { | ||
| return options.isUseAstDefinitions() && definition != null; | ||
| } | ||
|
|
||
| /** | ||
| * This will print out a runtime graphql schema element using its contained AST type definition. This | ||
| * must be guarded by a called to {@link #shouldPrintAsAst(TypeDefinition)} | ||
|
|
@@ -792,6 +804,25 @@ private void printAsAst(PrintWriter out, TypeDefinition<?> definition, List<? ex | |
| out.print('\n'); | ||
| } | ||
|
|
||
| /** | ||
| * This will print out a runtime graphql schema block using its AST definition. This | ||
| * must be guarded by a called to {@link #shouldPrintAsAst(SchemaDefinition)} | ||
| * | ||
| * @param out the output writer | ||
| * @param definition the AST schema definition | ||
| * @param extensions a list of schema definition extensions | ||
| */ | ||
| private void printAsAst(PrintWriter out, SchemaDefinition definition, List<SchemaExtensionDefinition> extensions) { | ||
| out.printf("%s\n", AstPrinter.printAst(definition)); | ||
| if (extensions != null) { | ||
| for (SchemaExtensionDefinition extension : extensions) { | ||
| out.printf("\n%s\n", AstPrinter.printAst(extension)); | ||
| } | ||
| } | ||
| out.print('\n'); | ||
| } | ||
|
|
||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to type definition version above. This prints everything including directives and description. |
||
|
|
||
| private static String printAst(InputValueWithState value, GraphQLInputType type) { | ||
| return AstPrinter.printAst(ValuesResolver.valueToLiteral(value, type, GraphQLContext.getDefault(), Locale.getDefault())); | ||
| } | ||
|
|
@@ -803,7 +834,7 @@ private SchemaElementPrinter<GraphQLSchema> schemaPrinter() { | |
| GraphQLObjectType subscriptionType = schema.getSubscriptionType(); | ||
|
|
||
| // when serializing a GraphQL schema using the type system language, a | ||
| // schema definition should be omitted if only uses the default root type names. | ||
| // schema definition should be omitted only if it uses the default root type names. | ||
| boolean needsSchemaPrinted = options.isIncludeSchemaDefinition(); | ||
|
|
||
| if (!needsSchemaPrinted) { | ||
|
|
@@ -819,21 +850,25 @@ private SchemaElementPrinter<GraphQLSchema> schemaPrinter() { | |
| } | ||
|
|
||
| if (needsSchemaPrinted) { | ||
| if (hasAstDefinitionComments(schema) || hasDescription(schema)) { | ||
| out.print(printComments(schema, "")); | ||
| } | ||
| List<GraphQLAppliedDirective> directives = DirectivesUtil.toAppliedDirectives(schema.getSchemaAppliedDirectives(), schema.getSchemaDirectives()); | ||
| out.format("schema %s{\n", directivesString(GraphQLSchemaElement.class, directives)); | ||
| if (queryType != null) { | ||
| out.format(" query: %s\n", queryType.getName()); | ||
| } | ||
| if (mutationType != null) { | ||
| out.format(" mutation: %s\n", mutationType.getName()); | ||
| } | ||
| if (subscriptionType != null) { | ||
| out.format(" subscription: %s\n", subscriptionType.getName()); | ||
| if (shouldPrintAsAst(schema.getDefinition())) { | ||
| printAsAst(out, schema.getDefinition(), schema.getExtensionDefinitions()); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Main change on this line: if AST flag is on, use the new AST print method for SchemaDefinition |
||
| } else { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What follows is the original code, this will run if AST switch is off |
||
| if (hasAstDefinitionComments(schema) || hasDescription(schema)) { | ||
| out.print(printComments(schema, "")); | ||
| } | ||
| List<GraphQLAppliedDirective> directives = DirectivesUtil.toAppliedDirectives(schema.getSchemaAppliedDirectives(), schema.getSchemaDirectives()); | ||
| out.format("schema %s{\n", directivesString(GraphQLSchemaElement.class, directives)); | ||
| if (queryType != null) { | ||
| out.format(" query: %s\n", queryType.getName()); | ||
| } | ||
| if (mutationType != null) { | ||
| out.format(" mutation: %s\n", mutationType.getName()); | ||
| } | ||
| if (subscriptionType != null) { | ||
| out.format(" subscription: %s\n", subscriptionType.getName()); | ||
| } | ||
| out.format("}\n\n"); | ||
| } | ||
| out.format("}\n\n"); | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1342,9 +1342,195 @@ type Query { | |
| ''' | ||
| } | ||
|
|
||
| def "can print extend schema block when AST printing enabled"() { | ||
| def sdl = ''' | ||
| directive @schemaDirective on SCHEMA | ||
|
|
||
| """ | ||
| My schema block description | ||
| """ | ||
| schema { | ||
| mutation: MyMutation | ||
| } | ||
|
|
||
| extend schema @schemaDirective { | ||
| query: MyQuery | ||
| } | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: although there is an implicit |
||
|
|
||
| extend schema { | ||
| subscription: MySubscription | ||
| } | ||
|
|
||
| type MyQuery { | ||
| foo: String | ||
| } | ||
|
|
||
| type MyMutation { | ||
| pizza: String | ||
| } | ||
|
|
||
| type MySubscription { | ||
| chippies: String | ||
| } | ||
| ''' | ||
|
|
||
| when: | ||
| def runtimeWiring = newRuntimeWiring().build() | ||
|
|
||
| def options = SchemaGenerator.Options.defaultOptions() | ||
| def types = new SchemaParser().parse(sdl) | ||
| GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) | ||
|
|
||
| def printOptions = defaultOptions() | ||
| .useAstDefinitions(true) | ||
| .includeSchemaDefinition(true) | ||
| def result = new SchemaPrinter(printOptions).print(schema) | ||
|
|
||
| then: | ||
| result == '''""" | ||
| My schema block description | ||
| """ | ||
| schema { | ||
| mutation: MyMutation | ||
| } | ||
|
|
||
| extend schema @schemaDirective { | ||
| query: MyQuery | ||
| } | ||
|
|
||
| extend schema { | ||
| subscription: MySubscription | ||
| } | ||
|
|
||
| "Marks the field, argument, input field or enum value as deprecated" | ||
| directive @deprecated( | ||
| "The reason for the deprecation" | ||
| reason: String = "No longer supported" | ||
| ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION | ||
|
|
||
| "Directs the executor to include this field or fragment only when the `if` argument is true" | ||
| directive @include( | ||
| "Included when true." | ||
| if: Boolean! | ||
| ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
|
||
| "Indicates an Input Object is a OneOf Input Object." | ||
| directive @oneOf on INPUT_OBJECT | ||
|
|
||
| directive @schemaDirective on SCHEMA | ||
|
|
||
| "Directs the executor to skip this field or fragment when the `if` argument is true." | ||
| directive @skip( | ||
| "Skipped when true." | ||
| if: Boolean! | ||
| ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
|
||
| "Exposes a URL that specifies the behaviour of this scalar." | ||
| directive @specifiedBy( | ||
| "The URL that specifies the behaviour of this scalar." | ||
| url: String! | ||
| ) on SCALAR | ||
|
|
||
| type MyMutation { | ||
| pizza: String | ||
| } | ||
|
|
||
| type MyQuery { | ||
| foo: String | ||
| } | ||
|
|
||
| type MySubscription { | ||
| chippies: String | ||
| } | ||
| ''' | ||
| } | ||
|
|
||
| def "will not print extend schema block when AST printing not enabled"() { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If AST switch is off, all |
||
| def sdl = ''' | ||
| directive @schemaDirective on SCHEMA | ||
|
|
||
| """ | ||
| My schema block description | ||
| """ | ||
| schema { | ||
| mutation: MyMutation | ||
| } | ||
|
|
||
| extend schema @schemaDirective { | ||
| query: MyQuery | ||
| } | ||
|
|
||
| type MyQuery { | ||
| foo: String | ||
| } | ||
|
|
||
| type MyMutation { | ||
| pizza: String | ||
| } | ||
| ''' | ||
|
|
||
| when: | ||
| def runtimeWiring = newRuntimeWiring().build() | ||
|
|
||
| def options = SchemaGenerator.Options.defaultOptions() | ||
| def types = new SchemaParser().parse(sdl) | ||
| GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(options, types, runtimeWiring) | ||
|
|
||
| def printOptions = defaultOptions() | ||
| .useAstDefinitions(false) | ||
| .includeSchemaDefinition(true) | ||
| def result = new SchemaPrinter(printOptions).print(schema) | ||
|
|
||
| then: | ||
| result == '''"My schema block description" | ||
| schema @schemaDirective{ | ||
| query: MyQuery | ||
| mutation: MyMutation | ||
| } | ||
|
|
||
| "Marks the field, argument, input field or enum value as deprecated" | ||
| directive @deprecated( | ||
| "The reason for the deprecation" | ||
| reason: String = "No longer supported" | ||
| ) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION | ||
|
|
||
| "Directs the executor to include this field or fragment only when the `if` argument is true" | ||
| directive @include( | ||
| "Included when true." | ||
| if: Boolean! | ||
| ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
|
||
| "Indicates an Input Object is a OneOf Input Object." | ||
| directive @oneOf on INPUT_OBJECT | ||
|
|
||
| directive @schemaDirective on SCHEMA | ||
|
|
||
| "Directs the executor to skip this field or fragment when the `if` argument is true." | ||
| directive @skip( | ||
| "Skipped when true." | ||
| if: Boolean! | ||
| ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT | ||
|
|
||
| "Exposes a URL that specifies the behaviour of this scalar." | ||
| directive @specifiedBy( | ||
| "The URL that specifies the behaviour of this scalar." | ||
| url: String! | ||
| ) on SCALAR | ||
|
|
||
| type MyMutation { | ||
| pizza: String | ||
| } | ||
|
|
||
| type MyQuery { | ||
| foo: String | ||
| } | ||
| ''' | ||
| } | ||
|
|
||
| def "can print a schema as AST elements"() { | ||
| def sdl = ''' | ||
| directive @directive1 on SCALAR | ||
|
|
||
| type Query { | ||
| foo : String | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to type definition version above