diff --git a/docs/codegen-options.md b/docs/codegen-options.md index c8847e568e6b1036cd392d0b8e886e9ef42f9dc6..ff6cc6674d9f0bab041562a49c545e3f65cbe802 100644 --- a/docs/codegen-options.md +++ b/docs/codegen-options.md @@ -4,6 +4,7 @@ | :---------------------------------------------: | :----------------------------------------------------------------: | :-------------------------------------------: | ----------- | | `graphqlSchemaPaths` | List(String) | (falls back to `graphqlSchemas`) | GraphQL schema locations. You can supply multiple paths to GraphQL schemas. To include many schemas from a folder hierarchy, use the `graphqlSchemas` block instead. | | `graphqlSchemas` | *See [graphqlSchemas](#option-graphqlschemas)* | All `.graphqls`/`.graphql` files in resources | Block to define the input GraphQL schemas, when exact paths are too cumbersome. See table below for a list of options. *See [graphqlSchemas](#option-graphqlschemas)* | +| `graphqlQueryIntrospectionResultPath` | String | None | Path to GraphQL Introspection Query result in json format (with root object `__schema` or `data.__schema`). Sample: [sample-introspection-query-result.json](../src/test/resources/introspection-result/sample-introspection-query-result.json)| | `outputDir` | String | None | The output target directory into which code will be generated. | | `jsonConfigurationFile` | String | Empty | Path to an external mapping configuration. | | `packageName` | String | Empty | Java package for generated classes. | diff --git a/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java b/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java index 0bd935c5571838e2fb2a65ec6ec0842e8d631ddc..b1273a74d17fce4d9f5d0c2687298305fca33b18 100644 --- a/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java +++ b/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java @@ -41,6 +41,7 @@ import java.util.Set; public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCodegenConfiguration { private List graphqlSchemaPaths; + private String graphqlQueryIntrospectionResultPath; private final SchemaFinderConfig graphqlSchemas = new SchemaFinderConfig(); private File outputDir; @@ -134,7 +135,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode mappingConfig.setMutationResolverParentInterface(getMutationResolverParentInterface()); mappingConfig.setSubscriptionResolverParentInterface(getSubscriptionResolverParentInterface()); - new GraphQLCodegen(getActualSchemaPaths(), outputDir, mappingConfig, buildJsonSupplier()).generate(); + new GraphQLCodegen(getActualSchemaPaths(), graphqlQueryIntrospectionResultPath, outputDir, mappingConfig, buildJsonSupplier()).generate(); } // This is only public so that it can be part of the inputs. @@ -192,6 +193,16 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode this.graphqlSchemaPaths = graphqlSchemaPaths; } + @InputFile + @Optional + public String getGraphqlQueryIntrospectionResultPath() { + return graphqlQueryIntrospectionResultPath; + } + + public void setGraphqlQueryIntrospectionResultPath(String graphqlQueryIntrospectionResultPath) { + this.graphqlQueryIntrospectionResultPath = graphqlQueryIntrospectionResultPath; + } + @Nested @Optional public SchemaFinderConfig getGraphqlSchemas() { diff --git a/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java b/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java index 63a7f96a96e1c9b4f08603ac2613204bb66ed2c1..4b6674a19f5c6f4365683553973253ca64ed0b9e 100644 --- a/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java +++ b/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java @@ -37,6 +37,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo @Parameter private String[] graphqlSchemaPaths; + @Parameter + private String graphqlQueryIntrospectionResultPath; + @Parameter private SchemaFinderConfig graphqlSchemas = new SchemaFinderConfig(); @@ -212,7 +215,7 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo MappingConfigSupplier mappingConfigSupplier = buildJsonSupplier(jsonConfigurationFile); try { - new GraphQLCodegen(getSchemas(), outputDir, mappingConfig, mappingConfigSupplier).generate(); + new GraphQLCodegen(getSchemas(), graphqlQueryIntrospectionResultPath, outputDir, mappingConfig, mappingConfigSupplier).generate(); } catch (Exception e) { getLog().error(e); throw new MojoExecutionException("Code generation failed. See above for the full exception."); @@ -265,6 +268,14 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo this.graphqlSchemaPaths = graphqlSchemaPaths; } + public String getGraphqlQueryIntrospectionResultPath() { + return graphqlQueryIntrospectionResultPath; + } + + public void setGraphqlQueryIntrospectionResultPath(String graphqlQueryIntrospectionResultPath) { + this.graphqlQueryIntrospectionResultPath = graphqlQueryIntrospectionResultPath; + } + public SchemaFinderConfig getGraphqlSchemas() { return graphqlSchemas; } diff --git a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala index b7a4adf36a007fc5464c2e59fcb7c844b44934d6..5f5c59050e70079363844e12acd478215f880342 100644 --- a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala +++ b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala @@ -104,6 +104,8 @@ trait GraphQLCodegenKeys { val useOptionalForNullableReturnTypes = settingKey[Boolean]("useOptionalForNullableReturnTypes") + val graphqlQueryIntrospectionResultPath = settingKey[Option[String]]("graphqlQueryIntrospectionResultPath") + //for version val javaxValidationApiVersion = settingKey[Option[String]]("javax-validation-api version") val graphqlJavaCodegenVersion = settingKey[Option[String]]("graphql java codegen version") diff --git a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala index 0f1c6ccc9604070db51374ca402a2ee26507b916..1fe19942988377b3de55af63cad3e5b01c8395d0 100644 --- a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala +++ b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala @@ -58,6 +58,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co //With the implementation of some other plugins, initialization is not necessary, //but maybe should be related to the dependency of key. For convenience, this is a conservative operation override lazy val globalSettings: Seq[Def.Setting[_]] = Seq( + graphqlQueryIntrospectionResultPath := None, graphqlSchemas := schemaFinderConfig, jsonConfigurationFile := None, graphqlSchemaPaths := Seq.empty, @@ -192,14 +193,18 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co val mappingConfigSupplier: JsonMappingConfigSupplier = buildJsonSupplier((jsonConfigurationFile in GraphQLCodegenConfig).value.orNull) var result: Seq[File] = Seq.empty try { - result = new GraphQLCodegen(getSchemas, (outputDir in GraphQLCodegenConfig).value, getMappingConfig().value, mappingConfigSupplier).generate.asScala + result = new GraphQLCodegen( + getSchemas, + (graphqlQueryIntrospectionResultPath in GraphQLCodegenConfig).value.orNull, + (outputDir in GraphQLCodegenConfig).value, + getMappingConfig().value, + mappingConfigSupplier).generate.asScala for (file ← result) { sLog.value.success(s"${file.getName}") } } catch { case e: Exception ⇒ - sLog.value.debug(s"${e.getStackTrace}") - throw new Exception("Code generation failed. See above for the full exception.") + throw new Exception(s"${e.getLocalizedMessage}") } def getSchemas: util.List[String] = { diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java index bd44595d0c3beb3f111aaea0b56bcfdb7b565ad2..f52ea3e626680044c1c7d959b26c5f042c34e699 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java @@ -52,30 +52,45 @@ import static java.util.stream.Collectors.toList; public class GraphQLCodegen { private final List schemas; + private final String introspectionResult; private final File outputDir; private final MappingConfig mappingConfig; private final GeneratedInformation generatedInformation; + // used in tests public GraphQLCodegen(List schemas, File outputDir, MappingConfig mappingConfig, GeneratedInformation generatedInformation) { - this(schemas, outputDir, mappingConfig, null, generatedInformation); + this(schemas, null, outputDir, mappingConfig, null, generatedInformation); } + // used in tests + public GraphQLCodegen(String introspectionResult, + File outputDir, + MappingConfig mappingConfig, + GeneratedInformation generatedInformation) { + this(null, introspectionResult, outputDir, mappingConfig, null, generatedInformation); + } + + // used in plugins public GraphQLCodegen(List schemas, + String introspectionResult, File outputDir, MappingConfig mappingConfig, MappingConfigSupplier externalMappingConfigSupplier) { - this(schemas, outputDir, mappingConfig, externalMappingConfigSupplier, new GeneratedInformation()); + this(schemas, introspectionResult, outputDir, mappingConfig, externalMappingConfigSupplier, new GeneratedInformation()); } + // used by other constructors public GraphQLCodegen(List schemas, + String introspectionResult, File outputDir, MappingConfig mappingConfig, MappingConfigSupplier externalMappingConfigSupplier, GeneratedInformation generatedInformation) { this.schemas = schemas; + this.introspectionResult = introspectionResult; this.outputDir = outputDir; this.mappingConfig = mappingConfig; this.mappingConfig.combine(externalMappingConfigSupplier != null ? externalMappingConfigSupplier.get() : null); @@ -155,7 +170,12 @@ public class GraphQLCodegen { } } - private static void validateConfigs(MappingConfig mappingConfig) { + private void validateConfigs(MappingConfig mappingConfig) { + if (!Utils.isEmpty(schemas) && introspectionResult != null || + (Utils.isEmpty(schemas) && introspectionResult == null)) { + // either schemas or introspection result should be provided + throw new IllegalArgumentException("Either graphql schema path or introspection result path should be supplied"); + } if (mappingConfig.getApiRootInterfaceStrategy() == ApiRootInterfaceStrategy.INTERFACE_PER_SCHEMA && mappingConfig.getApiNamePrefixStrategy() == ApiNamePrefixStrategy.CONSTANT) { // we will have a conflict in case there is "type Query" in multiple graphql schema files @@ -205,13 +225,20 @@ public class GraphQLCodegen { GraphQLCodegenFileCreator.prepareOutputDir(outputDir); long startTime = System.currentTimeMillis(); List generatedFiles = Collections.emptyList(); - if (!schemas.isEmpty()) { - ExtendedDocument document = GraphQLDocumentParser.getDocument(mappingConfig, schemas); + if (!Utils.isEmpty(schemas)) { + ExtendedDocument document = GraphQLDocumentParser.getDocumentFromSchemas(mappingConfig, schemas); + initCustomTypeMappings(document.getScalarDefinitions()); + generatedFiles = processDefinitions(document); + System.out.println(String.format("Finished processing %d schema(s) in %d ms", schemas.size(), + System.currentTimeMillis() - startTime)); + } else if (introspectionResult != null) { + ExtendedDocument document = GraphQLDocumentParser.getDocumentFromIntrospectionResult(mappingConfig, introspectionResult); initCustomTypeMappings(document.getScalarDefinitions()); generatedFiles = processDefinitions(document); + System.out.println(String.format("Finished processing introspection result in %d ms", + System.currentTimeMillis() - startTime)); } - long elapsed = System.currentTimeMillis() - startTime; - System.out.println(String.format("Finished processing %d schema(s) in %d ms", schemas.size(), elapsed)); + return generatedFiles; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLDocumentParser.java b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLDocumentParser.java index b8d22bd3bd44c64a34b8fd1ad7568a00f0d9305b..8e31d57e5ef3ab9dbe5b15940fe73dff5b31500b 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLDocumentParser.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLDocumentParser.java @@ -1,5 +1,6 @@ package com.kobylynskyi.graphql.codegen; +import com.fasterxml.jackson.core.type.TypeReference; import com.kobylynskyi.graphql.codegen.model.MappingConfig; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDocument; @@ -10,6 +11,7 @@ import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedObjectTypeDefin import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedScalarTypeDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedUnionTypeDefinition; import com.kobylynskyi.graphql.codegen.utils.Utils; +import graphql.introspection.IntrospectionResultToSchema; import graphql.language.Definition; import graphql.language.Document; import graphql.language.EnumTypeDefinition; @@ -41,7 +43,7 @@ class GraphQLDocumentParser { private GraphQLDocumentParser() { } - static ExtendedDocument getDocument(MappingConfig mappingConfig, List schemaPaths) throws IOException { + static ExtendedDocument getDocumentFromSchemas(MappingConfig mappingConfig, List schemaPaths) throws IOException { Document document = readDocument(schemaPaths); ExtendedDocumentBuilder extendedDocumentBuilder = new ExtendedDocumentBuilder(); @@ -52,6 +54,25 @@ class GraphQLDocumentParser { return extendedDocumentBuilder.build(); } + static ExtendedDocument getDocumentFromIntrospectionResult(MappingConfig mappingConfig, String introspectionResult) throws IOException { + String introspectionResultContent = Utils.getFileContent(introspectionResult); + Map introspectionResultMap = Utils.OBJECT_MAPPER.readValue(introspectionResultContent, + new TypeReference>() { + }); + // unwrapping "data" (in case such GraphQL response supplied) + if (introspectionResultMap.containsKey("data")) { + introspectionResultMap = (Map) introspectionResultMap.get("data"); + } + Document document = new IntrospectionResultToSchema().createSchemaDefinition(introspectionResultMap); + + ExtendedDocumentBuilder extendedDocumentBuilder = new ExtendedDocumentBuilder(); + + for (Definition definition : document.getDefinitions()) { + processDefinition(mappingConfig, extendedDocumentBuilder, definition); + } + return extendedDocumentBuilder.build(); + } + private static void processDefinition(MappingConfig mappingConfig, ExtendedDocumentBuilder extendedDocumentBuilder, Definition definition) { if (!(definition instanceof NamedNode)) { // the only definition that does not have a name is SchemaDefinition, so skipping it diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedObjectTypeDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedObjectTypeDefinition.java index 53942538df7ea00a3433bf98cd31464de272e561..6d93c790a44fe3b826b665a12dc732c72a812e44 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedObjectTypeDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/definitions/ExtendedObjectTypeDefinition.java @@ -1,5 +1,6 @@ package com.kobylynskyi.graphql.codegen.model.definitions; +import graphql.language.Node; import graphql.language.ObjectTypeDefinition; import graphql.language.ObjectTypeExtensionDefinition; @@ -45,16 +46,26 @@ public class ExtendedObjectTypeDefinition extends ExtendedImplementingTypeDefini private Map groupBySourceLocation(Function fileStringFunction) { Map definitionMap = new HashMap<>(); if (definition != null) { - File file = new File(definition.getSourceLocation().getSourceName()); + File file = new File(getSourceLocationName(definition)); definitionMap.computeIfAbsent(fileStringFunction.apply(file), d -> new ExtendedObjectTypeDefinition()) .setDefinition(definition); } for (ObjectTypeExtensionDefinition extension : extensions) { - File file = new File(extension.getSourceLocation().getSourceName()); + File file = new File(getSourceLocationName(extension)); definitionMap.computeIfAbsent(fileStringFunction.apply(file), d -> new ExtendedObjectTypeDefinition()) .getExtensions().add(extension); } return definitionMap; } + /** + * Get source location of the node. + * In some cases Node does not have a source location defined, so returning "unknown" + * + * @return source location if present or "unknown" otherwise + */ + private static String getSourceLocationName(Node node) { + return node.getSourceLocation() != null ? node.getSourceLocation().getSourceName() : "unknown"; + } + } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/supplier/JsonMappingConfigSupplier.java b/src/main/java/com/kobylynskyi/graphql/codegen/supplier/JsonMappingConfigSupplier.java index 867c709a470e53811e1f9271deb6e66020999dc0..1c3181ec202e439ab28a210f55d29a111d722a1c 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/supplier/JsonMappingConfigSupplier.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/supplier/JsonMappingConfigSupplier.java @@ -1,7 +1,7 @@ package com.kobylynskyi.graphql.codegen.supplier; -import com.fasterxml.jackson.databind.ObjectMapper; import com.kobylynskyi.graphql.codegen.model.MappingConfig; +import com.kobylynskyi.graphql.codegen.utils.Utils; import java.io.File; import java.io.IOException; @@ -13,8 +13,6 @@ import java.io.IOException; */ public class JsonMappingConfigSupplier implements MappingConfigSupplier { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private final String jsonConfigFile; /** @@ -30,7 +28,7 @@ public class JsonMappingConfigSupplier implements MappingConfigSupplier { public MappingConfig get() { if (jsonConfigFile != null && !jsonConfigFile.isEmpty()) { try { - return OBJECT_MAPPER.readValue(new File(jsonConfigFile), MappingConfig.class); + return Utils.OBJECT_MAPPER.readValue(new File(jsonConfigFile), MappingConfig.class); } catch (IOException e) { throw new IllegalArgumentException(e); } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/utils/Utils.java b/src/main/java/com/kobylynskyi/graphql/codegen/utils/Utils.java index cc09dbcb34f820d2612a2103d7c5be8a7b4cb4e2..e040d5db6109ee93984a76826263b3ffdf360d0f 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/utils/Utils.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/utils/Utils.java @@ -1,5 +1,6 @@ package com.kobylynskyi.graphql.codegen.utils; +import com.fasterxml.jackson.databind.ObjectMapper; import com.kobylynskyi.graphql.codegen.model.exception.UnableToCreateDirectoryException; import com.kobylynskyi.graphql.codegen.model.exception.UnableToDeleteDirectoryException; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; @@ -18,6 +19,8 @@ import java.util.Objects; */ public final class Utils { + public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private Utils() { } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenIntrospectionResultTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenIntrospectionResultTest.java new file mode 100644 index 0000000000000000000000000000000000000000..427cf833aaab3a3b72abafd64d8ca1bab537abc8 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenIntrospectionResultTest.java @@ -0,0 +1,83 @@ +package com.kobylynskyi.graphql.codegen; + +import com.kobylynskyi.graphql.codegen.model.ApiNamePrefixStrategy; +import com.kobylynskyi.graphql.codegen.model.ApiRootInterfaceStrategy; +import com.kobylynskyi.graphql.codegen.model.MappingConfig; +import com.kobylynskyi.graphql.codegen.utils.Utils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class GraphQLCodegenIntrospectionResultTest { + + private final File outputBuildDir = new File("build/generated"); + private final File outputJavaClassesDir = new File("build/generated/com/kobylynskyi/graphql/test1"); + + private MappingConfig mappingConfig; + + @BeforeEach + void init() { + mappingConfig = new MappingConfig(); + mappingConfig.setPackageName("com.kobylynskyi.graphql.test1"); + mappingConfig.setGenerateClient(true); + } + + @AfterEach + void cleanup() { + Utils.deleteDir(outputBuildDir); + } + + @Test + void generateClientFromIntrospectionResult() throws Exception { + new GraphQLCodegen("src/test/resources/introspection-result/sample-introspection-query-result.json", + outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + checkGeneratedFiles(); + } + + @Test + void generateClientFromIntrospectionResultWrappedInData() throws Exception { + new GraphQLCodegen("src/test/resources/introspection-result/sample-introspection-query-result-wrapped.json", + outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + checkGeneratedFiles(); + } + + @Test + void generateClientFromIntrospectionResult_SetApiStrategies() throws Exception { + mappingConfig.setApiRootInterfaceStrategy(ApiRootInterfaceStrategy.INTERFACE_PER_SCHEMA); + mappingConfig.setApiNamePrefixStrategy(ApiNamePrefixStrategy.FOLDER_NAME_AS_PREFIX); + + new GraphQLCodegen("src/test/resources/introspection-result/sample-introspection-query-result.json", + outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + checkGeneratedFiles(); + } + + private void checkGeneratedFiles() throws IOException { + File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); + List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); + assertEquals(Arrays.asList("CreateMutationRequest.java", "CreateMutationResolver.java", + "CreateMutationResponse.java", "MutationResolver.java", "Product.java", "ProductByIdQueryRequest.java", + "ProductByIdQueryResolver.java", "ProductByIdQueryResponse.java", "ProductInput.java", + "ProductResponseProjection.java", "ProductsByIdsQueryRequest.java", "ProductsByIdsQueryResolver.java", + "ProductsByIdsQueryResponse.java", "ProductsQueryRequest.java", "ProductsQueryResolver.java", + "ProductsQueryResponse.java", "QueryResolver.java", "StockStatus.java"), generatedFileNames); + + for (File file : files) { + File expected = new File(String.format("src/test/resources/expected-classes/from-introspection-result/%s.txt", file.getName())); + assertSameTrimmedContent(expected, file); + } + } + +} diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java index 8846a87173764d1a304568ae81741971b026c3cd..c31644755ce4510b33f16f8160e6d610bf41e249 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java @@ -1,5 +1,6 @@ package com.kobylynskyi.graphql.codegen; +import com.kobylynskyi.graphql.codegen.model.GeneratedInformation; import com.kobylynskyi.graphql.codegen.model.MappingConfig; import com.kobylynskyi.graphql.codegen.utils.Utils; import org.hamcrest.core.StringContains; @@ -225,12 +226,11 @@ class GraphQLCodegenTest { } @Test - void generate_NoSchemas() throws Exception { - new GraphQLCodegen(emptyList(), - outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); - - File[] files = Objects.requireNonNull(outputBuildDir.listFiles()); - assertEquals(0, files.length); + void generate_NoSchemas() { + GeneratedInformation staticGeneratedInfo = TestUtils.getStaticGeneratedInfo(); + List schemas = emptyList(); + assertThrows(IllegalArgumentException.class, () -> + new GraphQLCodegen(schemas, outputBuildDir, mappingConfig, staticGeneratedInfo)); } @Test @@ -239,6 +239,8 @@ class GraphQLCodegenTest { outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()); assertThrows(NoSuchFileException.class, graphQLCodegen::generate); + + assertEquals(0, Objects.requireNonNull(outputBuildDir.listFiles()).length); } @Test diff --git a/src/test/resources/expected-classes/from-introspection-result/CreateMutationRequest.java.txt b/src/test/resources/expected-classes/from-introspection-result/CreateMutationRequest.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..3ec1e87ed729040667d18e6fba8b59a586f8e03b --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/CreateMutationRequest.java.txt @@ -0,0 +1,67 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class CreateMutationRequest implements GraphQLOperationRequest { + + private static final GraphQLOperation OPERATION_TYPE = GraphQLOperation.MUTATION; + private static final String OPERATION_NAME = "create"; + + private Map input = new LinkedHashMap<>(); + + public CreateMutationRequest() { + } + + public void setProductInput(ProductInput productInput) { + this.input.put("productInput", productInput); + } + + @Override + public GraphQLOperation getOperationType() { + return OPERATION_TYPE; + } + + @Override + public String getOperationName() { + return OPERATION_NAME; + } + + @Override + public Map getInput() { + return input; + } + + @Override + public String toString() { + return Objects.toString(input); + } + + public static class Builder { + + private ProductInput productInput; + + public Builder() { + } + + public Builder setProductInput(ProductInput productInput) { + this.productInput = productInput; + return this; + } + + + public CreateMutationRequest build() { + CreateMutationRequest obj = new CreateMutationRequest(); + obj.setProductInput(productInput); + return obj; + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/CreateMutationResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/CreateMutationResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..30db736eaee0d6b9bbf1b002caab88bebcbb1ab3 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/CreateMutationResolver.java.txt @@ -0,0 +1,12 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface CreateMutationResolver { + + Product create(ProductInput productInput) throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/CreateMutationResponse.java.txt b/src/test/resources/expected-classes/from-introspection-result/CreateMutationResponse.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..4feeb8ac6b9e6e90e6cf4f3d7db6b93afe16764a --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/CreateMutationResponse.java.txt @@ -0,0 +1,22 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResult; +import java.util.Map; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class CreateMutationResponse extends GraphQLResult> { + + private static final String OPERATION_NAME = "create"; + + public CreateMutationResponse() { + } + + public Product create() { + Map data = getData(); + return data != null ? data.get(OPERATION_NAME) : null; + } + +} diff --git a/src/test/resources/expected-classes/from-introspection-result/MutationResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/MutationResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..cb7d0d572927662be1845806eccf991e4d1dd86b --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/MutationResolver.java.txt @@ -0,0 +1,12 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface MutationResolver { + + Product create(ProductInput productInput) throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/Product.java.txt b/src/test/resources/expected-classes/from-introspection-result/Product.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..e9b569d8de0a2fc0608581d2f47d1e783c3ee3fa --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/Product.java.txt @@ -0,0 +1,173 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class Product implements java.io.Serializable { + + @javax.validation.constraints.NotNull + private String id; + @javax.validation.constraints.NotNull + private String title; + private String description; + @javax.validation.constraints.NotNull + private String price; + @javax.validation.constraints.NotNull + private String sku; + private StockStatus stockStatus; + @javax.validation.constraints.NotNull + private String addedDateTime; + + public Product() { + } + + public Product(String id, String title, String description, String price, String sku, StockStatus stockStatus, String addedDateTime) { + this.id = id; + this.title = title; + this.description = description; + this.price = price; + this.sku = sku; + this.stockStatus = stockStatus; + this.addedDateTime = addedDateTime; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + + public StockStatus getStockStatus() { + return stockStatus; + } + public void setStockStatus(StockStatus stockStatus) { + this.stockStatus = stockStatus; + } + + public String getAddedDateTime() { + return addedDateTime; + } + public void setAddedDateTime(String addedDateTime) { + this.addedDateTime = addedDateTime; + } + + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "{ ", " }"); + if (id != null) { + joiner.add("id: " + GraphQLRequestSerializer.getEntry(id)); + } + if (title != null) { + joiner.add("title: " + GraphQLRequestSerializer.getEntry(title)); + } + if (description != null) { + joiner.add("description: " + GraphQLRequestSerializer.getEntry(description)); + } + if (price != null) { + joiner.add("price: " + GraphQLRequestSerializer.getEntry(price)); + } + if (sku != null) { + joiner.add("sku: " + GraphQLRequestSerializer.getEntry(sku)); + } + if (stockStatus != null) { + joiner.add("stockStatus: " + GraphQLRequestSerializer.getEntry(stockStatus)); + } + if (addedDateTime != null) { + joiner.add("addedDateTime: " + GraphQLRequestSerializer.getEntry(addedDateTime)); + } + return joiner.toString(); + } + + public static Product.Builder builder() { + return new Product.Builder(); + } + + public static class Builder { + + private String id; + private String title; + private String description; + private String price; + private String sku; + private StockStatus stockStatus; + private String addedDateTime; + + public Builder() { + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + public Builder setTitle(String title) { + this.title = title; + return this; + } + + public Builder setDescription(String description) { + this.description = description; + return this; + } + + public Builder setPrice(String price) { + this.price = price; + return this; + } + + public Builder setSku(String sku) { + this.sku = sku; + return this; + } + + public Builder setStockStatus(StockStatus stockStatus) { + this.stockStatus = stockStatus; + return this; + } + + public Builder setAddedDateTime(String addedDateTime) { + this.addedDateTime = addedDateTime; + return this; + } + + + public Product build() { + return new Product(id, title, description, price, sku, stockStatus, addedDateTime); + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryRequest.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryRequest.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..b3ff5a0917fb728f5417a0c2eec322077acce4f1 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryRequest.java.txt @@ -0,0 +1,67 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductByIdQueryRequest implements GraphQLOperationRequest { + + private static final GraphQLOperation OPERATION_TYPE = GraphQLOperation.QUERY; + private static final String OPERATION_NAME = "productById"; + + private Map input = new LinkedHashMap<>(); + + public ProductByIdQueryRequest() { + } + + public void setId(String id) { + this.input.put("id", id); + } + + @Override + public GraphQLOperation getOperationType() { + return OPERATION_TYPE; + } + + @Override + public String getOperationName() { + return OPERATION_NAME; + } + + @Override + public Map getInput() { + return input; + } + + @Override + public String toString() { + return Objects.toString(input); + } + + public static class Builder { + + private String id; + + public Builder() { + } + + public Builder setId(String id) { + this.id = id; + return this; + } + + + public ProductByIdQueryRequest build() { + ProductByIdQueryRequest obj = new ProductByIdQueryRequest(); + obj.setId(id); + return obj; + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..ec71104b37e0a126351c4a1fcccb026021d318c3 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResolver.java.txt @@ -0,0 +1,12 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface ProductByIdQueryResolver { + + Product productById(String id) throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResponse.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResponse.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..4f369ccb62c62ec51e428c717481f1a45b6308f5 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductByIdQueryResponse.java.txt @@ -0,0 +1,22 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResult; +import java.util.Map; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductByIdQueryResponse extends GraphQLResult> { + + private static final String OPERATION_NAME = "productById"; + + public ProductByIdQueryResponse() { + } + + public Product productById() { + Map data = getData(); + return data != null ? data.get(OPERATION_NAME) : null; + } + +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductInput.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductInput.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..a010d56bc7adbd0744ae0953240933d7ae8c1fba --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductInput.java.txt @@ -0,0 +1,135 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductInput implements java.io.Serializable { + + @javax.validation.constraints.NotNull + private String title; + private String description; + @javax.validation.constraints.NotNull + private String price; + @javax.validation.constraints.NotNull + private String sku; + private StockStatus stockStatus; + + public ProductInput() { + } + + public ProductInput(String title, String description, String price, String sku, StockStatus stockStatus) { + this.title = title; + this.description = description; + this.price = price; + this.sku = sku; + this.stockStatus = stockStatus; + } + + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public String getPrice() { + return price; + } + public void setPrice(String price) { + this.price = price; + } + + public String getSku() { + return sku; + } + public void setSku(String sku) { + this.sku = sku; + } + + public StockStatus getStockStatus() { + return stockStatus; + } + public void setStockStatus(StockStatus stockStatus) { + this.stockStatus = stockStatus; + } + + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "{ ", " }"); + if (title != null) { + joiner.add("title: " + GraphQLRequestSerializer.getEntry(title)); + } + if (description != null) { + joiner.add("description: " + GraphQLRequestSerializer.getEntry(description)); + } + if (price != null) { + joiner.add("price: " + GraphQLRequestSerializer.getEntry(price)); + } + if (sku != null) { + joiner.add("sku: " + GraphQLRequestSerializer.getEntry(sku)); + } + if (stockStatus != null) { + joiner.add("stockStatus: " + GraphQLRequestSerializer.getEntry(stockStatus)); + } + return joiner.toString(); + } + + public static ProductInput.Builder builder() { + return new ProductInput.Builder(); + } + + public static class Builder { + + private String title; + private String description; + private String price; + private String sku; + private StockStatus stockStatus; + + public Builder() { + } + + public Builder setTitle(String title) { + this.title = title; + return this; + } + + public Builder setDescription(String description) { + this.description = description; + return this; + } + + public Builder setPrice(String price) { + this.price = price; + return this; + } + + public Builder setSku(String sku) { + this.sku = sku; + return this; + } + + public Builder setStockStatus(StockStatus stockStatus) { + this.stockStatus = stockStatus; + return this; + } + + + public ProductInput build() { + return new ProductInput(title, description, price, sku, stockStatus); + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductResponseProjection.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductResponseProjection.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..7359de1dc5f19c4b566db7e36977d6dcccb410b2 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductResponseProjection.java.txt @@ -0,0 +1,91 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseField; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; + +/** + * Response projection for Product + */ +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductResponseProjection extends GraphQLResponseProjection { + + public ProductResponseProjection() { + } + + public ProductResponseProjection id() { + return id(null); + } + + public ProductResponseProjection id(String alias) { + fields.add(new GraphQLResponseField("id").alias(alias)); + return this; + } + + public ProductResponseProjection title() { + return title(null); + } + + public ProductResponseProjection title(String alias) { + fields.add(new GraphQLResponseField("title").alias(alias)); + return this; + } + + public ProductResponseProjection description() { + return description(null); + } + + public ProductResponseProjection description(String alias) { + fields.add(new GraphQLResponseField("description").alias(alias)); + return this; + } + + public ProductResponseProjection price() { + return price(null); + } + + public ProductResponseProjection price(String alias) { + fields.add(new GraphQLResponseField("price").alias(alias)); + return this; + } + + public ProductResponseProjection sku() { + return sku(null); + } + + public ProductResponseProjection sku(String alias) { + fields.add(new GraphQLResponseField("sku").alias(alias)); + return this; + } + + public ProductResponseProjection stockStatus() { + return stockStatus(null); + } + + public ProductResponseProjection stockStatus(String alias) { + fields.add(new GraphQLResponseField("stockStatus").alias(alias)); + return this; + } + + public ProductResponseProjection addedDateTime() { + return addedDateTime(null); + } + + public ProductResponseProjection addedDateTime(String alias) { + fields.add(new GraphQLResponseField("addedDateTime").alias(alias)); + return this; + } + + public ProductResponseProjection typename() { + return typename(null); + } + + public ProductResponseProjection typename(String alias) { + fields.add(new GraphQLResponseField("__typename").alias(alias)); + return this; + } + + +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryRequest.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryRequest.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0df9d78393804e1bd09a96889a0af5d63860801 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryRequest.java.txt @@ -0,0 +1,67 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductsByIdsQueryRequest implements GraphQLOperationRequest { + + private static final GraphQLOperation OPERATION_TYPE = GraphQLOperation.QUERY; + private static final String OPERATION_NAME = "productsByIds"; + + private Map input = new LinkedHashMap<>(); + + public ProductsByIdsQueryRequest() { + } + + public void setIds(java.util.List ids) { + this.input.put("ids", ids); + } + + @Override + public GraphQLOperation getOperationType() { + return OPERATION_TYPE; + } + + @Override + public String getOperationName() { + return OPERATION_NAME; + } + + @Override + public Map getInput() { + return input; + } + + @Override + public String toString() { + return Objects.toString(input); + } + + public static class Builder { + + private java.util.List ids; + + public Builder() { + } + + public Builder setIds(java.util.List ids) { + this.ids = ids; + return this; + } + + + public ProductsByIdsQueryRequest build() { + ProductsByIdsQueryRequest obj = new ProductsByIdsQueryRequest(); + obj.setIds(ids); + return obj; + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..43ff84d94b415b2c3ab074a01cb1ee3b908dc79e --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResolver.java.txt @@ -0,0 +1,12 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface ProductsByIdsQueryResolver { + + java.util.List productsByIds(java.util.List ids) throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResponse.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResponse.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..30018d5e4b027b3de697b9787cd025b90b44f763 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsByIdsQueryResponse.java.txt @@ -0,0 +1,22 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResult; +import java.util.Map; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductsByIdsQueryResponse extends GraphQLResult>> { + + private static final String OPERATION_NAME = "productsByIds"; + + public ProductsByIdsQueryResponse() { + } + + public java.util.List productsByIds() { + Map> data = getData(); + return data != null ? data.get(OPERATION_NAME) : null; + } + +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsQueryRequest.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryRequest.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..d757293abe59efd88bbb851d3dd2e45d9f505cf9 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryRequest.java.txt @@ -0,0 +1,56 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperationRequest; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductsQueryRequest implements GraphQLOperationRequest { + + private static final GraphQLOperation OPERATION_TYPE = GraphQLOperation.QUERY; + private static final String OPERATION_NAME = "products"; + + private Map input = new LinkedHashMap<>(); + + public ProductsQueryRequest() { + } + + @Override + public GraphQLOperation getOperationType() { + return OPERATION_TYPE; + } + + @Override + public String getOperationName() { + return OPERATION_NAME; + } + + @Override + public Map getInput() { + return input; + } + + @Override + public String toString() { + return Objects.toString(input); + } + + public static class Builder { + + + public Builder() { + } + + + public ProductsQueryRequest build() { + ProductsQueryRequest obj = new ProductsQueryRequest(); + return obj; + } + + } +} diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..c608e8cb9a246b803f1ca3690f21ff86ae053fe4 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResolver.java.txt @@ -0,0 +1,12 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface ProductsQueryResolver { + + java.util.List products() throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResponse.java.txt b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResponse.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..2e79caf82ef6fbe69e51deb2ea4da61ef128289f --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/ProductsQueryResponse.java.txt @@ -0,0 +1,22 @@ +package com.kobylynskyi.graphql.test1; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResult; +import java.util.Map; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class ProductsQueryResponse extends GraphQLResult>> { + + private static final String OPERATION_NAME = "products"; + + public ProductsQueryResponse() { + } + + public java.util.List products() { + Map> data = getData(); + return data != null ? data.get(OPERATION_NAME) : null; + } + +} diff --git a/src/test/resources/expected-classes/from-introspection-result/QueryResolver.java.txt b/src/test/resources/expected-classes/from-introspection-result/QueryResolver.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..9632c41f54e1664f0c63041e39941565d9963f77 --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/QueryResolver.java.txt @@ -0,0 +1,16 @@ +package com.kobylynskyi.graphql.test1; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface QueryResolver { + + java.util.List products() throws Exception; + + Product productById(String id) throws Exception; + + java.util.List productsByIds(java.util.List ids) throws Exception; + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/from-introspection-result/StockStatus.java.txt b/src/test/resources/expected-classes/from-introspection-result/StockStatus.java.txt new file mode 100644 index 0000000000000000000000000000000000000000..b38c08360b8ba349a34aa0374a63a4b5995658ad --- /dev/null +++ b/src/test/resources/expected-classes/from-introspection-result/StockStatus.java.txt @@ -0,0 +1,27 @@ +package com.kobylynskyi.graphql.test1; + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public enum StockStatus { + + IN_STOCK("IN_STOCK"), + SPECIAL_ORDER("SPECIAL_ORDER"), + BACK_ORDERED("BACK_ORDERED"), + COMING_SOON("COMING_SOON"), + SOLD_OUT("SOLD_OUT"), + DISCONTINUED("DISCONTINUED"); + + private final String graphqlName; + + private StockStatus(String graphqlName) { + this.graphqlName = graphqlName; + } + + @Override + public String toString() { + return this.graphqlName; + } + +} \ No newline at end of file diff --git a/src/test/resources/introspection-result/sample-introspection-query-result-wrapped.json b/src/test/resources/introspection-result/sample-introspection-query-result-wrapped.json new file mode 100644 index 0000000000000000000000000000000000000000..a9c74981c3d6b1e7f0fc5e77c8f6064b7b8c9bb7 --- /dev/null +++ b/src/test/resources/introspection-result/sample-introspection-query-result-wrapped.json @@ -0,0 +1,1309 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": { + "name": "Mutation" + }, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "BigDecimal", + "description": "Built-in java.math.BigDecimal", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "DateTime", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "ID", + "description": "Built-in ID", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Mutation", + "description": "", + "fields": [ + { + "name": "create", + "description": "", + "args": [ + { + "name": "productInput", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProductInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Product", + "description": "", + "fields": [ + { + "name": "id", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "price", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigDecimal", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sku", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stockStatus", + "description": "", + "args": [], + "type": { + "kind": "ENUM", + "name": "StockStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addedDateTime", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ProductInput", + "description": "", + "fields": null, + "inputFields": [ + { + "name": "title", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "description", + "description": "", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "price", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigDecimal", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "sku", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "stockStatus", + "description": "", + "type": { + "kind": "ENUM", + "name": "StockStatus", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": "", + "fields": [ + { + "name": "products", + "description": "", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productById", + "description": "", + "args": [ + { + "name": "id", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productsByIds", + "description": "", + "args": [ + { + "name": "ids", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID" + } + } + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "StockStatus", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "IN_STOCK", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SPECIAL_ORDER", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BACK_ORDERED", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMING_SOON", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SOLD_OUT", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DISCONTINUED", + "description": "", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__DirectiveLocation", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "onOperation", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onFragment", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onField", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__DirectiveLocation", + "description": "An enum describing valid locations where a directive can be placed", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "QUERY", + "description": "Indicates the directive is valid on queries.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MUTATION", + "description": "Indicates the directive is valid on mutations.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD", + "description": "Indicates the directive is valid on fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_DEFINITION", + "description": "Indicates the directive is valid on fragment definitions.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_SPREAD", + "description": "Indicates the directive is valid on fragment spreads.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INLINE_FRAGMENT", + "description": "Indicates the directive is valid on inline fragments.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCHEMA", + "description": "Indicates the directive is valid on a schema SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCALAR", + "description": "Indicates the directive is valid on a scalar SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Indicates the directive is valid on an object SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD_DEFINITION", + "description": "Indicates the directive is valid on a field SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ARGUMENT_DEFINITION", + "description": "Indicates the directive is valid on a field argument SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Indicates the directive is valid on an interface SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Indicates the directive is valid on an union SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Indicates the directive is valid on an enum SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM_VALUE", + "description": "Indicates the directive is valid on an enum value SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Indicates the directive is valid on an input object SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_FIELD_DEFINITION", + "description": "Indicates the directive is valid on an input object field SDL definition.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__EnumValue", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Field", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__InputValue", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "defaultValue", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Schema", + "description": "A GraphQL Introspection defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, the entry points for query, mutation, and subscription operations.", + "fields": [ + { + "name": "types", + "description": "A list of all types supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "queryType", + "description": "The type that query operations will be rooted at.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mutationType", + "description": "If this server supports mutation, the type that mutation operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "directives", + "description": "'A list of all directives supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Directive" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscriptionType", + "description": "'If this server support subscription, the type that subscription operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Type", + "description": null, + "fields": [ + { + "name": "kind", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__TypeKind", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fields", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Field", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "interfaces", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "possibleTypes", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "enumValues", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__EnumValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inputFields", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__TypeKind", + "description": "An enum describing what kind of type a given __Type is", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SCALAR", + "description": "Indicates this type is a scalar.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Indicates this type is a union. `possibleTypes` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Indicates this type is an enum. `enumValues` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Indicates this type is an input object. `inputFields` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LIST", + "description": "Indicates this type is a list. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NON_NULL", + "description": "Indicates this type is a non-null. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true", + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "onOperation": false, + "onFragment": true, + "onField": true + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if`'argument is true.", + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "onOperation": false, + "onFragment": true, + "onField": true + }, + { + "name": "deprecated", + "description": "Marks the field or enum value as deprecated", + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": "\"No longer supported\"" + } + ], + "onOperation": false, + "onFragment": false, + "onField": false + } + ] + } + } +} \ No newline at end of file diff --git a/src/test/resources/introspection-result/sample-introspection-query-result.json b/src/test/resources/introspection-result/sample-introspection-query-result.json new file mode 100644 index 0000000000000000000000000000000000000000..8d26b3283dde27319dcc04d5b392b43be5f6f763 --- /dev/null +++ b/src/test/resources/introspection-result/sample-introspection-query-result.json @@ -0,0 +1,1307 @@ +{ + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": { + "name": "Mutation" + }, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "BigDecimal", + "description": "Built-in java.math.BigDecimal", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "DateTime", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "ID", + "description": "Built-in ID", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Mutation", + "description": "", + "fields": [ + { + "name": "create", + "description": "", + "args": [ + { + "name": "productInput", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "ProductInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Product", + "description": "", + "fields": [ + { + "name": "id", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "title", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": "", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "price", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigDecimal", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "sku", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "stockStatus", + "description": "", + "args": [], + "type": { + "kind": "ENUM", + "name": "StockStatus", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "addedDateTime", + "description": "", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "DateTime", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "ProductInput", + "description": "", + "fields": null, + "inputFields": [ + { + "name": "title", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "description", + "description": "", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + }, + { + "name": "price", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "BigDecimal", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "sku", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "stockStatus", + "description": "", + "type": { + "kind": "ENUM", + "name": "StockStatus", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": "", + "fields": [ + { + "name": "products", + "description": "", + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productById", + "description": "", + "args": [ + { + "name": "id", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "productsByIds", + "description": "", + "args": [ + { + "name": "ids", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID" + } + } + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "Product", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "StockStatus", + "description": "", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "IN_STOCK", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SPECIAL_ORDER", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "BACK_ORDERED", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "COMING_SOON", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SOLD_OUT", + "description": "", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "DISCONTINUED", + "description": "", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__DirectiveLocation", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "onOperation", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onFragment", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + }, + { + "name": "onField", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "Use `locations`." + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__DirectiveLocation", + "description": "An enum describing valid locations where a directive can be placed", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "QUERY", + "description": "Indicates the directive is valid on queries.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "MUTATION", + "description": "Indicates the directive is valid on mutations.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD", + "description": "Indicates the directive is valid on fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_DEFINITION", + "description": "Indicates the directive is valid on fragment definitions.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FRAGMENT_SPREAD", + "description": "Indicates the directive is valid on fragment spreads.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INLINE_FRAGMENT", + "description": "Indicates the directive is valid on inline fragments.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCHEMA", + "description": "Indicates the directive is valid on a schema SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "SCALAR", + "description": "Indicates the directive is valid on a scalar SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Indicates the directive is valid on an object SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "FIELD_DEFINITION", + "description": "Indicates the directive is valid on a field SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ARGUMENT_DEFINITION", + "description": "Indicates the directive is valid on a field argument SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Indicates the directive is valid on an interface SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Indicates the directive is valid on an union SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Indicates the directive is valid on an enum SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM_VALUE", + "description": "Indicates the directive is valid on an enum value SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Indicates the directive is valid on an input object SDL definition.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_FIELD_DEFINITION", + "description": "Indicates the directive is valid on an input object field SDL definition.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__EnumValue", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Field", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "args", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "deprecationReason", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__InputValue", + "description": null, + "fields": [ + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "type", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "defaultValue", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Schema", + "description": "A GraphQL Introspection defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, the entry points for query, mutation, and subscription operations.", + "fields": [ + { + "name": "types", + "description": "A list of all types supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "queryType", + "description": "The type that query operations will be rooted at.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "mutationType", + "description": "If this server supports mutation, the type that mutation operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "directives", + "description": "'A list of all directives supported by this server.", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Directive" + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "subscriptionType", + "description": "'If this server support subscription, the type that subscription operations will be rooted at.", + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Type", + "description": null, + "fields": [ + { + "name": "kind", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "__TypeKind", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fields", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Field", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "interfaces", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "possibleTypes", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "enumValues", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__EnumValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inputFields", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "__TypeKind", + "description": "An enum describing what kind of type a given __Type is", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ + { + "name": "SCALAR", + "description": "Indicates this type is a scalar.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "OBJECT", + "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INTERFACE", + "description": "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "UNION", + "description": "Indicates this type is a union. `possibleTypes` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ENUM", + "description": "Indicates this type is an enum. `enumValues` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "INPUT_OBJECT", + "description": "Indicates this type is an input object. `inputFields` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "LIST", + "description": "Indicates this type is a list. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "NON_NULL", + "description": "Indicates this type is a non-null. `ofType` is a valid field.", + "isDeprecated": false, + "deprecationReason": null + } + ], + "possibleTypes": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true", + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "onOperation": false, + "onFragment": true, + "onField": true + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if`'argument is true.", + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "onOperation": false, + "onFragment": true, + "onField": true + }, + { + "name": "deprecated", + "description": "Marks the field or enum value as deprecated", + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": "\"No longer supported\"" + } + ], + "onOperation": false, + "onFragment": false, + "onField": false + } + ] + } +}