From 1b411f519cde8a197d1cfc12c388a104cc5240e7 Mon Sep 17 00:00:00 2001 From: Martin Bonnin Date: Thu, 17 Aug 2023 13:29:19 +0200 Subject: [PATCH] Add `mergeExtensions` and `toFullSchemaGQLDocument` (#5162) * cleanup the introspection API add GQLDocument.toFullSchemaGQLDocument and GQLDocument.mergeExtensions * Make methods callable from Java * remove old GQLDocument constructor * Update libraries/apollo-gradle-plugin/src/test/kotlin/util/TestUtils.kt Co-authored-by: Benoit Lubek * add comment * rename file --------- Co-authored-by: Benoit Lubek --- build-logic/src/main/kotlin/Common.kt | 4 +- docs/source/advanced/apollo-ast.mdx | 7 +- docs/source/migration/4.0.mdx | 12 +- libraries/apollo-ast/api/apollo-ast.api | 550 +------- .../apollographql/apollo3/ast/SDLWriter.kt | 2 + .../com/apollographql/apollo3/ast/Schema.kt | 2 +- .../apollo3/ast/SourceLocation.kt | 2 +- .../com/apollographql/apollo3/ast/api.kt | 42 +- .../com/apollographql/apollo3/ast/gql.kt | 7 +- .../apollographql/apollo3/ast/gqldirective.kt | 13 + .../apollographql/apollo3/ast/gqldocument.kt | 24 +- .../com/apollographql/apollo3/ast/gqlnode.kt | 2 + ...sionsMergeScope.kt => ExtensionsMerger.kt} | 156 ++- .../ast/internal/SchemaValidationScope.kt | 16 +- .../apollo3/ast/internal/ValidationCommon.kt | 2 +- .../apollo3/ast/internal/definitions.kt | 32 +- .../ast/introspection/IntrospectionSchema.kt | 256 ---- .../ast/introspection/introspection_reader.kt | 558 ++++++++ .../introspection/introspection_to_schema.kt | 345 ----- .../ast/introspection/introspection_writer.kt | 417 ++++++ .../introspection/schema_to_introspection.kt | 250 ---- .../apollo3/graphql/ast/test/SchemaTest.kt | 3 +- .../test/introspection/IntrospectionTest.kt | 29 +- .../validation/OperationValidationTest.kt | 38 +- .../com/apollographql/apollo3/ast/api.jvm.kt | 13 + .../apollo3/ast/internal/antlr_to_gql.kt | 5 +- .../introspection/IntrospectionSchema.jvm.kt | 16 - .../ast/introspection/introspection.jvm.kt | 16 + .../introspection_to_schema.jvm.kt | 25 - .../graphql/ast/test/IntrospectionTest.jvm.kt | 54 + .../apollo3/graphql/ast/test/SDLWriterTest.kt | 8 +- .../introspection/confetti.expected | 1 + .../introspection/confetti.graphqls | 166 +++ .../test-fixtures/introspection/draft.json | 1172 +++++++++++++++++ .../test-fixtures/introspection/july2015.json | 1055 +++++++++++++++ .../test-fixtures/introspection/june2018.json | 1135 ++++++++++++++++ .../introspection/missing_default_values.json | 1163 ++++++++++++++++ .../introspection/october2021.json | 1154 ++++++++++++++++ .../test-fixtures/sdl/introspection.expected | 170 +-- .../apollo3/compiler/ApolloCompiler.kt | 24 +- .../compiler/checkCapitalizedFields.kt | 5 +- .../compiler/checkConditionalFragment.kt | 17 +- .../apollo3/compiler/CodegenTest.kt | 4 +- .../apollo3/compiler/PossibleTypesTest.kt | 2 +- .../apollo3/compiler/SdlWritingTest.kt | 5 +- .../apollo3/compiler/StringEncodingTest.kt | 6 +- .../apollo3/compiler/TestUtils.kt | 4 +- .../apollo3/compiler/TypenameTest.kt | 4 +- .../ConditionalFragmentsTest.kt | 2 +- .../compiler/keyfields/KeyFieldsTest.kt | 25 +- .../internal/ApolloConvertSchemaTask.kt | 5 +- .../gradle/internal/SchemaExtensions.kt | 33 - .../apollo3/gradle/test/ConvertSchemaTests.kt | 2 +- .../convertSchema/schemas/schema.json | 909 ++++++++++--- .../main/graphql/graphql/july2015/README.md | 1 + .../graphql/july2015/operations.graphql | 89 ++ .../graphql/graphql/july2015/schema.graphqls | 80 ++ .../graphql/october2021/operations.graphql | 2 +- .../apollo3/tooling/SchemaDownloader.kt | 19 +- 59 files changed, 8129 insertions(+), 2031 deletions(-) rename libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/{TypeExtensionsMergeScope.kt => ExtensionsMerger.kt} (56%) delete mode 100644 libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt create mode 100644 libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_reader.kt delete mode 100644 libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.kt create mode 100644 libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_writer.kt delete mode 100644 libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/schema_to_introspection.kt delete mode 100644 libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.jvm.kt create mode 100644 libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection.jvm.kt delete mode 100644 libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.jvm.kt create mode 100644 libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/IntrospectionTest.jvm.kt create mode 100644 libraries/apollo-ast/test-fixtures/introspection/confetti.expected create mode 100644 libraries/apollo-ast/test-fixtures/introspection/confetti.graphqls create mode 100644 libraries/apollo-ast/test-fixtures/introspection/draft.json create mode 100644 libraries/apollo-ast/test-fixtures/introspection/july2015.json create mode 100644 libraries/apollo-ast/test-fixtures/introspection/june2018.json create mode 100644 libraries/apollo-ast/test-fixtures/introspection/missing_default_values.json create mode 100644 libraries/apollo-ast/test-fixtures/introspection/october2021.json delete mode 100644 libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/SchemaExtensions.kt create mode 100644 libraries/apollo-tooling/src/main/graphql/graphql/july2015/README.md create mode 100644 libraries/apollo-tooling/src/main/graphql/graphql/july2015/operations.graphql create mode 100644 libraries/apollo-tooling/src/main/graphql/graphql/july2015/schema.graphqls diff --git a/build-logic/src/main/kotlin/Common.kt b/build-logic/src/main/kotlin/Common.kt index 0a797973303..d3730a25ca6 100644 --- a/build-logic/src/main/kotlin/Common.kt +++ b/build-logic/src/main/kotlin/Common.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest fun Project.commonSetup() { pluginManager.withPlugin("org.jetbrains.kotlin.jvm") { tasks.register("ft") { - if (this@commonSetup.name != "apollo-gradle-plugin") { + if (this@commonSetup.name !in setOf("apollo-gradle-plugin", "intellij-plugin")) { dependsOn("test") } } @@ -37,6 +37,8 @@ private fun Project.configureTestAggregation() { attribute(USAGE_ATTRIBUTE, objects.named(Usage::class.java, "apolloTestAggregation")) } } + // Hide this from the 'assemble' task + configuration.setVisible(false) tasks.withType(AbstractTestTask::class.java).configureEach { configuration.getOutgoing().artifact( diff --git a/docs/source/advanced/apollo-ast.mdx b/docs/source/advanced/apollo-ast.mdx index bbbc3e8b9f1..7126fa0829e 100644 --- a/docs/source/advanced/apollo-ast.mdx +++ b/docs/source/advanced/apollo-ast.mdx @@ -42,7 +42,7 @@ val graphQLText = """ } """.trimIndent() -val parseResult = Buffer().writeUtf8(graphQLText).parseAsGQLDocument() +val parseResult = graphQLText.parseAsGQLDocument() ``` This method returns a `GQLResult`, which contains the document and/or parsing issues, each of which can have a severity of either `WARNING` or `ERROR`. Because there can be warnings, it is possible to have both a valid document and issues at the same time. @@ -111,7 +111,7 @@ val schemaText = """ } """.trimIndent() -val schemaGQLDocument = Buffer().writeUtf8(schemaText).parseAsGQLDocument().getOrThrow() +val schemaGQLDocument = schemaText.parseAsGQLDocument().getOrThrow() val schemaResult = schemaGQLDocument.validateAsSchema() println(schemaResult.issues.map { it.severity.name + ": " + it.message }) ``` @@ -146,9 +146,6 @@ println(queryGqlDocument.toUtf8()) // Output to a File queryGqlDocument.toUtf8(file) - -// Output to an Okio BufferedSink -queryGqlDocument.toUtf8(sink) ``` ## Transforming an AST diff --git a/docs/source/migration/4.0.mdx b/docs/source/migration/4.0.mdx index 76fc9641d10..46413f6f459 100644 --- a/docs/source/migration/4.0.mdx +++ b/docs/source/migration/4.0.mdx @@ -197,15 +197,17 @@ The normalized cache must be configured before the auto persisted queries, confi ## apollo-ast -The AST classes (`GQLNode` and subclasses) as well as `Introspection` classes are not data classes anymore (see https://github.com/apollographql/apollo-kotlin/pull/4704/). +The AST classes (`GQLNode` and subclasses) as well as `Introspection` classes are not data classes anymore (see https://github.com/apollographql/apollo-kotlin/pull/4704/). The class hierarchy has been tweaked so that `GQLNamed`, `GQLDescribed` and `GQLHasDirectives` are more consistently inherited from. -`GQLSelectionSet` and `GQLArguments` are deprecated and removed from `GQLField`, `GQLInlineFragment` and other constructors. Use `.selections` directly +`GQLSelectionSet` and `GQLArguments` are deprecated and removed from `GQLField` and `GQLInlineFragment`. Use `.selections` directly -`GQLInlineFragment.typeCondition` is now nullable to account for inline fragments who inherit their type condition +`GQLInlineFragment.typeCondition` is now nullable to account for inline fragments who inherit their type condition. + +`SourceLocation.position` is renamed `SourceLocation.column` and is now 1-indexed. `GQLNode.sourceLocation` is now nullable to account for the cases where the nodes are constructed programmatically. + +It is not possible to create a `Schema` from a File or String directly anymore. Instead, create a `GQLDocument` first and convert it to a schema with `toSchema()`. -`SourceLocation.position` is renamed `SourceLocation.column` and is now 1-indexed -`GQLNode.sourceLocation` is now nullable ## Gradle configuration diff --git a/libraries/apollo-ast/api/apollo-ast.api b/libraries/apollo-ast/api/apollo-ast.api index 9ef056f6104..69a726fc095 100644 --- a/libraries/apollo-ast/api/apollo-ast.api +++ b/libraries/apollo-ast/api/apollo-ast.api @@ -11,7 +11,20 @@ public final class com/apollographql/apollo3/ast/ApolloParser { public static synthetic fun parseAsGQLType$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLResult; public static final fun parseAsGQLValue (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Lcom/apollographql/apollo3/ast/GQLResult; public static synthetic fun parseAsGQLValue$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLResult; - public static final fun toSchema (Ljava/lang/String;)Lcom/apollographql/apollo3/ast/Schema; + public static final fun toGQLDocument (Ljava/io/File;Lcom/apollographql/apollo3/ast/ParserOptions;Z)Lcom/apollographql/apollo3/ast/GQLDocument; + public static final fun toGQLDocument (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Lcom/apollographql/apollo3/ast/GQLDocument; + public static final fun toGQLDocument (Lokio/Path;Lcom/apollographql/apollo3/ast/ParserOptions;Z)Lcom/apollographql/apollo3/ast/GQLDocument; + public static synthetic fun toGQLDocument$default (Ljava/io/File;Lcom/apollographql/apollo3/ast/ParserOptions;ZILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLDocument; + public static synthetic fun toGQLDocument$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLDocument; + public static synthetic fun toGQLDocument$default (Lokio/Path;Lcom/apollographql/apollo3/ast/ParserOptions;ZILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLDocument; + public static final fun toGQLNullability (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Lcom/apollographql/apollo3/ast/GQLNullability; + public static synthetic fun toGQLNullability$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLNullability; + public static final fun toGQLSelections (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Ljava/util/List; + public static synthetic fun toGQLSelections$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Ljava/util/List; + public static final fun toGQLType (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Lcom/apollographql/apollo3/ast/GQLType; + public static synthetic fun toGQLType$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLType; + public static final fun toGQLValue (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;)Lcom/apollographql/apollo3/ast/GQLValue; + public static synthetic fun toGQLValue$default (Ljava/lang/String;Lcom/apollographql/apollo3/ast/ParserOptions;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLValue; } public final class com/apollographql/apollo3/ast/ConversionException : com/apollographql/apollo3/ast/SourceAwareException { @@ -125,7 +138,6 @@ public final class com/apollographql/apollo3/ast/GQLDirectiveLocation : java/lan public final class com/apollographql/apollo3/ast/GQLDocument : com/apollographql/apollo3/ast/GQLNode { public static final field Companion Lcom/apollographql/apollo3/ast/GQLDocument$Companion; public fun (Ljava/util/List;Lcom/apollographql/apollo3/ast/SourceLocation;)V - public fun (Ljava/util/List;Ljava/lang/String;)V public final fun copy (Ljava/util/List;Lcom/apollographql/apollo3/ast/SourceLocation;)Lcom/apollographql/apollo3/ast/GQLDocument; public static synthetic fun copy$default (Lcom/apollographql/apollo3/ast/GQLDocument;Ljava/util/List;Lcom/apollographql/apollo3/ast/SourceLocation;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/GQLDocument; public fun copyWithNewChildrenInternal (Lcom/apollographql/apollo3/ast/NodeContainer;)Lcom/apollographql/apollo3/ast/GQLNode; @@ -641,7 +653,7 @@ public final class com/apollographql/apollo3/ast/GQLTypeDefinition$Companion { public abstract interface class com/apollographql/apollo3/ast/GQLTypeExtension : com/apollographql/apollo3/ast/GQLNamed, com/apollographql/apollo3/ast/GQLTypeSystemExtension { } -public abstract interface class com/apollographql/apollo3/ast/GQLTypeSystemExtension : com/apollographql/apollo3/ast/GQLNode { +public abstract interface class com/apollographql/apollo3/ast/GQLTypeSystemExtension : com/apollographql/apollo3/ast/GQLDefinition { } public final class com/apollographql/apollo3/ast/GQLUnionTypeDefinition : com/apollographql/apollo3/ast/GQLTypeDefinition { @@ -704,11 +716,11 @@ public final class com/apollographql/apollo3/ast/GQLVariableValue : com/apollogr } public final class com/apollographql/apollo3/ast/GqlKt { - public static final fun transform (Lcom/apollographql/apollo3/ast/GQLNode;Lcom/apollographql/apollo3/ast/NodeTransformer;)Lcom/apollographql/apollo3/ast/GQLNode; } public final class com/apollographql/apollo3/ast/GqldirectiveKt { public static final fun findDeprecationReason (Ljava/util/List;)Ljava/lang/String; + public static final fun findSpecifiedBy (Ljava/util/List;)Ljava/lang/String; } public final class com/apollographql/apollo3/ast/GqldocumentKt { @@ -716,6 +728,7 @@ public final class com/apollographql/apollo3/ast/GqldocumentKt { public static final fun apolloDefinitions (Ljava/lang/String;)Ljava/util/List; public static final fun builtinDefinitions ()Ljava/util/List; public static final fun linkDefinitions ()Ljava/util/List; + public static final fun toSchema (Lcom/apollographql/apollo3/ast/GQLDocument;)Lcom/apollographql/apollo3/ast/Schema; public static final fun withBuiltinDefinitions (Lcom/apollographql/apollo3/ast/GQLDocument;)Lcom/apollographql/apollo3/ast/GQLDocument; public static final fun withoutBuiltinDefinitions (Lcom/apollographql/apollo3/ast/GQLDocument;)Lcom/apollographql/apollo3/ast/GQLDocument; } @@ -730,10 +743,8 @@ public final class com/apollographql/apollo3/ast/GqlfieldKt { public final class com/apollographql/apollo3/ast/GqlnodeKt { public static final fun toUtf8 (Lcom/apollographql/apollo3/ast/GQLNode;Ljava/io/File;Ljava/lang/String;)V public static final fun toUtf8 (Lcom/apollographql/apollo3/ast/GQLNode;Ljava/lang/String;)Ljava/lang/String; - public static final fun toUtf8 (Lcom/apollographql/apollo3/ast/GQLNode;Lokio/BufferedSink;Ljava/lang/String;)V public static synthetic fun toUtf8$default (Lcom/apollographql/apollo3/ast/GQLNode;Ljava/io/File;Ljava/lang/String;ILjava/lang/Object;)V public static synthetic fun toUtf8$default (Lcom/apollographql/apollo3/ast/GQLNode;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String; - public static synthetic fun toUtf8$default (Lcom/apollographql/apollo3/ast/GQLNode;Lokio/BufferedSink;Ljava/lang/String;ILjava/lang/Object;)V } public final class com/apollographql/apollo3/ast/GqloperationdefinitionKt { @@ -834,10 +845,6 @@ public final class com/apollographql/apollo3/ast/NodeContainer { public final fun setRemainingNodes (Ljava/util/List;)V } -public abstract interface class com/apollographql/apollo3/ast/NodeTransformer { - public abstract fun transform (Lcom/apollographql/apollo3/ast/GQLNode;)Lcom/apollographql/apollo3/ast/TransformResult; -} - public final class com/apollographql/apollo3/ast/ParserOptions { public static final field Companion Lcom/apollographql/apollo3/ast/ParserOptions$Companion; public synthetic fun (ZZZZLkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -873,15 +880,6 @@ public final class com/apollographql/apollo3/ast/QueryDocumentMinifier { public static final fun minify (Ljava/lang/String;)Ljava/lang/String; } -public class com/apollographql/apollo3/ast/SDLWriter : java/io/Closeable { - public fun (Lokio/BufferedSink;Ljava/lang/String;)V - public fun close ()V - public final fun indent ()V - public final fun unindent ()V - public fun write (Lcom/apollographql/apollo3/ast/GQLNode;)V - public final fun write (Ljava/lang/String;)V -} - public final class com/apollographql/apollo3/ast/Schema { public static final field Companion Lcom/apollographql/apollo3/ast/Schema$Companion; public static final field FIELD_POLICY Ljava/lang/String; @@ -951,9 +949,6 @@ public final class com/apollographql/apollo3/ast/SourceLocationKt { public static final fun pretty (Lcom/apollographql/apollo3/ast/SourceLocation;)Ljava/lang/String; } -public abstract interface class com/apollographql/apollo3/ast/TransformResult { -} - public final class com/apollographql/apollo3/ast/TransformResult$Continue : com/apollographql/apollo3/ast/TransformResult { public static final field INSTANCE Lcom/apollographql/apollo3/ast/TransformResult$Continue; } @@ -986,519 +981,22 @@ public final class com/apollographql/apollo3/ast/VariableUsage { public final fun getVariable ()Lcom/apollographql/apollo3/ast/GQLVariableValue; } -public abstract interface class com/apollographql/apollo3/ast/internal/IssuesScope { - public abstract fun getIssues ()Ljava/util/List; -} - public final class com/apollographql/apollo3/ast/internal/SchemaValidationScopeKt { } -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Companion; - public synthetic fun (ILcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema;)V - public final fun get__schema ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Companion; - public synthetic fun (ILcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType;Ljava/util/List;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType;Ljava/util/List;Ljava/util/List;)V - public synthetic fun (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType;Ljava/util/List;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getDirectives ()Ljava/util/List; - public final fun getMutationType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType; - public final fun getQueryType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType; - public final fun getSubscriptionType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType; - public final fun getTypes ()Ljava/util/List; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getDefaultValue ()Ljava/lang/String; - public final fun getDeprecationReason ()Ljava/lang/String; - public final fun getDescription ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef; - public final fun isDeprecated ()Z - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Argument$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZLkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Z)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getArgs ()Ljava/util/List; - public final fun getDescription ()Ljava/lang/String; - public final fun getLocations ()Ljava/util/List; - public final fun getName ()Ljava/lang/String; - public final fun isRepeatable ()Z - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation : java/lang/Enum { - public static final field ARGUMENT_DEFINITION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field ENUM Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field ENUM_VALUE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field FIELD Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field FIELD_DEFINITION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field FRAGMENT_DEFINITION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field FRAGMENT_SPREAD Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field INLINE_FRAGMENT Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field INPUT_FIELD_DEFINITION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field INPUT_OBJECT Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field INTERFACE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field MUTATION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field OBJECT Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field QUERY Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field SCALAR Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field SCHEMA Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field SUBSCRIPTION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field UNION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static final field VARIABLE_DEFINITION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static fun valueOf (Ljava/lang/String;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; - public static fun values ()[Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Directive$DirectiveLocation; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/util/List;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getArgs ()Ljava/util/List; - public final fun getDeprecationReason ()Ljava/lang/String; - public final fun getDescription ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef; - public final fun isDeprecated ()Z - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Field$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getDefaultValue ()Ljava/lang/String; - public final fun getDeprecationReason ()Ljava/lang/String; - public final fun getDescription ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef; - public final fun isDeprecated ()Z - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$InputField$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind : java/lang/Enum { - public static final field ENUM Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field INPUT_OBJECT Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field INTERFACE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field LIST Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field NON_NULL Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field OBJECT Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field SCALAR Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static final field UNION Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static fun valueOf (Ljava/lang/String;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public static fun values ()[Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType$Companion; - public synthetic fun (ILjava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;)V - public final fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$MutationType$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType$Companion; - public synthetic fun (ILjava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;)V - public final fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$QueryType$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType$Companion; - public synthetic fun (ILjava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;)V - public final fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$SubscriptionType$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public abstract class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Companion; - public synthetic fun (ILkotlinx/serialization/internal/SerializationConstructorMarker;)V - public abstract fun getDescription ()Ljava/lang/String; - public abstract fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V - public fun getDescription ()Ljava/lang/String; - public final fun getEnumValues ()Ljava/util/List; - public fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getDeprecationReason ()Ljava/lang/String; - public final fun getDescription ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun isDeprecated ()Z - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V +public final class com/apollographql/apollo3/ast/introspection/ApolloIntrospectionSchema { } -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Enum$Value$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)V - public fun getDescription ()Ljava/lang/String; - public final fun getInputFields ()Ljava/util/List; - public fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$InputObject$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Ljava/util/List;)V - public fun getDescription ()Ljava/lang/String; - public final fun getFields ()Ljava/util/List; - public final fun getInterfaces ()Ljava/util/List; - public fun getName ()Ljava/lang/String; - public final fun getPossibleTypes ()Ljava/util/List; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Interface$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V - public fun getDescription ()Ljava/lang/String; - public final fun getFields ()Ljava/util/List; - public final fun getInterfaces ()Ljava/util/List; - public fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Object$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;)V - public fun getDescription ()Ljava/lang/String; - public fun getName ()Ljava/lang/String; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Scalar$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union : com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union$Companion; - public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V - public fun getDescription ()Ljava/lang/String; - public final fun getFields ()Ljava/util/List; - public fun getName ()Ljava/lang/String; - public final fun getPossibleTypes ()Ljava/util/List; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Type$Union$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef { - public static final field Companion Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef$Companion; - public synthetic fun (ILcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind;Ljava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind;Ljava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;)V - public synthetic fun (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind;Ljava/lang/String;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun getKind ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$Kind; - public final fun getName ()Ljava/lang/String; - public final fun getOfType ()Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef; - public static final synthetic fun write$Self (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef$$serializer; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef;)V - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema$TypeRef$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - -public final class com/apollographql/apollo3/ast/introspection/IntrospectionSchemaKt { - public static final fun normalize (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema$Schema; - public static final fun normalize (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; +public final class com/apollographql/apollo3/ast/introspection/Introspection { + public static final fun toGQLDocument (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;)Lcom/apollographql/apollo3/ast/GQLDocument; + public static final fun toIntrospectionSchema (Lcom/apollographql/apollo3/ast/GQLDocument;)Lcom/apollographql/apollo3/ast/introspection/ApolloIntrospectionSchema; public static final fun toIntrospectionSchema (Ljava/io/File;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; public static final fun toIntrospectionSchema (Ljava/lang/String;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; - public static final fun toIntrospectionSchema (Lokio/BufferedSource;Ljava/lang/String;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; - public static synthetic fun toIntrospectionSchema$default (Lokio/BufferedSource;Ljava/lang/String;ILjava/lang/Object;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; - public static final fun toJson (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;)Ljava/lang/String; - public static final fun writeTo (Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema;Ljava/io/File;)V -} - -public final class com/apollographql/apollo3/ast/introspection/Introspection_to_schemaKt { + public static final fun toJson (Lcom/apollographql/apollo3/ast/introspection/ApolloIntrospectionSchema;)Ljava/lang/String; + public static final fun writeTo (Lcom/apollographql/apollo3/ast/introspection/ApolloIntrospectionSchema;Ljava/io/File;)V } -public final class com/apollographql/apollo3/ast/introspection/Schema_to_introspectionKt { - public static final fun toIntrospectionSchema (Lcom/apollographql/apollo3/ast/Schema;)Lcom/apollographql/apollo3/ast/introspection/IntrospectionSchema; +public abstract interface class com/apollographql/apollo3/ast/introspection/IntrospectionSchema { } public class com/apollographql/apollo3/generated/antlr/GraphQLBaseListener : com/apollographql/apollo3/generated/antlr/GraphQLListener { diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SDLWriter.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SDLWriter.kt index 8b2557e42e5..312bf2f9c49 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SDLWriter.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SDLWriter.kt @@ -1,11 +1,13 @@ package com.apollographql.apollo3.ast +import com.apollographql.apollo3.annotations.ApolloInternal import okio.BufferedSink import okio.Closeable /** * A [SDLWriter] writes utf8 text to the given sink and supports [indent]/[unindent] */ +@ApolloInternal open class SDLWriter( private val sink: BufferedSink, private val indent: String, diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/Schema.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/Schema.kt index 8f6002bfb5d..d92834b1778 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/Schema.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/Schema.kt @@ -47,7 +47,7 @@ class Schema internal constructor( fun toGQLDocument(): GQLDocument = GQLDocument( definitions = definitions, - filePath = null + sourceLocation = null ) /** diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt index 3a90958d653..24347971861 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/SourceLocation.kt @@ -31,7 +31,7 @@ class SourceLocation( get() = column - 1 override fun toString(): String { - return "($line:$column)" + return pretty() } fun pretty(): String = "$filePath: ($line, $column)" diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/api.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/api.kt index 0dccc1fd034..7e6f29716a1 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/api.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/api.kt @@ -11,6 +11,8 @@ import com.apollographql.apollo3.ast.internal.LexerException import com.apollographql.apollo3.ast.internal.Parser import com.apollographql.apollo3.ast.internal.ParserException import com.apollographql.apollo3.ast.internal.validateSchema +import com.apollographql.apollo3.ast.introspection.toGQLDocument +import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema import okio.Buffer import okio.BufferedSource import okio.Path @@ -19,16 +21,6 @@ import okio.use import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName -/** - * Parses the source to a [Schema], throwing on parsing or validation errors. - * - * See [parseAsGQLDocument] and [validateAsSchema] for more granular error reporting - */ -@ApolloExperimental -fun BufferedSource.toSchema(filePath: String? = null): Schema = parseAsGQLDocument(filePath).getOrThrow().validateAsSchema().getOrThrow() - -fun String.toSchema(): Schema = parseAsGQLDocument().getOrThrow().validateAsSchema().getOrThrow() - /** * Parses the source to a List<[GQLDefinition]>, throwing on parsing or validation errors. * @@ -145,6 +137,10 @@ fun String.parseAsGQLDocument(options: ParserOptions = ParserOptions.Default): G } } +fun String.toGQLDocument(options: ParserOptions = ParserOptions.Default): GQLDocument { + return parseAsGQLDocument(options).getOrThrow() +} + fun String.parseAsGQLValue(options: ParserOptions = ParserOptions.Default): GQLResult { @Suppress("DEPRECATION") return if (options.useAntlr) { @@ -154,6 +150,10 @@ fun String.parseAsGQLValue(options: ParserOptions = ParserOptions.Default): GQLR } } +fun String.toGQLValue(options: ParserOptions = ParserOptions.Default): GQLValue { + return parseAsGQLValue(options).getOrThrow() +} + fun String.parseAsGQLType(options: ParserOptions = ParserOptions.Default): GQLResult { @Suppress("DEPRECATION") return if (options.useAntlr) { @@ -163,12 +163,20 @@ fun String.parseAsGQLType(options: ParserOptions = ParserOptions.Default): GQLRe } } +fun String.toGQLType(options: ParserOptions = ParserOptions.Default): GQLType { + return parseAsGQLType(options).getOrThrow() +} + internal fun String.parseAsGQLNullability(options: ParserOptions = ParserOptions.Default): GQLResult { @Suppress("DEPRECATION") - check (!options.useAntlr) + check(!options.useAntlr) return parseInternal(null, options) { parseNullability() ?: error("No nullability") } } +fun String.toGQLNullability(options: ParserOptions = ParserOptions.Default): GQLNullability { + return parseAsGQLNullability(options).getOrThrow() +} + fun String.parseAsGQLSelections(options: ParserOptions = ParserOptions.Default): GQLResult> { @Suppress("DEPRECATION") return if (options.useAntlr) { @@ -178,10 +186,22 @@ fun String.parseAsGQLSelections(options: ParserOptions = ParserOptions.Default): } } +fun String.toGQLSelections(options: ParserOptions = ParserOptions.Default): List { + return parseAsGQLSelections(options).getOrThrow() +} + fun Path.parseAsGQLDocument(options: ParserOptions = ParserOptions.Default): GQLResult { return HOST_FILESYSTEM.source(this).buffer().parseAsGQLDocument(filePath = toString(), options = options) } +fun Path.toGQLDocument(options: ParserOptions = ParserOptions.Default, allowJson: Boolean = false): GQLDocument { + return if (allowJson && name.endsWith(".json")) { + toIntrospectionSchema().toGQLDocument() + } else { + parseAsGQLDocument(options).getOrThrow() + } +} + /** * Parses the source to a [GQLDocument], validating the syntax but not the contents of the document. * diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gql.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gql.kt index f8dfcebc93b..1f658c3908a 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gql.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gql.kt @@ -46,6 +46,7 @@ sealed interface GQLNode { fun copyWithNewChildrenInternal(container: NodeContainer): GQLNode } +@ApolloExperimental sealed interface TransformResult { object Delete : TransformResult object Continue : TransformResult @@ -57,10 +58,12 @@ sealed interface TransformResult { class Replace(val newNode: GQLNode) : TransformResult } +@ApolloExperimental fun interface NodeTransformer { fun transform(node: GQLNode): TransformResult } +@ApolloExperimental fun GQLNode.transform(transformer: NodeTransformer): GQLNode? { return when (val result = transformer.transform(this)) { is TransformResult.Delete -> null @@ -117,7 +120,7 @@ interface GQLHasDirectives { sealed interface GQLDefinition : GQLNode sealed interface GQLExecutableDefinition : GQLDefinition -sealed interface GQLTypeSystemExtension : GQLNode +sealed interface GQLTypeSystemExtension : GQLDefinition sealed interface GQLTypeExtension : GQLTypeSystemExtension, GQLNamed sealed class GQLSelection : GQLNode @@ -132,8 +135,6 @@ class GQLDocument( val definitions: List, override val sourceLocation: SourceLocation?, ) : GQLNode { - constructor(definitions: List, filePath: String?) : this(definitions, SourceLocation.forPath(filePath)) - override val children = definitions override fun writeInternal(writer: SDLWriter) { diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldirective.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldirective.kt index 723feed4ea5..9676f62b61c 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldirective.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldirective.kt @@ -16,6 +16,19 @@ fun List.findDeprecationReason() = firstOrNull { it.name == "depre ?: "No longer supported" } +fun List.findSpecifiedBy() = firstOrNull { it.name == "specifiedBy" } + ?.let { directive -> + directive.arguments + .firstOrNull { it.name == "url" } + ?.value + ?.let { value -> + if (value !is GQLStringValue) { + throw ConversionException("url must be a string", directive.sourceLocation) + } + value.value + } + } + @ApolloInternal fun List.findOptInFeature(schema: Schema): String? = filter { schema.originalDirectiveName(it.name) == Schema.REQUIRES_OPT_IN } .map { diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldocument.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldocument.kt index 2eaa12a4f23..4c301b47763 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldocument.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldocument.kt @@ -2,9 +2,11 @@ package com.apollographql.apollo3.ast import com.apollographql.apollo3.annotations.ApolloDeprecatedSince import com.apollographql.apollo3.annotations.ApolloExperimental +import com.apollographql.apollo3.ast.internal.ExtensionsMerger import com.apollographql.apollo3.ast.internal.apollo_v0_1_definitionsStr import com.apollographql.apollo3.ast.internal.apollo_v0_2_definitionsStr import com.apollographql.apollo3.ast.internal.builtinsDefinitionsStr +import com.apollographql.apollo3.ast.internal.ensureSchemaDefinition import com.apollographql.apollo3.ast.internal.linkDefinitionsStr import okio.Buffer @@ -22,7 +24,26 @@ fun GQLDocument.withBuiltinDefinitions(): GQLDocument { return withDefinitions(builtinDefinitions()) } -@Deprecated("Use GQLDocument.toSDL() to write a GQLDocument without the scalar directives") +/** + * Returns a "full schema" document. Full schema documents are for use by clients and other tools that need + * to know what features are supported by a given server. They include builtin directives and merge all type + * extensions + */ +@ApolloExperimental +fun GQLDocument.toFullSchemaGQLDocument(): GQLDocument { + return ensureSchemaDefinition() + .withDefinitions(builtinDefinitions()) + .mergeExtensions() +} + +fun GQLDocument.toSchema(): Schema = validateAsSchema().getOrThrow() + +@ApolloExperimental +fun GQLDocument.mergeExtensions(): GQLDocument { + return GQLDocument(ExtensionsMerger(definitions).merge().getOrThrow(), sourceLocation = null) +} + +@Deprecated("Use GQLDocument.toSDL() to write a GQLDocument") @ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0) fun GQLDocument.withoutBuiltinDefinitions(): GQLDocument { return withoutDefinitions(builtinDefinitions()) @@ -123,6 +144,7 @@ private fun GQLDocument.withDefinitions(definitions: List): GQLDo ) } + /** * Outputs a schema document to SDL. For executable documents, use toUtf8() * diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqlnode.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqlnode.kt index 1461a010fdf..22d961611c4 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqlnode.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqlnode.kt @@ -2,11 +2,13 @@ @file:JvmName("GqlnodeKt") package com.apollographql.apollo3.ast +import com.apollographql.apollo3.annotations.ApolloExperimental import okio.Buffer import okio.BufferedSink import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName +@ApolloExperimental fun GQLNode.toUtf8(sink: BufferedSink, indent: String = " ") { val writer = SDLWriter(sink, indent) writer.write(this) diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/TypeExtensionsMergeScope.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ExtensionsMerger.kt similarity index 56% rename from libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/TypeExtensionsMergeScope.kt rename to libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ExtensionsMerger.kt index 7389daa01a9..f172005c7cd 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/TypeExtensionsMergeScope.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ExtensionsMerger.kt @@ -2,6 +2,7 @@ package com.apollographql.apollo3.ast.internal import com.apollographql.apollo3.ast.GQLDefinition import com.apollographql.apollo3.ast.GQLDirective +import com.apollographql.apollo3.ast.GQLDirectiveDefinition import com.apollographql.apollo3.ast.GQLEnumTypeDefinition import com.apollographql.apollo3.ast.GQLEnumTypeExtension import com.apollographql.apollo3.ast.GQLEnumValueDefinition @@ -13,6 +14,7 @@ import com.apollographql.apollo3.ast.GQLNamed import com.apollographql.apollo3.ast.GQLNode import com.apollographql.apollo3.ast.GQLObjectTypeDefinition import com.apollographql.apollo3.ast.GQLObjectTypeExtension +import com.apollographql.apollo3.ast.GQLResult import com.apollographql.apollo3.ast.GQLScalarTypeDefinition import com.apollographql.apollo3.ast.GQLScalarTypeExtension import com.apollographql.apollo3.ast.GQLSchemaDefinition @@ -22,23 +24,48 @@ import com.apollographql.apollo3.ast.GQLUnionTypeDefinition import com.apollographql.apollo3.ast.GQLUnionTypeExtension import com.apollographql.apollo3.ast.Issue import com.apollographql.apollo3.ast.SourceLocation +import kotlin.reflect.KClass +/** + * Because directive order is important, the order of the definitions is also important here + * + * Typically, extensions come after type definitions + */ +internal class ExtensionsMerger(private val definitions: List) { + val issues = mutableListOf() + val directiveDefinitions: Map + + init { + directiveDefinitions = definitions.filterIsInstance().associateBy { it.name } + } + + fun merge(): GQLResult> { + val newDefinitions = mutableListOf() + definitions.forEach { definition -> -internal fun ValidationScope.mergeExtensions(definitions: List, extensions: List): List { - return extensions.fold(definitions) { acc, extension -> - when (extension) { - is GQLSchemaExtension -> mergeSchemaExtension(acc, schemaExtension = extension) - is GQLScalarTypeExtension -> merge(acc, extension, "scalar") { merge(it, extension) } - is GQLInterfaceTypeExtension -> merge(acc, extension, "interface") { merge(it, extension) } - is GQLObjectTypeExtension -> merge(acc, extension, "object") { merge(it, extension) } - is GQLInputObjectTypeExtension -> merge(acc, extension, "input") { merge(it, extension) } - is GQLEnumTypeExtension -> merge(acc, extension, "enum") { merge(it, extension) } - is GQLUnionTypeExtension -> merge(acc, extension, "union") { merge(it, extension) } + when (definition) { + is GQLTypeSystemExtension -> { + when(definition) { + is GQLSchemaExtension -> mergeTyped(GQLSchemaDefinition::class, newDefinitions, definition, "schema") { mergeSchema(it, definition) } + is GQLScalarTypeExtension -> mergeNamed(GQLScalarTypeDefinition::class, newDefinitions, definition, "scalar") { mergeScalar(it, definition) } + is GQLInterfaceTypeExtension -> mergeNamed(GQLInterfaceTypeDefinition::class, newDefinitions, definition, "interface") { mergeInterface(it, definition) } + is GQLObjectTypeExtension -> mergeNamed(GQLObjectTypeDefinition::class, newDefinitions, definition, "object") { mergeObject(it, definition) } + is GQLInputObjectTypeExtension -> mergeNamed(GQLInputObjectTypeDefinition::class, newDefinitions, definition, "input") { mergeInputObject(it, definition) } + is GQLEnumTypeExtension -> mergeNamed(GQLEnumTypeDefinition::class, newDefinitions, definition, "enum") { mergeEnum(it, definition) } + is GQLUnionTypeExtension -> mergeNamed(GQLUnionTypeDefinition::class, newDefinitions, definition, "union") { mergeUnion(it, definition) } + } + } + else -> { + newDefinitions.add(definition) + } + } } + + return GQLResult(newDefinitions, issues) } } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeUnion( unionTypeDefinition: GQLUnionTypeDefinition, extension: GQLUnionTypeExtension, ): GQLUnionTypeDefinition = with(unionTypeDefinition) { @@ -48,7 +75,7 @@ private fun ValidationScope.merge( ) } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeEnum( enumTypeDefinition: GQLEnumTypeDefinition, extension: GQLEnumTypeExtension, ): GQLEnumTypeDefinition = with(enumTypeDefinition) { @@ -62,7 +89,7 @@ private fun ValidationScope.merge( * Technically not allowed by the current spec, but useful to be able to add directives on enum values. * See https://github.com/graphql/graphql-spec/issues/952 */ -private fun ValidationScope.mergeEnumValues( +private fun ExtensionsMerger.mergeEnumValues( existingList: List, otherList: List, ): List { @@ -80,7 +107,7 @@ private fun ValidationScope.mergeEnumValues( return result } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeInputObject( inputObjectTypeDefinition: GQLInputObjectTypeDefinition, extension: GQLInputObjectTypeExtension, ): GQLInputObjectTypeDefinition = with(inputObjectTypeDefinition) { @@ -90,7 +117,7 @@ private fun ValidationScope.merge( ) } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeObject( objectTypeDefinition: GQLObjectTypeDefinition, extension: GQLObjectTypeExtension, ): GQLObjectTypeDefinition = with(objectTypeDefinition) { @@ -101,7 +128,7 @@ private fun ValidationScope.merge( ) } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeInterface( interfaceTypeDefinition: GQLInterfaceTypeDefinition, extension: GQLInterfaceTypeExtension, ): GQLInterfaceTypeDefinition = with(interfaceTypeDefinition) { @@ -112,27 +139,22 @@ private fun ValidationScope.merge( ) } -private fun ValidationScope.mergeSchemaExtension( - definitions: List, - schemaExtension: GQLSchemaExtension, -): List = with(definitions) { - var found = false - val newDefinitions = mutableListOf() - forEach { - if (it is GQLSchemaDefinition) { - newDefinitions.add(merge(it, schemaExtension)) - found = true - } else { - newDefinitions.add(it) - } - } - if (!found) { - issues.add(Issue.ValidationError("Cannot apply schema extension on non existing schema definition", schemaExtension.sourceLocation)) +private inline fun ExtensionsMerger.mergeTyped( + @Suppress("UNUSED_PARAMETER") clazz: KClass, + newDefinitions: MutableList, + extension: E, + extra: String, + merge: (T) -> T, +) where T: GQLDefinition, E: GQLTypeSystemExtension{ + val index = newDefinitions.indexOfFirst { it is T } + if (index == -1) { + issues.add(Issue.ValidationError("Cannot find $extra definition to apply extension", extension.sourceLocation)) + } else { + newDefinitions.set(index, merge(newDefinitions[index]as T)) } - return newDefinitions } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeScalar( scalarTypeDefinition: GQLScalarTypeDefinition, scalarTypeExtension: GQLScalarTypeExtension, ): GQLScalarTypeDefinition = with(scalarTypeDefinition) { @@ -141,32 +163,32 @@ private fun ValidationScope.merge( ) } -private inline fun ValidationScope.merge( - definitions: List, +private inline fun ExtensionsMerger.mergeNamed( + @Suppress("UNUSED_PARAMETER") clazz: KClass, + definitions: MutableList, extension: E, extra: String, merge: (T) -> T, -): List where T : GQLDefinition, T : GQLNamed, E : GQLNamed, E : GQLNode = with(definitions) { - var found = false - val newDefinitions = mutableListOf() - forEach { - if (it is T && it.name == extension.name) { - if (found) { - issues.add(Issue.ValidationError("Multiple '${extension.name}' types found while merging extensions. This is a bug, check validation code", extension.sourceLocation)) - } - newDefinitions.add(merge(it)) - found = true - } else { - newDefinitions.add(it) - } +) where T : GQLDefinition, T : GQLNamed, E : GQLNamed, E : GQLTypeSystemExtension { + val indexedValues = definitions.withIndex().filter { (_, value) -> + value is T && value.name == extension.name } - if (!found) { - issues.add(Issue.ValidationError("Cannot find $extra type `${extension.name}` to apply extension", extension.sourceLocation)) + + when (indexedValues.size) { + 0 -> { + issues.add(Issue.ValidationError("Cannot find $extra type `${extension.name}` to apply extension", extension.sourceLocation)) + } + 1 -> { + val indexedValue = indexedValues.first() + definitions.set(indexedValue.index, merge(indexedValue.value as T)) + } + else -> { + issues.add(Issue.ValidationError("Multiple '${extension.name}' types found while merging extensions.", extension.sourceLocation)) + } } - return newDefinitions } -private fun ValidationScope.merge( +private fun ExtensionsMerger.mergeSchema( schemaDefinition: GQLSchemaDefinition, extension: GQLSchemaExtension, ): GQLSchemaDefinition = with(schemaDefinition) { @@ -176,28 +198,36 @@ private fun ValidationScope.merge( ) } -private fun ValidationScope.mergeDirectives( +/** + * Merge both list of directive + */ +private fun ExtensionsMerger.mergeDirectives( list: List, other: List, ): List { val result = mutableListOf() result.addAll(list) - for (directive in other) { - if (result.any { it.name == directive.name }) { - val definition = directiveDefinitions[directive.name] ?: error("Cannot find directive definition '${directive.name}") - if (!definition.repeatable) { - issues.add(Issue.ValidationError("Cannot add non-repeatable directive `${directive.name}`", directive.sourceLocation)) + for (directiveToAdd in other) { + if (result.any { it.name == directiveToAdd.name }) { + // duplicated directive, get the definition to see if we can + val definition = directiveDefinitions[directiveToAdd.name] + + if (definition == null) { + issues.add(Issue.ValidationError("Cannot find directive definition `${directiveToAdd.name}`", directiveToAdd.sourceLocation)) + continue + } else if (!definition.repeatable) { + issues.add(Issue.ValidationError("Cannot add non-repeatable directive `${directiveToAdd.name}`", directiveToAdd.sourceLocation)) continue } } - result.add(directive) + result.add(directiveToAdd) } return result } -private inline fun IssuesScope.mergeUniquesOrThrow( +private inline fun ExtensionsMerger.mergeUniquesOrThrow( list: List, others: List, ): List where T : GQLNamed, T : GQLNode = with(list) { @@ -208,7 +238,7 @@ private inline fun IssuesScope.mergeUniquesOrThrow( } } -private fun IssuesScope.mergeUniqueInterfacesOrThrow( +private fun ExtensionsMerger.mergeUniqueInterfacesOrThrow( list: List, others: List, sourceLocation: SourceLocation?, @@ -221,7 +251,7 @@ private fun IssuesScope.mergeUniqueInterfacesOrThrow( } -private inline fun IssuesScope.mergeUniquesOrThrow( +private inline fun ExtensionsMerger.mergeUniquesOrThrow( list: List, others: List, name: (T) -> String, diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/SchemaValidationScope.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/SchemaValidationScope.kt index 88efdb73368..25d027d9969 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/SchemaValidationScope.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/SchemaValidationScope.kt @@ -5,6 +5,7 @@ import com.apollographql.apollo3.ast.ConflictResolution import com.apollographql.apollo3.ast.GQLDefinition import com.apollographql.apollo3.ast.GQLDirective import com.apollographql.apollo3.ast.GQLDirectiveDefinition +import com.apollographql.apollo3.ast.GQLDocument import com.apollographql.apollo3.ast.GQLEnumTypeDefinition import com.apollographql.apollo3.ast.GQLField import com.apollographql.apollo3.ast.GQLInputObjectTypeDefinition @@ -32,6 +33,7 @@ import com.apollographql.apollo3.ast.builtinDefinitions import com.apollographql.apollo3.ast.canHaveKeyFields import com.apollographql.apollo3.ast.combineDefinitions import com.apollographql.apollo3.ast.containsError +import com.apollographql.apollo3.ast.introspection.defaultSchemaDefinition import com.apollographql.apollo3.ast.linkDefinitions import com.apollographql.apollo3.ast.parseAsGQLSelections import com.apollographql.apollo3.ast.pretty @@ -139,8 +141,7 @@ internal fun validateSchema(definitions: List, requiresApolloDefi * I'm not 100% clear on the order of validations, here I'm merging the extensions first thing */ val dedupedDefinitions = listOfNotNull(schemaDefinition) + directiveDefinitions.values + typeDefinitions.values - val dedupedScope = DefaultValidationScope(typeDefinitions, directiveDefinitions, issues) - val mergedDefinitions = dedupedScope.mergeExtensions(dedupedDefinitions, typeSystemExtensions) + val mergedDefinitions = ExtensionsMerger(dedupedDefinitions + typeSystemExtensions).merge().getOrThrow() val foreignNames = foreignSchemas.flatMap { it.newNames.entries @@ -540,3 +541,14 @@ private val GQLTypeDefinition.fields is GQLInterfaceTypeDefinition -> fields else -> emptyList() } + +internal fun GQLDocument.ensureSchemaDefinition(): GQLDocument { + if (definitions.any { it is GQLSchemaDefinition }) { + return this + } + + val typeDefinitions = definitions.filterIsInstance() + .associateBy { it.name } + return this.copy(listOf(defaultSchemaDefinition(typeDefinitions)) + definitions) +} + diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ValidationCommon.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ValidationCommon.kt index ef454002e70..8bc36f3d295 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ValidationCommon.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/ValidationCommon.kt @@ -37,7 +37,7 @@ import com.apollographql.apollo3.ast.isVariableUsageAllowed import com.apollographql.apollo3.ast.parseAsGQLSelections import com.apollographql.apollo3.ast.pretty -interface IssuesScope { +internal interface IssuesScope { val issues: MutableList } diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/definitions.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/definitions.kt index ced6f1d7a9e..7f3f7047930 100644 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/definitions.kt +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/internal/definitions.kt @@ -6,8 +6,6 @@ package com.apollographql.apollo3.ast.internal * - builtins.graphqls: the official built-in defintions such as [built-in scalars](https://spec.graphql.org/draft/#sec-Scalars.Built-in-Scalars), [built-in directives](https://spec.graphql.org/draft/#sec-Type-System.Directives.Built-in-Directives) or [introspection definitions](https://spec.graphql.org/draft/#sec-Schema-Introspection.Schema-Introspection-Schema). * - link.graphqls: the [core schemas](https://specs.apollo.dev/link/v1.0/) definitions. * - apollo-${version}.graphqls: the client directives supported by Apollo Kotlin. Changes are versioned at https://github.com/apollographql/specs. Changing them requires a new version and a PR. - * - * TODO: move to apollo-compiler instead? */ internal val apollo_v0_1_definitionsStr = """ @@ -144,15 +142,14 @@ internal val apollo_v0_2_definitionsStr = """ | INPUT_OBJECT """.trimIndent() +// Built in scalar and introspection types from the Draft: +// - https://spec.graphql.org/draft/#sec-Scalars +// - https://spec.graphql.org/draft/#sec-Schema-Introspection.Schema-Introspection-Schema +// In theory the user needs to provide the builtin definitions because we cannot know in advance what +// version of the spec they are using neither if they have extended any of the introspection types. +// This file is a fallback to make a best-effort guess in case the user didn't provide these definitions, at the +// risk of potentially validating invalid queries. internal val builtinsDefinitionsStr = """ - # Built in scalar and introspection types from: - # - https://spec.graphql.org/June2018/#sec-Scalars - # - https://github.com/graphql/graphql-spec/blob/afc0a35d271ba9502c3c68aeda6e6c6fbc223774/spec/Section%204%20--%20Introspection.md - # In theory the user needs to provide the builtin definitions because we cannot know in advance what - # version of the spec they are using neither if they have extended any of the introspection types. - # This file is a fallback to make a best-effort guess in case the user didn't provide these definitions, at the - # risk of potentially validating invalid queries. - ""${'"'} The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. ""${'"'} @@ -178,7 +175,6 @@ internal val builtinsDefinitionsStr = """ ""${'"'} scalar ID - type __Schema { description: String types: [__Type!]! @@ -187,7 +183,7 @@ internal val builtinsDefinitionsStr = """ subscriptionType: __Type directives: [__Directive!]! } - + type __Type { kind: __TypeKind! name: String @@ -207,7 +203,7 @@ internal val builtinsDefinitionsStr = """ # may be non-null for custom SCALAR, otherwise null. specifiedByURL: String } - + enum __TypeKind { SCALAR OBJECT @@ -218,7 +214,7 @@ internal val builtinsDefinitionsStr = """ LIST NON_NULL } - + type __Field { name: String! description: String @@ -227,7 +223,7 @@ internal val builtinsDefinitionsStr = """ isDeprecated: Boolean! deprecationReason: String } - + type __InputValue { name: String! description: String @@ -236,14 +232,14 @@ internal val builtinsDefinitionsStr = """ isDeprecated: Boolean! deprecationReason: String } - + type __EnumValue { name: String! description: String isDeprecated: Boolean! deprecationReason: String } - + type __Directive { name: String! description: String @@ -251,7 +247,7 @@ internal val builtinsDefinitionsStr = """ args(includeDeprecated: Boolean = false): [__InputValue!]! isRepeatable: Boolean! } - + enum __DirectiveLocation { QUERY MUTATION diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt deleted file mode 100644 index 9ed2ca6fb8a..00000000000 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.kt +++ /dev/null @@ -1,256 +0,0 @@ -@file:JvmMultifileClass -@file:JvmName("IntrospectionSchemaKt") - -package com.apollographql.apollo3.ast.introspection - -import com.apollographql.apollo3.annotations.ApolloExperimental -import com.apollographql.apollo3.ast.HOST_FILESYSTEM -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import okio.Buffer -import okio.BufferedSource -import okio.ByteString.Companion.decodeHex -import okio.Path -import okio.buffer -import kotlin.jvm.JvmMultifileClass -import kotlin.jvm.JvmName - - -@Serializable -private class IntrospectionSchemaEnvelope( - val data: IntrospectionSchema?, - val __schema: IntrospectionSchema.Schema?, -) - -@Serializable -class IntrospectionSchema( - val __schema: Schema, -) { - @Serializable - class Schema( - val queryType: QueryType, - val mutationType: MutationType?, - val subscriptionType: SubscriptionType?, - val types: List, - val directives: List = emptyList(), - ) { - @Serializable - class QueryType(val name: String) - - @Serializable - class MutationType(val name: String) - - @Serializable - class SubscriptionType(val name: String) - - @Serializable - sealed class Type { - abstract val name: String - abstract val description: String? - - @SerialName("SCALAR") - @Serializable - class Scalar( - override val name: String, - override val description: String?, - ) : Type() - - @SerialName("OBJECT") - @Serializable - class Object( - override val name: String, - override val description: String?, - val fields: List?, - val interfaces: List?, - ) : Type() - - @SerialName("INTERFACE") - @Serializable - class Interface( - override val name: String, - override val description: String?, - val fields: List?, - val interfaces: List?, - val possibleTypes: List?, - ) : Type() - - @SerialName("UNION") - @Serializable - class Union( - override val name: String, - override val description: String?, - val fields: List?, - val possibleTypes: List?, - ) : Type() - - @SerialName("ENUM") - @Serializable - class Enum( - override val name: String, - override val description: String?, - val enumValues: List, - ) : Type() { - @Serializable - class Value( - val name: String, - val description: String?, - val isDeprecated: Boolean = false, - val deprecationReason: String?, - ) - } - - @SerialName("INPUT_OBJECT") - @Serializable - class InputObject( - override val name: String, - override val description: String?, - val inputFields: List, - ) : Type() - } - - @Serializable - class InputField( - val name: String, - val description: String?, - val isDeprecated: Boolean = false, - val deprecationReason: String?, - val type: TypeRef, - val defaultValue: String?, - ) - - @Serializable - class Field( - val name: String, - val description: String?, - val isDeprecated: Boolean = false, - val deprecationReason: String?, - val type: TypeRef, - val args: List = emptyList(), - ) - - @Serializable - class Argument( - val name: String, - val description: String?, - val isDeprecated: Boolean = false, - val deprecationReason: String?, - val type: TypeRef, - val defaultValue: String?, - ) - - /** - * An introspection TypeRef - */ - @Serializable - class TypeRef( - val kind: Kind, - val name: String? = "", - val ofType: TypeRef? = null, - ) - - /** - * An introspection directive - */ - @Serializable - class Directive( - val name: String, - val description: String?, - val locations: List = emptyList(), - val args: List, - val isRepeatable: Boolean = false, - ) { - enum class DirectiveLocation { - QUERY, - MUTATION, - SUBSCRIPTION, - FIELD, - FRAGMENT_DEFINITION, - FRAGMENT_SPREAD, - INLINE_FRAGMENT, - VARIABLE_DEFINITION, - SCHEMA, - SCALAR, - OBJECT, - FIELD_DEFINITION, - ARGUMENT_DEFINITION, - INTERFACE, - UNION, - ENUM, - ENUM_VALUE, - INPUT_OBJECT, - INPUT_FIELD_DEFINITION, - } - } - - enum class Kind { - ENUM, INTERFACE, OBJECT, INPUT_OBJECT, SCALAR, NON_NULL, LIST, UNION - } - } -} - -internal val json: Json by lazy { - Json { - ignoreUnknownKeys = true - classDiscriminator = "kind" - @OptIn(ExperimentalSerializationApi::class) - explicitNulls = false - encodeDefaults = true - } -} - -fun BufferedSource.toIntrospectionSchema(origin: String = ""): IntrospectionSchema { - val bom = "EFBBBF".decodeHex() - - if (rangeEquals(0, bom)) { - skip(bom.size.toLong()) - } - - return try { - val introspectionSchemaEnvelope = json.decodeFromString(IntrospectionSchemaEnvelope.serializer(), this.readUtf8()) - introspectionSchemaEnvelope.data ?: introspectionSchemaEnvelope.__schema?.let { schema -> - IntrospectionSchema(IntrospectionSchema.Schema( - queryType = schema.queryType, - mutationType = schema.mutationType, - subscriptionType = schema.subscriptionType, - types = schema.types, - // Old introspection json (pre `April2016`) may not have the `locations` field, in which case the list will be empty, which is invalid. Exclude those directives. - // Validation doesn't validate the unknown directives (yet). A future version may want to fail here and enforce proper validation. - directives = schema.directives.filter { directive -> directive.locations.isNotEmpty() } - )) - } - ?: throw IllegalArgumentException("Invalid introspection schema: $origin") - } catch (e: Exception) { - throw RuntimeException("Cannot decode introspection $origin", e) - } -} - -fun String.toIntrospectionSchema() = Buffer().writeUtf8(this).toIntrospectionSchema() - -fun IntrospectionSchema.normalize(): IntrospectionSchema { - return IntrospectionSchema( - __schema = __schema.normalize() - ) -} - -fun IntrospectionSchema.Schema.normalize(): IntrospectionSchema.Schema { - return IntrospectionSchema.Schema( - queryType = queryType, - mutationType = mutationType, - subscriptionType = subscriptionType, - types = types.sortedBy { it.name }, - directives = directives.sortedBy { it.name } - ) -} - -fun IntrospectionSchema.toJson(): String { - return json.encodeToString(IntrospectionSchema.serializer(), this) -} - -@ApolloExperimental -fun Path.toIntrospectionSchema(): IntrospectionSchema { - return HOST_FILESYSTEM - .source(this) - .buffer().toIntrospectionSchema("from `$this`") -} \ No newline at end of file diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_reader.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_reader.kt new file mode 100644 index 00000000000..10b3266feb9 --- /dev/null +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_reader.kt @@ -0,0 +1,558 @@ +@file:JvmMultifileClass +@file:JvmName("Introspection") + +@file:Suppress("PropertyName") + +package com.apollographql.apollo3.ast.introspection + +import com.apollographql.apollo3.annotations.ApolloExperimental +import com.apollographql.apollo3.annotations.ApolloInternal +import com.apollographql.apollo3.ast.ConversionException +import com.apollographql.apollo3.ast.GQLArgument +import com.apollographql.apollo3.ast.GQLDirective +import com.apollographql.apollo3.ast.GQLDirectiveDefinition +import com.apollographql.apollo3.ast.GQLDirectiveLocation +import com.apollographql.apollo3.ast.GQLDocument +import com.apollographql.apollo3.ast.GQLEnumTypeDefinition +import com.apollographql.apollo3.ast.GQLEnumValueDefinition +import com.apollographql.apollo3.ast.GQLFieldDefinition +import com.apollographql.apollo3.ast.GQLInputObjectTypeDefinition +import com.apollographql.apollo3.ast.GQLInputValueDefinition +import com.apollographql.apollo3.ast.GQLInterfaceTypeDefinition +import com.apollographql.apollo3.ast.GQLListType +import com.apollographql.apollo3.ast.GQLNamedType +import com.apollographql.apollo3.ast.GQLNonNullType +import com.apollographql.apollo3.ast.GQLObjectTypeDefinition +import com.apollographql.apollo3.ast.GQLOperationTypeDefinition +import com.apollographql.apollo3.ast.GQLScalarTypeDefinition +import com.apollographql.apollo3.ast.GQLSchemaDefinition +import com.apollographql.apollo3.ast.GQLStringValue +import com.apollographql.apollo3.ast.GQLType +import com.apollographql.apollo3.ast.GQLUnionTypeDefinition +import com.apollographql.apollo3.ast.GQLValue +import com.apollographql.apollo3.ast.HOST_FILESYSTEM +import com.apollographql.apollo3.ast.SourceLocation +import com.apollographql.apollo3.ast.parseAsGQLValue +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.Json +import okio.Buffer +import okio.BufferedSource +import okio.ByteString.Companion.decodeHex +import okio.Path +import okio.buffer +import kotlin.jvm.JvmMultifileClass +import kotlin.jvm.JvmName + +/** + * Because there are different versions of GraphQL in the wild and because users may use + * different introspection queries it tries to be as lenient as possible. + * + * Probable user error (incomplete introspection query): + * - missing description defaults to null + * - missing directive argument definitions default to empty + * - missing directives default to empty + * - missing defaultValue defaults to null + * - missing isDeprecated (for fields) defaults to false + * - missing mutationType/subscriptionType + * + * Old schemas + * - missing isRepeatable defaults to false + * - missing isDeprecated (for input value) defaults to false + * + * Very old schemas + * - missing directive locations skip the directive definition + * + */ + +interface IntrospectionSchema + +@ApolloExperimental +fun BufferedSource.toIntrospectionSchema(filePath: String? = null): IntrospectionSchema { + val bom = "EFBBBF".decodeHex() + + if (rangeEquals(0, bom)) { + skip(bom.size.toLong()) + } + + val string = this.readUtf8() + val envelope: REnvelope = json.decodeFromString(string) + val __schema = envelope.__schema ?: envelope.data?.__schema + if (__schema == null) { + throw ConversionException("Invalid introspection schema '${string.substring(0, 50)}': expected input should look like '{ \"__schema\": { \"types\": ...'") + } + return IntrospectionSchemaImpl(__schema, filePath) +} + +fun String.toIntrospectionSchema(): IntrospectionSchema = Buffer().writeUtf8(this).toIntrospectionSchema() + +@ApolloExperimental +fun Path.toIntrospectionSchema(): IntrospectionSchema { + return HOST_FILESYSTEM + .source(this) + .buffer() + .toIntrospectionSchema(toString()) +} + +/** + * Parses the [RSchema] into a [GQLDocument] + */ +fun IntrospectionSchema.toGQLDocument(): GQLDocument { + this as IntrospectionSchemaImpl + return GQLDocumentBuilder(this).toGQLDocument(filePath) +} + +private class IntrospectionSchemaImpl(val __schema: RSchema, val filePath: String?) : IntrospectionSchema + +private val json = Json { + // be robust to errors: [] keys + ignoreUnknownKeys = true +} + +@Serializable +private class REnvelope( + val data: RData? = null, + @Suppress("PropertyName") + val __schema: RSchema? = null, +) + +@Serializable +private class RData( + @Suppress("PropertyName") + val __schema: RSchema, +) + +@Serializable +private class RSchema( + val description: Optional = Optional.absent(), + val types: List, + val queryType: RTypeRoot, + val mutationType: Optional = Optional.absent(), + val subscriptionType: Optional = Optional.absent(), + val directives: Optional> = Optional.absent(), +) + +@Serializable +private class RTypeRoot(val name: String) + +@Serializable +private class RTypeFull( + val kind: RTypeKind, + val name: String, + val description: Optional = Optional.absent(), + val fields: List? = null, + val interfaces: List? = null, + val possibleTypes: List? = null, + val enumValues: List? = null, + val inputFields: List? = null, + val specifiedByURL: String? = null, +) { + override fun toString(): String { + return "$kind - $name" + } +} + +@Serializable +private class RTypeRef( + val kind: RTypeKind, + val name: String? = null, + val ofType: RTypeRef? = null, +) + +private enum class RTypeKind { + SCALAR, + OBJECT, + INTERFACE, + UNION, + ENUM, + INPUT_OBJECT, + LIST, + NON_NULL, +} + +@Serializable +private class RField( + val name: String, + val description: Optional = Optional.absent(), + val args: Optional> = Optional.absent(), + val type: RTypeRef, + val isDeprecated: Optional = Optional.absent(), + val deprecationReason: Optional = Optional.absent(), +) + +@Serializable +private class RInputValue( + val name: String, + val description: Optional = Optional.absent(), + val type: RTypeRef, + val defaultValue: Optional = Optional.absent(), + val isDeprecated: Boolean = false, + val deprecationReason: String? = null, +) + +@Serializable +private class REnumValue( + val name: String, + val description: Optional = Optional.absent(), + val isDeprecated: Optional = Optional.absent(), + val deprecationReason: Optional = Optional.absent(), +) + +@Serializable +private class RDirective( + val name: String, + val description: Optional = Optional.absent(), + val locations: Optional> = Optional.absent(), + val args: Optional> = Optional.absent(), + val isRepeatable: Boolean = false, +) + +@Serializable(with = OptionalSerializer::class) +private sealed class Optional { + fun getOrNull() = (this as? Present)?.value + fun getOrThrow(): V { + if (this !is Present) { + throw Exception("Optional has no value") + } + return this.value + } + + fun mapValue(block: (V) -> R): Optional { + return when (this) { + is Absent -> Absent + is Present -> Optional.present(block(this.value)) + } + } + + data class Present(val value: V) : Optional() + object Absent : Optional() + + companion object { + fun absent(): Optional = Absent + + fun present(value: V): Optional = Present(value) + } +} + + +private class OptionalSerializer(private val dataSerializer: KSerializer) : KSerializer> { + override val descriptor: SerialDescriptor = dataSerializer.descriptor + override fun serialize(encoder: Encoder, value: Optional) { + dataSerializer.serialize(encoder, value.getOrThrow()) + } + + override fun deserialize(decoder: Decoder): Optional { + return Optional.present(dataSerializer.deserialize(decoder)) + } +} + +private class GQLDocumentBuilder(private val introspectionSchema: IntrospectionSchemaImpl) { + fun toGQLDocument(filePath: String?): GQLDocument { + return with(introspectionSchema.__schema) { + val directives = if (directives is Optional.Absent) { + println("Apollo: __schema.directives is missing, double check your introspection query") + emptyList() + } else { + directives.getOrThrow() + } + + GQLDocument( + definitions = types.map { + when (it.kind) { + RTypeKind.SCALAR -> it.toGQLScalarTypeDefinition() + RTypeKind.OBJECT -> it.toGQLObjectTypeDefinition() + RTypeKind.INTERFACE -> it.toGQLInterfaceTypeDefinition() + RTypeKind.UNION -> it.toGQLUnionTypeDefinition() + RTypeKind.ENUM -> it.toGQLEnumTypeDefinition() + RTypeKind.INPUT_OBJECT -> it.toGQLInputObjectTypeDefinition() + else -> throw ConversionException("Unknown type kind: ${it.kind}") + } + } + + directives.mapNotNull { it.toGQLDirectiveDefinition() } + + schemaDefinition(), + sourceLocation = SourceLocation.forPath(filePath) + ) + } + } + + private fun Optional.unwrapDescription(context: String): String? { + return if (this is Optional.Absent) { + println("Apollo: $context is missing 'description', double check your introspection query") + null + } else { + getOrThrow() + } + } + + private fun RTypeFull.toGQLObjectTypeDefinition(): GQLObjectTypeDefinition { + return GQLObjectTypeDefinition( + description = description.unwrapDescription(name), + name = name, + directives = emptyList(), + fields = fields?.map { it.toGQLFieldDefinition() } ?: throw ConversionException("Object '$name' does not define any field"), + implementsInterfaces = findInterfacesImplementedBy(name) + ) + } + + private fun findInterfacesImplementedBy(name: String): List { + return introspectionSchema.__schema + .types + .filter { + it.kind == RTypeKind.INTERFACE + } + .filter { + it.possibleTypes?.map { it.name }?.contains(name) == true + } + .map { + it.name + } + } + + private fun RTypeFull.toGQLEnumTypeDefinition(): GQLEnumTypeDefinition { + return GQLEnumTypeDefinition( + description = description.unwrapDescription(name), + name = name, + enumValues = enumValues?.map { it.toGQLEnumValueDefinition() } + ?: throw ConversionException("Enum '$name' does not define any value"), + directives = emptyList() + ) + } + + private fun REnumValue.toGQLEnumValueDefinition(): GQLEnumValueDefinition { + return GQLEnumValueDefinition( + description = description.unwrapDescription(name), + name = name, + directives = makeDirectives(deprecationReason.unwrapDeprecationReason(name)) + ) + } + + private fun Optional.unwrapDeprecationReason(name: String): String? { + return if (this is Optional.Absent) { + println("Apollo: $name is missing 'deprecationReason', double check your introspection query") + null + } else { + getOrThrow() + } + } + + private fun RTypeFull.toGQLInterfaceTypeDefinition(): GQLInterfaceTypeDefinition { + return GQLInterfaceTypeDefinition( + name = name, + description = description.unwrapDescription(name), + fields = fields?.map { it.toGQLFieldDefinition() } ?: throw ConversionException("interface '$name' did not define any field"), + implementsInterfaces = interfaces?.mapNotNull { it.name } ?: emptyList(), + directives = emptyList() + ) + } + + private fun RField.toGQLFieldDefinition(): GQLFieldDefinition { + val args = if (args is Optional.Absent) { + println("Apollo: $name.args is missing, double check your introspection query") + emptyList() + } else { + args.getOrThrow() + } + + return GQLFieldDefinition( + name = name, + description = description.unwrapDescription(name), + arguments = args.map { it.toGQLInputValueDefinition() }, + directives = makeDirectives(deprecationReason.unwrapDeprecationReason(name)), + type = type.toGQLType() + ) + } + + private fun String?.toGQLValue(): GQLValue? { + if (this == null) { + // no default value + return null + } + try { + return Buffer().writeUtf8(this).parseAsGQLValue().getOrThrow() + } catch (e: Exception) { + throw ConversionException("cannot convert $this to a GQLValue") + } + } + + /** + * This assumes the case where `deprecationReason == null && isDeprecated` is not valid + * which is unclear from reading the spec as the below seems allowed: + * + * ``` + * type Query { + * foo: Int @deprecated(reason: null) + * } + * ``` + * + * If there are legit use cases for `@deprecated(reason: null)` we should update this function + */ + fun makeDirectives(deprecationReason: String?): List { + if (deprecationReason == null) { + return emptyList() + } + return listOf( + GQLDirective( + name = "deprecated", + arguments = listOf( + GQLArgument(name = "reason", value = GQLStringValue(value = deprecationReason)) + ) + ) + ) + } + + private fun RTypeFull.toGQLUnionTypeDefinition(): GQLUnionTypeDefinition { + return GQLUnionTypeDefinition( + name = name, + description = description.unwrapDescription(name), + memberTypes = possibleTypes?.map { it.toGQLNamedType() } ?: throw ConversionException("Union '$name' must have members"), + directives = emptyList(), + ) + } + + private fun RTypeRef.toGQLNamedType(): GQLNamedType { + return toGQLType() as? GQLNamedType ?: throw ConversionException("expected a NamedType") + } + + private fun RTypeRef.toGQLType(): GQLType { + return when (this.kind) { + RTypeKind.NON_NULL -> GQLNonNullType( + type = ofType?.toGQLType() ?: throw ConversionException("ofType must not be null for non null types") + ) + + RTypeKind.LIST -> GQLListType( + type = ofType?.toGQLType() ?: throw ConversionException("ofType must not be null for list types") + ) + + else -> GQLNamedType( + name = name!! + ) + } + } + + private fun RSchema.schemaDefinition(): GQLSchemaDefinition { + val rootOperationTypeDefinitions = mutableListOf() + rootOperationTypeDefinitions.add( + GQLOperationTypeDefinition( + operationType = "query", + namedType = queryType.name + ) + ) + val mutationType = if (mutationType is Optional.Absent) { + println("Apollo: schema.mutationType is missing, double check your introspection query") + null + } else { + mutationType.getOrThrow() + } + if (mutationType != null) { + rootOperationTypeDefinitions.add( + GQLOperationTypeDefinition( + operationType = "mutation", + namedType = mutationType.name + ) + ) + } + + val subscriptionType = if (subscriptionType is Optional.Absent) { + println("Apollo: schema.mutationType is missing, double check your introspection query") + null + } else { + subscriptionType.getOrThrow() + } + if (subscriptionType != null) { + rootOperationTypeDefinitions.add( + GQLOperationTypeDefinition( + operationType = "subscription", + namedType = subscriptionType.name + ) + ) + } + + return GQLSchemaDefinition( + description = description.unwrapDescription("schema"), + directives = emptyList(), + rootOperationTypeDefinitions = rootOperationTypeDefinitions + ) + } + + private fun RTypeFull.toGQLInputObjectTypeDefinition(): GQLInputObjectTypeDefinition { + return GQLInputObjectTypeDefinition( + description = description.unwrapDescription(name), + name = name, + inputFields = inputFields?.map { it.toGQLInputValueDefinition() } + ?: throw ConversionException("Input Object '$name' does not define any input field"), + directives = emptyList() + ) + } + + private fun RInputValue.toGQLInputValueDefinition(): GQLInputValueDefinition { + val defaultValue = if (defaultValue is Optional.Absent) { + println("Apollo: '$name.defaultValue' is missing, check your introspection query") + null + } else { + defaultValue.getOrNull() + } + return GQLInputValueDefinition( + name = name, + description = description.unwrapDescription(name), + directives = makeDirectives(deprecationReason), + defaultValue = defaultValue.toGQLValue(), + type = type.toGQLType(), + ) + } + + private fun RTypeFull.toGQLScalarTypeDefinition(): GQLScalarTypeDefinition { + return GQLScalarTypeDefinition( + description = description.unwrapDescription(name), + name = name, + directives = emptyList() + ) + } + + private fun RDirective.toGQLDirectiveDefinition(): GQLDirectiveDefinition? { + if (locations is Optional.Absent) { + println("Apollo: '$name.locations' is missing, check your introspection query") + return null + } + val locations = locations.getOrThrow() + val args = if (args is Optional.Absent) { + println("Apollo: '$name.args' is missing, check your introspection query") + emptyList() + } else { + args.getOrThrow() + } + return GQLDirectiveDefinition( + description = description.unwrapDescription(name), + name = name, + arguments = args.map { it.toGQLInputValueDefinition() }, + locations = locations.map { GQLDirectiveLocation.valueOf(it) }, + repeatable = isRepeatable, + ) + } +} + +@ApolloInternal +fun IntrospectionSchema.normalize(): IntrospectionSchema { + this as IntrospectionSchemaImpl + // This does not sort the fields/arguments for some reason + return with(__schema) { + IntrospectionSchemaImpl( + RSchema( + queryType = queryType, + mutationType = mutationType, + subscriptionType = subscriptionType, + types = types.sortedBy { it.name }, + directives = directives.mapValue { it.sortedBy { it.name } }, + description = description + ), + null + ) + } +} + + + + diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.kt deleted file mode 100644 index a6915f32bb6..00000000000 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.kt +++ /dev/null @@ -1,345 +0,0 @@ -@file:JvmMultifileClass -@file:JvmName("Introspection_to_schemaKt") -package com.apollographql.apollo3.ast.introspection - -import com.apollographql.apollo3.annotations.ApolloExperimental -import com.apollographql.apollo3.ast.ConversionException -import com.apollographql.apollo3.ast.GQLArgument -import com.apollographql.apollo3.ast.GQLBooleanValue -import com.apollographql.apollo3.ast.GQLDirective -import com.apollographql.apollo3.ast.GQLDirectiveDefinition -import com.apollographql.apollo3.ast.GQLDirectiveLocation -import com.apollographql.apollo3.ast.GQLDocument -import com.apollographql.apollo3.ast.GQLEnumTypeDefinition -import com.apollographql.apollo3.ast.GQLEnumValueDefinition -import com.apollographql.apollo3.ast.GQLFieldDefinition -import com.apollographql.apollo3.ast.GQLFloatValue -import com.apollographql.apollo3.ast.GQLInputObjectTypeDefinition -import com.apollographql.apollo3.ast.GQLInputValueDefinition -import com.apollographql.apollo3.ast.GQLIntValue -import com.apollographql.apollo3.ast.GQLInterfaceTypeDefinition -import com.apollographql.apollo3.ast.GQLListType -import com.apollographql.apollo3.ast.GQLListValue -import com.apollographql.apollo3.ast.GQLNamedType -import com.apollographql.apollo3.ast.GQLNonNullType -import com.apollographql.apollo3.ast.GQLObjectField -import com.apollographql.apollo3.ast.GQLObjectTypeDefinition -import com.apollographql.apollo3.ast.GQLObjectValue -import com.apollographql.apollo3.ast.GQLOperationTypeDefinition -import com.apollographql.apollo3.ast.GQLScalarTypeDefinition -import com.apollographql.apollo3.ast.GQLSchemaDefinition -import com.apollographql.apollo3.ast.GQLStringValue -import com.apollographql.apollo3.ast.GQLType -import com.apollographql.apollo3.ast.GQLUnionTypeDefinition -import com.apollographql.apollo3.ast.GQLValue -import com.apollographql.apollo3.ast.Schema -import com.apollographql.apollo3.ast.SourceLocation -import com.apollographql.apollo3.ast.parseAsGQLDocument -import com.apollographql.apollo3.ast.parseAsGQLValue -import com.apollographql.apollo3.ast.validateAsSchema -import okio.Buffer -import okio.Path -import kotlin.jvm.JvmMultifileClass -import kotlin.jvm.JvmName - - -private class GQLDocumentBuilder(private val introspectionSchema: IntrospectionSchema, filePath: String?) { - private val sourceLocation = SourceLocation.forPath(filePath) - - fun toGQLDocument(): GQLDocument { - return with(introspectionSchema.__schema) { - GQLDocument( - definitions = types.map { - when (it) { - is IntrospectionSchema.Schema.Type.Union -> it.toGQLUnionTypeDefinition() - is IntrospectionSchema.Schema.Type.Interface -> it.toGQLInterfaceTypeDefinition() - is IntrospectionSchema.Schema.Type.Enum -> it.toGQLEnumTypeDefinition() - is IntrospectionSchema.Schema.Type.Object -> it.toGQLObjectTypeDefinition() - is IntrospectionSchema.Schema.Type.InputObject -> it.toGQLInputObjectTypeDefinition() - is IntrospectionSchema.Schema.Type.Scalar -> it.toGQLScalarTypeDefinition() - } - } - + directives.map { it.toGQLDirectiveDefinition() } - + schemaDefinition(), - filePath = sourceLocation.filePath - ) - } - } - - private fun IntrospectionSchema.Schema.Type.Object.toGQLObjectTypeDefinition(): GQLObjectTypeDefinition { - return GQLObjectTypeDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - directives = emptyList(), - fields = fields?.map { it.toGQLFieldDefinition() } ?: throw ConversionException("Object '$name' did not define any field"), - implementsInterfaces = findInterfacesImplementedBy(name) - ) - } - - private fun findInterfacesImplementedBy(name: String): List { - return introspectionSchema.__schema.types.filterIsInstance() - .filter { - it.possibleTypes?.map { it.name }?.contains(name) == true - } - .map { - it.name - } - } - - private fun IntrospectionSchema.Schema.Type.Enum.toGQLEnumTypeDefinition(): GQLEnumTypeDefinition { - return GQLEnumTypeDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - enumValues = enumValues.map { it.toGQLEnumValueDefinition() }, - directives = emptyList() - ) - } - - private fun IntrospectionSchema.Schema.Type.Enum.Value.toGQLEnumValueDefinition(): GQLEnumValueDefinition { - return GQLEnumValueDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - directives = makeDirectives(deprecationReason) - ) - } - - private fun IntrospectionSchema.Schema.Type.Interface.toGQLInterfaceTypeDefinition(): GQLInterfaceTypeDefinition { - return GQLInterfaceTypeDefinition( - sourceLocation = sourceLocation, - name = name, - description = description, - fields = fields?.map { it.toGQLFieldDefinition() } ?: throw ConversionException("interface '$name' did not define any field"), - implementsInterfaces = interfaces?.mapNotNull { it.name } ?: emptyList(), - directives = emptyList() - ) - } - - private fun IntrospectionSchema.Schema.Field.toGQLFieldDefinition(): GQLFieldDefinition { - return GQLFieldDefinition( - sourceLocation = sourceLocation, - name = name, - description = description, - arguments = this.args.map { it.toGQLInputValueDefinition() }, - directives = makeDirectives(deprecationReason), - type = type.toGQLType() - ) - } - - private fun IntrospectionSchema.Schema.Argument.toGQLInputValueDefinition(): GQLInputValueDefinition { - return GQLInputValueDefinition( - sourceLocation = sourceLocation, - name = name, - description = description, - directives = makeDirectives(deprecationReason), - defaultValue = defaultValue.toGQLValue(), - type = type.toGQLType(), - ) - } - - private fun Any?.toGQLValue(): GQLValue? { - if (this == null) { - // no default value - return null - } - try { - if (this is String) { - return Buffer().writeUtf8(this).parseAsGQLValue().getOrThrow() - } - } catch (e: Exception) { - println("Wrongly encoded default value: $this: ${e.message}") - } - - // All the below should theoretically not happen because the spec says defaultValue should be - // a GQLValue encoded as a string - return when { - this is String -> GQLStringValue(value = this) - this is Int -> GQLIntValue(value = this) - this is Long -> GQLIntValue(value = this.toInt()) - this is Double -> GQLFloatValue(value = this) - this is Boolean -> GQLBooleanValue(value = this) - this is Map<*, *> -> GQLObjectValue(fields = this.map { - GQLObjectField(name = it.key as String, value = it.value.toGQLValue()!!) - }) - - this is List<*> -> GQLListValue(values = map { it.toGQLValue()!! }) - else -> throw ConversionException("cannot convert $this to a GQLValue") - } - } - - fun makeDirectives(deprecationReason: String?): List { - if (deprecationReason == null) { - return emptyList() - } - return listOf( - GQLDirective( - name = "deprecated", - arguments = listOf( - GQLArgument(name = "reason", value = GQLStringValue(value = deprecationReason)) - ) - ) - ) - } - - private fun IntrospectionSchema.Schema.Type.Union.toGQLUnionTypeDefinition(): GQLUnionTypeDefinition { - return GQLUnionTypeDefinition( - sourceLocation = sourceLocation, - name = name, - description = "", - memberTypes = possibleTypes?.map { it.toGQLNamedType() } ?: throw ConversionException("Union '$name' must have members"), - directives = emptyList(), - ) - } - - private fun IntrospectionSchema.Schema.TypeRef.toGQLNamedType(): GQLNamedType { - return toGQLType() as? GQLNamedType ?: throw ConversionException("expected a NamedType") - } - - private fun IntrospectionSchema.Schema.TypeRef.toGQLType(): GQLType { - return when (this.kind) { - IntrospectionSchema.Schema.Kind.NON_NULL -> GQLNonNullType( - type = ofType?.toGQLType() ?: throw ConversionException("ofType must not be null for non null types") - ) - - IntrospectionSchema.Schema.Kind.LIST -> GQLListType( - type = ofType?.toGQLType() ?: throw ConversionException("ofType must not be null for list types") - ) - - else -> GQLNamedType( - name = name!! - ) - } - } - - private fun IntrospectionSchema.Schema.schemaDefinition(): GQLSchemaDefinition { - val rootOperationTypeDefinitions = mutableListOf() - rootOperationTypeDefinitions.add( - GQLOperationTypeDefinition( - sourceLocation = sourceLocation, - operationType = "query", - namedType = queryType.name - ) - ) - if (mutationType != null) { - rootOperationTypeDefinitions.add( - GQLOperationTypeDefinition( - sourceLocation = sourceLocation, - operationType = "mutation", - namedType = mutationType.name - ) - ) - } - if (subscriptionType != null) { - rootOperationTypeDefinitions.add( - GQLOperationTypeDefinition( - sourceLocation = sourceLocation, - operationType = "subscription", - namedType = subscriptionType.name - ) - ) - } - - return GQLSchemaDefinition( - sourceLocation = sourceLocation, - description = "", - directives = emptyList(), - rootOperationTypeDefinitions = rootOperationTypeDefinitions - ) - } - - private fun IntrospectionSchema.Schema.Type.InputObject.toGQLInputObjectTypeDefinition(): GQLInputObjectTypeDefinition { - return GQLInputObjectTypeDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - inputFields = inputFields.map { it.toGQLInputValueDefinition() }, - directives = emptyList() - ) - } - - private fun IntrospectionSchema.Schema.InputField.toGQLInputValueDefinition(): GQLInputValueDefinition { - return GQLInputValueDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - directives = makeDirectives(deprecationReason), - type = type.toGQLType(), - defaultValue = defaultValue.toGQLValue() - ) - } - - private fun IntrospectionSchema.Schema.Type.Scalar.toGQLScalarTypeDefinition(): GQLScalarTypeDefinition { - return GQLScalarTypeDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - directives = emptyList() - ) - } - - private fun IntrospectionSchema.Schema.Directive.toGQLDirectiveDefinition(): GQLDirectiveDefinition { - return GQLDirectiveDefinition( - sourceLocation = sourceLocation, - description = description, - name = name, - arguments = args.map { it.toGQLInputValueDefinition() }, - locations = locations.map { it.toGQLDirectiveLocations() }, - repeatable = isRepeatable, - ) - } - - private fun IntrospectionSchema.Schema.Directive.DirectiveLocation.toGQLDirectiveLocations() = when (this) { - IntrospectionSchema.Schema.Directive.DirectiveLocation.QUERY -> GQLDirectiveLocation.QUERY - IntrospectionSchema.Schema.Directive.DirectiveLocation.MUTATION -> GQLDirectiveLocation.MUTATION - IntrospectionSchema.Schema.Directive.DirectiveLocation.SUBSCRIPTION -> GQLDirectiveLocation.SUBSCRIPTION - IntrospectionSchema.Schema.Directive.DirectiveLocation.FIELD -> GQLDirectiveLocation.FIELD - IntrospectionSchema.Schema.Directive.DirectiveLocation.FRAGMENT_DEFINITION -> GQLDirectiveLocation.FRAGMENT_DEFINITION - IntrospectionSchema.Schema.Directive.DirectiveLocation.FRAGMENT_SPREAD -> GQLDirectiveLocation.FRAGMENT_SPREAD - IntrospectionSchema.Schema.Directive.DirectiveLocation.INLINE_FRAGMENT -> GQLDirectiveLocation.INLINE_FRAGMENT - IntrospectionSchema.Schema.Directive.DirectiveLocation.VARIABLE_DEFINITION -> GQLDirectiveLocation.VARIABLE_DEFINITION - IntrospectionSchema.Schema.Directive.DirectiveLocation.SCHEMA -> GQLDirectiveLocation.SCHEMA - IntrospectionSchema.Schema.Directive.DirectiveLocation.SCALAR -> GQLDirectiveLocation.SCALAR - IntrospectionSchema.Schema.Directive.DirectiveLocation.OBJECT -> GQLDirectiveLocation.OBJECT - IntrospectionSchema.Schema.Directive.DirectiveLocation.FIELD_DEFINITION -> GQLDirectiveLocation.FIELD_DEFINITION - IntrospectionSchema.Schema.Directive.DirectiveLocation.ARGUMENT_DEFINITION -> GQLDirectiveLocation.ARGUMENT_DEFINITION - IntrospectionSchema.Schema.Directive.DirectiveLocation.INTERFACE -> GQLDirectiveLocation.INTERFACE - IntrospectionSchema.Schema.Directive.DirectiveLocation.UNION -> GQLDirectiveLocation.UNION - IntrospectionSchema.Schema.Directive.DirectiveLocation.ENUM -> GQLDirectiveLocation.ENUM - IntrospectionSchema.Schema.Directive.DirectiveLocation.ENUM_VALUE -> GQLDirectiveLocation.ENUM_VALUE - IntrospectionSchema.Schema.Directive.DirectiveLocation.INPUT_OBJECT -> GQLDirectiveLocation.INPUT_OBJECT - IntrospectionSchema.Schema.Directive.DirectiveLocation.INPUT_FIELD_DEFINITION -> GQLDirectiveLocation.INPUT_FIELD_DEFINITION - } -} - -/** - * Parses the [IntrospectionSchema] into a [GQLDocument] - */ -@ApolloExperimental -fun IntrospectionSchema.toGQLDocument(filePath: String? = null): GQLDocument = GQLDocumentBuilder(this, filePath) - .toGQLDocument() - -/** - * Transforms the [IntrospectionSchema] into a [Schema] that contains builtin definitions - * - * In the process, the builtin definitions are removed and added again. - */ -@ApolloExperimental -fun IntrospectionSchema.toSchema(): Schema = toGQLDocument().validateAsSchema().getOrThrow() - - -/** - * Transforms the given path to a [GQLDocument] without doing validation - */ -@ApolloExperimental -fun Path.toSchemaGQLDocument(): GQLDocument { - return if (name.endsWith("json")) { - toIntrospectionSchema().toGQLDocument(filePath = name) - } else { - parseAsGQLDocument().getOrThrow() - } -} - -@ApolloExperimental -fun Path.toSchema(): Schema = toSchemaGQLDocument().validateAsSchema().getOrThrow() \ No newline at end of file diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_writer.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_writer.kt new file mode 100644 index 00000000000..ce797962b5b --- /dev/null +++ b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_writer.kt @@ -0,0 +1,417 @@ +@file:JvmMultifileClass +@file:JvmName("Introspection") +@file:Suppress("PropertyName") + +package com.apollographql.apollo3.ast.introspection + +import com.apollographql.apollo3.ast.ConversionException +import com.apollographql.apollo3.ast.GQLDirectiveDefinition +import com.apollographql.apollo3.ast.GQLDocument +import com.apollographql.apollo3.ast.GQLEnumTypeDefinition +import com.apollographql.apollo3.ast.GQLEnumValueDefinition +import com.apollographql.apollo3.ast.GQLFieldDefinition +import com.apollographql.apollo3.ast.GQLInputObjectTypeDefinition +import com.apollographql.apollo3.ast.GQLInputValueDefinition +import com.apollographql.apollo3.ast.GQLInterfaceTypeDefinition +import com.apollographql.apollo3.ast.GQLListType +import com.apollographql.apollo3.ast.GQLNamedType +import com.apollographql.apollo3.ast.GQLNonNullType +import com.apollographql.apollo3.ast.GQLObjectTypeDefinition +import com.apollographql.apollo3.ast.GQLOperationTypeDefinition +import com.apollographql.apollo3.ast.GQLScalarTypeDefinition +import com.apollographql.apollo3.ast.GQLSchemaDefinition +import com.apollographql.apollo3.ast.GQLType +import com.apollographql.apollo3.ast.GQLTypeDefinition +import com.apollographql.apollo3.ast.GQLUnionTypeDefinition +import com.apollographql.apollo3.ast.findDeprecationReason +import com.apollographql.apollo3.ast.findSpecifiedBy +import com.apollographql.apollo3.ast.toUtf8 +import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlin.jvm.JvmMultifileClass +import kotlin.jvm.JvmName + +/** + * The Json Model matching the `__Schema` [GraphQL type](https://spec.graphql.org/draft/#sec-The-__Schema-Type) + * + * It matches the draft version of the spec. Some fields did not exist in earlier versions + * like `__InputValue.isDeprecated` for an example. + * + * The models match with the spec types except for Type that is used recursively, and therefore + * we have [WTypeFull], [WTypeRef] and [WTypeRoot] + */ +@Serializable +internal class WSchema( + internal val description: String?, + internal val types: List, + internal val queryType: WTypeRoot, + internal val mutationType: WTypeRoot?, + internal val subscriptionType: WTypeRoot?, + internal val directives: List, +) + +@Serializable +internal class WTypeRoot(val name: String) + +@Serializable +internal class WTypeFull( + val kind: WTypeKind, + // name is nullable in the spec but when queried from __schema.types, it should never be + val name: String, + val description: String?, + val fields: List?, + val interfaces: List?, + val possibleTypes: List?, + val enumValues: List?, + val inputFields: List?, + val specifiedByURL: String?, +) + +@Serializable +internal class WTypeRef( + val kind: WTypeKind, + val name: String?, + val ofType: WTypeRef?, +) + +internal enum class WTypeKind { + SCALAR, + OBJECT, + INTERFACE, + UNION, + ENUM, + INPUT_OBJECT, + LIST, + NON_NULL, +} + +@Serializable +internal class WField( + val name: String, + val description: String?, + val args: List, + val type: WTypeRef, + val isDeprecated: Boolean, + val deprecationReason: String?, +) + +@Serializable +internal class WInputValue( + val name: String, + val description: String?, + val type: WTypeRef, + val defaultValue: String?, + val isDeprecated: Boolean, + val deprecationReason: String?, +) + +@Serializable +internal class WEnumValue( + val name: String, + val description: String?, + val isDeprecated: Boolean, + val deprecationReason: String?, +) + +@Serializable +internal class WDirective( + val name: String, + val description: String?, + val locations: List, + val args: List, + val isRepeatable: Boolean, +) + +@Serializable +internal class WData(val __schema: WSchema) + +internal class IntrospectionSchemaBuilder(document: GQLDocument) { + private val typeDefinitions: Map + private val directiveDefinitions: List + private val schemaDefinition: GQLSchemaDefinition + + init { + val types = mutableMapOf() + val directives = mutableListOf() + var schema: GQLSchemaDefinition? = null + + document.definitions.forEach { + when (it) { + is GQLTypeDefinition -> { + types.put(it.name, it) + } + + is GQLDirectiveDefinition -> { + directives.add(it) + } + + is GQLSchemaDefinition -> { + schema = it + } + + else -> { + throw ConversionException("Unsupported definition ${it::class.simpleName} apply type extensions before converting to introspection") + } + } + } + + schemaDefinition = schema ?: defaultSchemaDefinition(types) + typeDefinitions = types + directiveDefinitions = directives + } + + fun toIntrospectionSchema(): ApolloIntrospectionSchema { + return ApolloIntrospectionSchema( + WSchema( + queryType = WTypeRoot(schemaDefinition.queryType()), + mutationType = schemaDefinition.mutationType()?.let { WTypeRoot(it) }, + subscriptionType = schemaDefinition.subscriptionType()?.let { WTypeRoot(it) }, + types = typeDefinitions.values.map { + when (it) { + is GQLObjectTypeDefinition -> it.toIntrospectionType() + is GQLInputObjectTypeDefinition -> it.toIntrospectionType() + is GQLInterfaceTypeDefinition -> it.toIntrospectionType() + is GQLScalarTypeDefinition -> it.toIntrospectionType() + is GQLEnumTypeDefinition -> it.toIntrospectionType() + is GQLUnionTypeDefinition -> it.toIntrospectionType() + } + }, + directives = directiveDefinitions.map { it.toIntrospectionDirective() }, + description = schemaDefinition.description + ) + ) + } + + private fun GQLObjectTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.OBJECT, + name = name, + description = description, + fields = fields.map { it.toIntrospectionField() }, + interfaces = implementsInterfaces.map { WTypeRef(kind = WTypeKind.INTERFACE, name = it, ofType = null) }, + possibleTypes = null, + enumValues = null, + inputFields = null, + specifiedByURL = null + ) + } + + private fun GQLFieldDefinition.toIntrospectionField(): WField { + val deprecationReason = directives.findDeprecationReason() + return WField( + name = name, + description = description, + isDeprecated = deprecationReason != null, + deprecationReason = deprecationReason, + type = type.toIntrospectionType(), + args = arguments.map { it.toIntrospectionInputValue() } + ) + } + + private fun GQLInputValueDefinition.toIntrospectionInputValue(): WInputValue { + val deprecationReason = directives.findDeprecationReason() + + return WInputValue( + name = name, + description = description, + isDeprecated = deprecationReason != null, + deprecationReason = deprecationReason, + type = type.toIntrospectionType(), + defaultValue = defaultValue?.toUtf8(indent = "") + ) + } + + private fun GQLInputObjectTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.INPUT_OBJECT, + name = name, + description = description, + inputFields = inputFields.map { it.toIntrospectionInputValue() }, + fields = null, + interfaces = null, + possibleTypes = null, + enumValues = null, + specifiedByURL = null + ) + } + + + private fun GQLInterfaceTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.INTERFACE, + name = name, + description = description, + fields = fields.map { it.toIntrospectionField() }, + possibleTypes = typeDefinitions.values + .filter { typeDefinition -> + typeDefinition is GQLObjectTypeDefinition && typeDefinition.implementsInterfaces.contains(name) + } + .map { typeDefinition -> + WTypeRef( + kind = WTypeKind.OBJECT, + name = typeDefinition.name, + ofType = null + ) + }, + interfaces = implementsInterfaces.map { interfaceName -> + WTypeRef( + kind = WTypeKind.INTERFACE, + name = interfaceName, + ofType = null + ) + }, + enumValues = null, + inputFields = null, + specifiedByURL = null + ) + } + + private fun GQLEnumTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.ENUM, + name = name, + description = description, + enumValues = enumValues.map { it.toIntrospectionEnumValue() }, + fields = null, + interfaces = null, + inputFields = null, + possibleTypes = null, + specifiedByURL = null + ) + } + + private fun GQLEnumValueDefinition.toIntrospectionEnumValue(): WEnumValue { + val deprecationReason = directives.findDeprecationReason() + return WEnumValue( + name = name, + description = description, + isDeprecated = deprecationReason != null, + deprecationReason = deprecationReason + ) + } + + private fun GQLScalarTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.SCALAR, + name = this.name, + description = this.description, + fields = null, + interfaces = null, + possibleTypes = null, + enumValues = null, + inputFields = null, + specifiedByURL = this.directives.findSpecifiedBy() + ) + } + + private fun GQLUnionTypeDefinition.toIntrospectionType(): WTypeFull { + return WTypeFull( + kind = WTypeKind.UNION, + name = name, + description = description, + fields = null, + possibleTypes = memberTypes.map { it.toIntrospectionType() }, + interfaces = null, + enumValues = null, + inputFields = null, + specifiedByURL = null + ) + } + + private fun GQLDirectiveDefinition.toIntrospectionDirective() = WDirective( + name = name, + description = description, + locations = locations.map { it.name }, + args = arguments.map { it.toIntrospectionInputValue() }, + isRepeatable = repeatable, + ) + + private fun GQLType.toIntrospectionType(): WTypeRef { + return when (this) { + is GQLNonNullType -> { + WTypeRef( + kind = WTypeKind.NON_NULL, + name = null, + ofType = type.toIntrospectionType() + ) + } + + is GQLListType -> { + WTypeRef( + kind = WTypeKind.LIST, + name = null, + ofType = type.toIntrospectionType()) + } + + is GQLNamedType -> { + WTypeRef( + kind = typeDefinitions.get(name)?.schemaKind() ?: throw ConversionException("Cannot find type $name"), + name = name, + ofType = null + ) + } + } + } +} + +internal fun defaultSchemaDefinition(typeDefinitions: Map): GQLSchemaDefinition { + return GQLSchemaDefinition( + description = null, + directives = emptyList(), + rootOperationTypeDefinitions = listOfNotNull( + typeDefinitions.getOperationTypeDefinition("Query", "query"), + typeDefinitions.getOperationTypeDefinition("Mutation", "mutation"), + typeDefinitions.getOperationTypeDefinition("Subscription", "subscription") + ) + ) +} + +internal fun GQLSchemaDefinition.queryType(): String { + return rootTypeFor("query") ?: throw ConversionException("Schema does not define a 'query' type") +} + +internal fun GQLSchemaDefinition.mutationType(): String? { + return rootTypeFor("mutation") +} + +internal fun GQLSchemaDefinition.subscriptionType(): String? { + return rootTypeFor("subscription") +} + +internal fun GQLSchemaDefinition.rootTypeFor(operationType: String): String? { + return rootOperationTypeDefinitions.firstOrNull { + it.operationType == operationType + }?.namedType +} + + +private fun Map.getOperationTypeDefinition( + namedType: String, + operationType: String, +): GQLOperationTypeDefinition? { + if (!containsKey(namedType)) { + return null + } + return GQLOperationTypeDefinition( + operationType = operationType, + namedType = namedType + ) +} + +private fun GQLTypeDefinition.schemaKind() = when (this) { + is GQLEnumTypeDefinition -> WTypeKind.ENUM + is GQLUnionTypeDefinition -> WTypeKind.UNION + is GQLObjectTypeDefinition -> WTypeKind.OBJECT + is GQLInputObjectTypeDefinition -> WTypeKind.INPUT_OBJECT + is GQLScalarTypeDefinition -> WTypeKind.SCALAR + is GQLInterfaceTypeDefinition -> WTypeKind.INTERFACE +} + +class ApolloIntrospectionSchema internal constructor(@Suppress("PropertyName") internal val __schema: WSchema) + +fun ApolloIntrospectionSchema.toJson(): String { + return Json.encodeToString(WData(__schema)) +} + +fun GQLDocument.toIntrospectionSchema(): ApolloIntrospectionSchema = IntrospectionSchemaBuilder(this).toIntrospectionSchema() diff --git a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/schema_to_introspection.kt b/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/schema_to_introspection.kt deleted file mode 100644 index aecb55a5e40..00000000000 --- a/libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/schema_to_introspection.kt +++ /dev/null @@ -1,250 +0,0 @@ -package com.apollographql.apollo3.ast.introspection - -import com.apollographql.apollo3.ast.GQLBooleanValue -import com.apollographql.apollo3.ast.GQLDirectiveDefinition -import com.apollographql.apollo3.ast.GQLDirectiveLocation -import com.apollographql.apollo3.ast.GQLEnumTypeDefinition -import com.apollographql.apollo3.ast.GQLEnumValue -import com.apollographql.apollo3.ast.GQLEnumValueDefinition -import com.apollographql.apollo3.ast.GQLFieldDefinition -import com.apollographql.apollo3.ast.GQLFloatValue -import com.apollographql.apollo3.ast.GQLInputObjectTypeDefinition -import com.apollographql.apollo3.ast.GQLInputValueDefinition -import com.apollographql.apollo3.ast.GQLIntValue -import com.apollographql.apollo3.ast.GQLInterfaceTypeDefinition -import com.apollographql.apollo3.ast.GQLListType -import com.apollographql.apollo3.ast.GQLListValue -import com.apollographql.apollo3.ast.GQLNamedType -import com.apollographql.apollo3.ast.GQLNonNullType -import com.apollographql.apollo3.ast.GQLNullValue -import com.apollographql.apollo3.ast.GQLObjectTypeDefinition -import com.apollographql.apollo3.ast.GQLObjectValue -import com.apollographql.apollo3.ast.GQLScalarTypeDefinition -import com.apollographql.apollo3.ast.GQLStringValue -import com.apollographql.apollo3.ast.GQLType -import com.apollographql.apollo3.ast.GQLTypeDefinition -import com.apollographql.apollo3.ast.GQLUnionTypeDefinition -import com.apollographql.apollo3.ast.GQLValue -import com.apollographql.apollo3.ast.GQLVariableValue -import com.apollographql.apollo3.ast.Schema -import com.apollographql.apollo3.ast.findDeprecationReason -import com.apollographql.apollo3.ast.toUtf8 - -private class IntrospectionSchemaBuilder(private val schema: Schema) { - private val typeDefinitions = schema.typeDefinitions - - fun toIntrospectionSchema(): IntrospectionSchema { - return IntrospectionSchema( - __schema = IntrospectionSchema.Schema( - queryType = IntrospectionSchema.Schema.QueryType(schema.queryTypeDefinition.name), - mutationType = schema.mutationTypeDefinition?.name?.let { IntrospectionSchema.Schema.MutationType(it) }, - subscriptionType = schema.subscriptionTypeDefinition?.name?.let { IntrospectionSchema.Schema.SubscriptionType(it) }, - types = typeDefinitions.values.map { - when (it) { - is GQLObjectTypeDefinition -> it.toSchemaType() - is GQLInputObjectTypeDefinition -> it.toSchemaType() - is GQLInterfaceTypeDefinition -> it.toSchemaType() - is GQLScalarTypeDefinition -> it.toSchemaType() - is GQLEnumTypeDefinition -> it.toSchemaType() - is GQLUnionTypeDefinition -> it.toSchemaType() - } - }, - directives = schema.directiveDefinitions.values.map { it.toSchemaDirective() }, - ) - ) - } - - private fun GQLObjectTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Object { - return IntrospectionSchema.Schema.Type.Object( - name = name, - description = description, - fields = fields.map { it.toSchemaField() }, - interfaces = implementsInterfaces.map { IntrospectionSchema.Schema.Type.Interface(name = it, description = null, fields = null, possibleTypes = null, interfaces = null) }.ifEmpty { null }, - ) - } - - private fun GQLFieldDefinition.toSchemaField(): IntrospectionSchema.Schema.Field { - val deprecationReason = directives.findDeprecationReason() - return IntrospectionSchema.Schema.Field( - name = name, - description = description, - isDeprecated = deprecationReason != null, - deprecationReason = deprecationReason, - type = type.toSchemaType(schema), - args = arguments.map { it.toSchemaArgument() } - ) - } - - private fun GQLInputValueDefinition.toSchemaArgument(): IntrospectionSchema.Schema.Argument { - val deprecationReason = directives.findDeprecationReason() - - return IntrospectionSchema.Schema.Argument( - name = name, - description = description, - isDeprecated = deprecationReason != null, - deprecationReason = deprecationReason, - type = type.toSchemaType(schema), - defaultValue = defaultValue?.toUtf8(indent = "") - ) - } - - private fun GQLInputObjectTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.InputObject { - return IntrospectionSchema.Schema.Type.InputObject( - name = name, - description = description, - inputFields = inputFields.map { it.toSchemaInputField() } - ) - } - - private fun GQLInputValueDefinition.toSchemaInputField(): IntrospectionSchema.Schema.InputField { - val deprecationReason = directives.findDeprecationReason() - return IntrospectionSchema.Schema.InputField( - name = name, - description = description, - isDeprecated = deprecationReason != null, - deprecationReason = deprecationReason, - type = type.toSchemaType(schema), - defaultValue = defaultValue?.toUtf8(indent = ""), - ) - } - - private fun GQLInterfaceTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Interface { - return IntrospectionSchema.Schema.Type.Interface( - name = name, - description = description, - fields = fields.map { it.toSchemaField() }, - possibleTypes = typeDefinitions.values - .filter { typeDefinition -> - typeDefinition is GQLObjectTypeDefinition && typeDefinition.implementsInterfaces.contains(name) - } - .map { typeDefinition -> - IntrospectionSchema.Schema.TypeRef( - kind = IntrospectionSchema.Schema.Kind.OBJECT, - name = typeDefinition.name - ) - }, - interfaces = implementsInterfaces.map { interfaceName -> - IntrospectionSchema.Schema.TypeRef( - kind = IntrospectionSchema.Schema.Kind.INTERFACE, - name = interfaceName - ) - } - ) - } - - private fun GQLEnumTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Enum { - return IntrospectionSchema.Schema.Type.Enum( - name = name, - description = description, - enumValues = enumValues.map { it.toSchemaEnumValue() } - ) - } - - private fun GQLEnumValueDefinition.toSchemaEnumValue(): IntrospectionSchema.Schema.Type.Enum.Value { - val deprecationReason = directives.findDeprecationReason() - return IntrospectionSchema.Schema.Type.Enum.Value( - name = name, - description = description, - isDeprecated = deprecationReason != null, - deprecationReason = deprecationReason - ) - } - - private fun GQLScalarTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Scalar { - return IntrospectionSchema.Schema.Type.Scalar( - name = this.name, - description = this.description - ) - } - - private fun GQLUnionTypeDefinition.toSchemaType(): IntrospectionSchema.Schema.Type.Union { - return IntrospectionSchema.Schema.Type.Union( - name = name, - description = description, - fields = null, - possibleTypes = memberTypes.map { it.toSchemaType(schema) } - ) - } - - private fun GQLDirectiveDefinition.toSchemaDirective() = IntrospectionSchema.Schema.Directive( - name = name, - description = description, - locations = locations.map { it.toSchemaDirectiveLocation() }, - args = arguments.map { it.toSchemaArgument() }, - isRepeatable = repeatable, - ) - - private fun GQLDirectiveLocation.toSchemaDirectiveLocation() = when (this) { - GQLDirectiveLocation.QUERY -> IntrospectionSchema.Schema.Directive.DirectiveLocation.QUERY - GQLDirectiveLocation.MUTATION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.MUTATION - GQLDirectiveLocation.SUBSCRIPTION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.SUBSCRIPTION - GQLDirectiveLocation.FIELD -> IntrospectionSchema.Schema.Directive.DirectiveLocation.FIELD - GQLDirectiveLocation.FRAGMENT_DEFINITION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.FRAGMENT_DEFINITION - GQLDirectiveLocation.FRAGMENT_SPREAD -> IntrospectionSchema.Schema.Directive.DirectiveLocation.FRAGMENT_SPREAD - GQLDirectiveLocation.INLINE_FRAGMENT -> IntrospectionSchema.Schema.Directive.DirectiveLocation.INLINE_FRAGMENT - GQLDirectiveLocation.VARIABLE_DEFINITION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.VARIABLE_DEFINITION - GQLDirectiveLocation.SCHEMA -> IntrospectionSchema.Schema.Directive.DirectiveLocation.SCHEMA - GQLDirectiveLocation.SCALAR -> IntrospectionSchema.Schema.Directive.DirectiveLocation.SCALAR - GQLDirectiveLocation.OBJECT -> IntrospectionSchema.Schema.Directive.DirectiveLocation.OBJECT - GQLDirectiveLocation.FIELD_DEFINITION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.FIELD_DEFINITION - GQLDirectiveLocation.ARGUMENT_DEFINITION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.ARGUMENT_DEFINITION - GQLDirectiveLocation.INTERFACE -> IntrospectionSchema.Schema.Directive.DirectiveLocation.INTERFACE - GQLDirectiveLocation.UNION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.UNION - GQLDirectiveLocation.ENUM -> IntrospectionSchema.Schema.Directive.DirectiveLocation.ENUM - GQLDirectiveLocation.ENUM_VALUE -> IntrospectionSchema.Schema.Directive.DirectiveLocation.ENUM_VALUE - GQLDirectiveLocation.INPUT_OBJECT -> IntrospectionSchema.Schema.Directive.DirectiveLocation.INPUT_OBJECT - GQLDirectiveLocation.INPUT_FIELD_DEFINITION -> IntrospectionSchema.Schema.Directive.DirectiveLocation.INPUT_FIELD_DEFINITION - } -} - -internal fun GQLType.toSchemaType(schema: Schema): IntrospectionSchema.Schema.TypeRef { - return when (this) { - is GQLNonNullType -> { - IntrospectionSchema.Schema.TypeRef( - kind = IntrospectionSchema.Schema.Kind.NON_NULL, - name = "", // why "" and not null ? - ofType = type.toSchemaType(schema) - ) - } - is GQLListType -> { - IntrospectionSchema.Schema.TypeRef( - kind = IntrospectionSchema.Schema.Kind.LIST, - name = "", // why "" and not null ? - ofType = type.toSchemaType(schema)) - } - is GQLNamedType -> { - IntrospectionSchema.Schema.TypeRef( - kind = schema.typeDefinition(name).schemaKind(), - name = name, - ofType = null - ) - } - } -} - -internal fun GQLTypeDefinition.schemaKind() = when (this) { - is GQLEnumTypeDefinition -> IntrospectionSchema.Schema.Kind.ENUM - is GQLUnionTypeDefinition -> IntrospectionSchema.Schema.Kind.UNION - is GQLObjectTypeDefinition -> IntrospectionSchema.Schema.Kind.OBJECT - is GQLInputObjectTypeDefinition -> IntrospectionSchema.Schema.Kind.INPUT_OBJECT - is GQLScalarTypeDefinition -> IntrospectionSchema.Schema.Kind.SCALAR - is GQLInterfaceTypeDefinition -> IntrospectionSchema.Schema.Kind.INTERFACE -} - -fun Schema.toIntrospectionSchema() = IntrospectionSchemaBuilder(this).toIntrospectionSchema() - -private fun GQLValue.toKotlinValue(constContext: Boolean): Any? { - return when (this) { - is GQLIntValue -> value - is GQLFloatValue -> value - is GQLStringValue -> value - is GQLNullValue -> null - is GQLListValue -> values.map { it.toKotlinValue(constContext) } - is GQLObjectValue -> fields.map { it.name to it.value.toKotlinValue(constContext) }.toMap() - is GQLBooleanValue -> value - is GQLEnumValue -> value // Could we use something else in Kotlin? - is GQLVariableValue -> { - error("Default values cannot contain variables") - } - } -} diff --git a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SchemaTest.kt b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SchemaTest.kt index bce011d75e0..063947a9e74 100644 --- a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SchemaTest.kt +++ b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SchemaTest.kt @@ -1,5 +1,6 @@ package com.apollographql.apollo3.graphql.ast.test +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSchema import kotlin.test.Test @@ -18,6 +19,6 @@ class SchemaTest { } """.trimIndent() - schemaString.toSchema() + schemaString.toGQLDocument().toSchema() } } diff --git a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/IntrospectionTest.kt b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/IntrospectionTest.kt index 08e8e8ddd6a..28873539411 100644 --- a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/IntrospectionTest.kt +++ b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/IntrospectionTest.kt @@ -1,13 +1,11 @@ package com.apollographql.apollo3.graphql.ast.test.introspection -import com.apollographql.apollo3.ast.HOST_FILESYSTEM import com.apollographql.apollo3.ast.SourceAwareException -import com.apollographql.apollo3.ast.introspection.IntrospectionSchema import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema -import com.apollographql.apollo3.ast.introspection.toSchema +import com.apollographql.apollo3.ast.toFullSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.graphql.ast.test.CWD -import okio.Buffer import okio.Path.Companion.toPath import kotlin.test.Test import kotlin.test.assertEquals @@ -17,7 +15,10 @@ class IntrospectionTest { @Test fun parseSchema() { try { - "${CWD}/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/duplicate.json".toPath().toSchema() + "${CWD}/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/introspection/duplicate.json" + .toPath() + .toGQLDocument(allowJson = true) + .toSchema() } catch (e: SourceAwareException) { assertTrue(e.message!!.contains("is defined multiple times")) } @@ -52,17 +53,19 @@ class IntrospectionTest { } """.trimIndent() - val introspectionSchema = Buffer().writeUtf8(schema) - .toSchema() + val introspectionSchema = schema + .toGQLDocument() + .toFullSchemaGQLDocument() .toIntrospectionSchema() + .__schema - val someInputType = introspectionSchema.__schema.types.first { it.name == "SomeInput" } as IntrospectionSchema.Schema.Type.InputObject + val someInputType = introspectionSchema.types.first { it.name == "SomeInput" } val someInputFields = someInputType.inputFields - assertEquals("false", someInputFields.first { it.name == "value1" }.defaultValue) - assertEquals("South", someInputFields.first { it.name == "value2" }.defaultValue) - assertEquals("{\nvalue: true\nvalue2: [North,null,South]\n}\n", someInputFields.first { it.name == "value3" }.defaultValue) - assertEquals("[0,null,1]", someInputFields.first { it.name == "value4" }.defaultValue) - assertEquals("\"South\"", someInputFields.first { it.name == "value5" }.defaultValue) + assertEquals("false", someInputFields?.first { it.name == "value1" }?.defaultValue) + assertEquals("South", someInputFields?.first { it.name == "value2" }?.defaultValue) + assertEquals("{\nvalue: true\nvalue2: [North,null,South]\n}\n", someInputFields?.first { it.name == "value3" }?.defaultValue) + assertEquals("[0,null,1]", someInputFields?.first { it.name == "value4" }?.defaultValue) + assertEquals("\"South\"", someInputFields?.first { it.name == "value5" }?.defaultValue) } } diff --git a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/OperationValidationTest.kt b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/OperationValidationTest.kt index c2df1c372cd..a2208636823 100644 --- a/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/OperationValidationTest.kt +++ b/libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/OperationValidationTest.kt @@ -1,39 +1,35 @@ package com.apollographql.apollo3.graphql.ast.test.validation -import com.apollographql.apollo3.ast.HOST_FILESYSTEM -import com.apollographql.apollo3.ast.SourceLocation -import com.apollographql.apollo3.ast.introspection.toSchema -import com.apollographql.apollo3.ast.parseAsGQLDocument -import com.apollographql.apollo3.ast.pretty +import com.apollographql.apollo3.ast.toGQLDocument +import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.ast.validateAsExecutable import com.apollographql.apollo3.graphql.ast.test.CWD import okio.Path.Companion.toPath -import okio.buffer import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertNotNull class OperationValidationTest { @Test fun deprecatedInputField() { - val schema = "${CWD}/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/inputTypeDeprecatedField.graphqls".toPath().toSchema() + val schema = "${CWD}/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/inputTypeDeprecatedField.graphqls" + .toPath() + .toGQLDocument() + .toSchema() + val operations = "${CWD}/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/validation/inputTypeDeprecatedField.graphql" .toPath() - .let { HOST_FILESYSTEM.source(it) } - .buffer() - .parseAsGQLDocument(null) // Use filePath = null to remove the absolute path above - .getOrThrow() + .toGQLDocument() + val operationIssues = operations.validateAsExecutable(schema).issues assertEquals(1, operationIssues.size) assertEquals("Use of deprecated input field `deprecatedParameter`", operationIssues[0].message) - assertEquals( - SourceLocation( - start = 0, - end = 1, - line = 12, - column = 41, - null - ).pretty(), - operationIssues[0].sourceLocation.pretty() - ) + operationIssues[0].sourceLocation.apply { + assertNotNull(this) + assertEquals(247, start) + assertEquals(269, end) + assertEquals(12, line) + assertEquals(41, column) + } } } diff --git a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/api.jvm.kt b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/api.jvm.kt index a3c007eaac5..42e99650a4f 100644 --- a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/api.jvm.kt +++ b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/api.jvm.kt @@ -2,6 +2,9 @@ @file:JvmName("ApolloParser") package com.apollographql.apollo3.ast +import com.apollographql.apollo3.annotations.ApolloExperimental +import com.apollographql.apollo3.ast.introspection.toGQLDocument +import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema import okio.buffer import okio.source import java.io.File @@ -10,3 +13,13 @@ fun File.parseAsGQLDocument(options: ParserOptions = ParserOptions.Default): GQL return this.source().buffer().parseAsGQLDocument(filePath = path, options = options) } +fun File.toGQLDocument(options: ParserOptions = ParserOptions.Default, allowJson: Boolean = false): GQLDocument { + if (allowJson && extension == "json") { + return toIntrospectionSchema().toGQLDocument() + } + return parseAsGQLDocument(options).getOrThrow() +} + + +@ApolloExperimental +fun File.toSchema(allowJson: Boolean = false): Schema = toGQLDocument(allowJson = allowJson).validateAsSchema().getOrThrow() diff --git a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/internal/antlr_to_gql.kt b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/internal/antlr_to_gql.kt index 015b4f12909..7d06c06ed76 100644 --- a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/internal/antlr_to_gql.kt +++ b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/internal/antlr_to_gql.kt @@ -1,8 +1,7 @@ package com.apollographql.apollo3.ast.internal -import com.apollographql.apollo3.generated.antlr.GraphQLParser - import com.apollographql.apollo3.ast.* +import com.apollographql.apollo3.generated.antlr.GraphQLParser import org.antlr.v4.runtime.Token /** @@ -28,7 +27,7 @@ private class AntlrToGQLScope(val filePath: String?) { fun parseDocumentContext(documentContext: GraphQLParser.DocumentContext): GQLDocument { return GQLDocument( definitions = documentContext.definition().map { it.parse() }, - filePath = filePath + sourceLocation = SourceLocation.forPath(filePath) ) } diff --git a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.jvm.kt b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.jvm.kt deleted file mode 100644 index e298ed09292..00000000000 --- a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/IntrospectionSchema.jvm.kt +++ /dev/null @@ -1,16 +0,0 @@ -@file:JvmMultifileClass -@file:JvmName("IntrospectionSchemaKt") -package com.apollographql.apollo3.ast.introspection - -import okio.buffer -import okio.sink -import okio.source -import java.io.File - -fun File.toIntrospectionSchema() = inputStream().source().buffer().toIntrospectionSchema("from `$this`") - -fun IntrospectionSchema.writeTo(file: File) { - file.outputStream().sink().buffer().use { - it.writeUtf8(json.encodeToString(IntrospectionSchema.serializer(), this)) - } -} diff --git a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection.jvm.kt b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection.jvm.kt new file mode 100644 index 00000000000..8adce31ae09 --- /dev/null +++ b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection.jvm.kt @@ -0,0 +1,16 @@ +@file:JvmMultifileClass +@file:JvmName("Introspection") +package com.apollographql.apollo3.ast.introspection + +import okio.buffer +import okio.sink +import okio.source +import java.io.File + +fun File.toIntrospectionSchema(): IntrospectionSchema = inputStream().source().buffer().toIntrospectionSchema(absolutePath) + +fun ApolloIntrospectionSchema.writeTo(file: File) { + file.outputStream().sink().buffer().use { + it.writeUtf8(this.toJson()) + } +} diff --git a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.jvm.kt b/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.jvm.kt deleted file mode 100644 index 4d79b9f44ae..00000000000 --- a/libraries/apollo-ast/src/jvmMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.jvm.kt +++ /dev/null @@ -1,25 +0,0 @@ -@file:JvmMultifileClass -@file:JvmName("Introspection_to_schemaKt") -package com.apollographql.apollo3.ast.introspection - -import com.apollographql.apollo3.annotations.ApolloExperimental -import com.apollographql.apollo3.ast.GQLDocument -import com.apollographql.apollo3.ast.Schema -import com.apollographql.apollo3.ast.parseAsGQLDocument -import com.apollographql.apollo3.ast.validateAsSchema -import java.io.File - -/** - * Transforms the given file to a [GQLDocument] without doing validation - */ -@ApolloExperimental -fun File.toSchemaGQLDocument(): GQLDocument { - return if (extension == "json") { - toIntrospectionSchema().toGQLDocument(filePath = path) - } else { - parseAsGQLDocument().getOrThrow() - } -} - -@ApolloExperimental -fun File.toSchema(): Schema = toSchemaGQLDocument().validateAsSchema().getOrThrow() diff --git a/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/IntrospectionTest.jvm.kt b/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/IntrospectionTest.jvm.kt new file mode 100644 index 00000000000..33369aa0da1 --- /dev/null +++ b/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/IntrospectionTest.jvm.kt @@ -0,0 +1,54 @@ +package com.apollographql.apollo3.graphql.ast.test + +import com.apollographql.apollo3.ast.introspection.toGQLDocument +import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema +import com.apollographql.apollo3.ast.introspection.toJson +import com.apollographql.apollo3.ast.toFullSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument +import com.apollographql.apollo3.ast.validateAsSchema +import com.apollographql.apollo3.graphql.ast.test.ParserTest.Companion.checkExpected +import com.google.testing.junit.testparameterinjector.TestParameterInjector +import org.junit.Test +import org.junit.runner.RunWith +import java.io.File + +@RunWith(TestParameterInjector::class) +class IntrospectionTest { + private fun canReadIntrospectionResults(name: String) { + File("${CWD}/test-fixtures/introspection/$name.json") + .toIntrospectionSchema() + .toGQLDocument() + .validateAsSchema() + .getOrThrow() + } + + @Test + fun canReadJuly2015IntrospectionResults() { + canReadIntrospectionResults("july2015") + } + + @Test + fun canReadJune2018IntrospectionResults() { + canReadIntrospectionResults("june2018") + } + + @Test + fun canReadOctober2021IntrospectionResults() { + canReadIntrospectionResults("october2021") + } + + @Test + fun canReadDraftIntrospectionResults() { + canReadIntrospectionResults("draft") + } + + @Test + fun canWriteConfettiSchema() { + checkExpected(File("${CWD}/test-fixtures/introspection/confetti.graphqls")) { + it.toGQLDocument() + .toFullSchemaGQLDocument() + .toIntrospectionSchema() + .toJson() + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SDLWriterTest.kt b/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SDLWriterTest.kt index b87d8c4b75e..25e234600cc 100644 --- a/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SDLWriterTest.kt +++ b/libraries/apollo-ast/src/jvmTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SDLWriterTest.kt @@ -1,7 +1,7 @@ package com.apollographql.apollo3.graphql.ast.test -import com.apollographql.apollo3.ast.introspection.toSchema import com.apollographql.apollo3.ast.parseAsGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSDL import com.apollographql.apollo3.ast.withBuiltinDefinitions import com.apollographql.apollo3.graphql.ast.test.ParserTest.Companion.checkExpected @@ -29,10 +29,10 @@ class SDLWriterTest { @Test fun introspectionSchema() { - val sdlSchema = File("${CWD}/test-fixtures/sdl/introspection.json") + val jsonSchema = File("${CWD}/test-fixtures/sdl/introspection.json") - checkExpected(sdlSchema) { - it.toSchema().toGQLDocument().toSDL(" ") + checkExpected(jsonSchema) { + it.toGQLDocument(allowJson = true).toSDL(" ") } } diff --git a/libraries/apollo-ast/test-fixtures/introspection/confetti.expected b/libraries/apollo-ast/test-fixtures/introspection/confetti.expected new file mode 100644 index 00000000000..4d4f4f34c7d --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/confetti.expected @@ -0,0 +1 @@ +{"__schema":{"description":null,"types":[{"kind":"SCALAR","name":"Instant","description":"A type representing a formatted kotlinx.datetime.Instant","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"LocalDate","description":"A type representing a formatted kotlinx.datetime.LocalDate","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"LocalDateTime","description":"A type representing a formatted kotlinx.datetime.LocalDateTime","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"OBJECT","name":"Query","description":null,"fields":[{"name":"hello","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"isDeprecated":false,"deprecationReason":null}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"OBJECT","name":"__Directive","description":null,"fields":[{"name":"name","description":"The __Directive type represents a Directive that a server supports.","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":"isRepeatable","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"locations","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"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":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false","isDeprecated":false,"deprecationReason":null}],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__InputValue","ofType":null}}}},"isDeprecated":false,"deprecationReason":null}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"ENUM","name":"__DirectiveLocation","description":"An enum describing valid locations where a directive can be placed","fields":null,"interfaces":null,"possibleTypes":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":"SUBSCRIPTION","description":"Indicates the directive is valid on subscriptions.","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":"VARIABLE_DEFINITION","description":"Indicates the directive is valid on variable definitions.","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}],"inputFields":null,"specifiedByURL":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}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":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":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false","isDeprecated":false,"deprecationReason":null}],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__InputValue","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":"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}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":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},{"name":"isDeprecated","description":null,"args":[],"type":{"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}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":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":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"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","ofType":null}}}},"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","ofType":null}}}},"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}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":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","isDeprecated":false,"deprecationReason":null}],"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","isDeprecated":false,"deprecationReason":null}],"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":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false","isDeprecated":false,"deprecationReason":null}],"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},{"name":"specifiedByURL","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"specifiedByUrl","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":true,"deprecationReason":"No longer supported"}],"interfaces":[],"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"ENUM","name":"__TypeKind","description":"An enum describing what kind of type a given __Type is","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":[{"name":"SCALAR","description":"Indicates this type is a scalar. 'specifiedByURL' is a valid field","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}],"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"Int","description":"The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"Float","description":"The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"String","description":"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"Boolean","description":"The `Boolean` scalar type represents `true` or `false`.","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null},{"kind":"SCALAR","name":"ID","description":"The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID.","fields":null,"interfaces":null,"possibleTypes":null,"enumValues":null,"inputFields":null,"specifiedByURL":null}],"queryType":{"name":"Query"},"mutationType":null,"subscriptionType":null,"directives":[{"name":"include","description":"Directs the executor to include this field or fragment only when the `if` argument is true","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"],"args":[{"name":"if","description":"Included when true.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"defaultValue":null,"isDeprecated":false,"deprecationReason":null}],"isRepeatable":false},{"name":"skip","description":"Directs the executor to skip this field or fragment when the `if` argument is true.","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"],"args":[{"name":"if","description":"Skipped when true.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"defaultValue":null,"isDeprecated":false,"deprecationReason":null}],"isRepeatable":false},{"name":"deprecated","description":"Marks the field, argument, input field or enum value as deprecated","locations":["FIELD_DEFINITION","ARGUMENT_DEFINITION","ENUM_VALUE","INPUT_FIELD_DEFINITION"],"args":[{"name":"reason","description":"The reason for the deprecation","type":{"kind":"SCALAR","name":"String","ofType":null},"defaultValue":"\"No longer supported\"","isDeprecated":false,"deprecationReason":null}],"isRepeatable":false},{"name":"specifiedBy","description":"Exposes a URL that specifies the behaviour of this scalar.","locations":["SCALAR"],"args":[{"name":"url","description":"The URL that specifies the behaviour of this scalar.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"defaultValue":null,"isDeprecated":false,"deprecationReason":null}],"isRepeatable":false},{"name":"defer","description":null,"locations":["FRAGMENT_SPREAD","INLINE_FRAGMENT"],"args":[{"name":"label","description":null,"type":{"kind":"SCALAR","name":"String","ofType":null},"defaultValue":null,"isDeprecated":false,"deprecationReason":null},{"name":"if","description":null,"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"defaultValue":"true","isDeprecated":false,"deprecationReason":null}],"isRepeatable":false}]}} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/introspection/confetti.graphqls b/libraries/apollo-ast/test-fixtures/introspection/confetti.graphqls new file mode 100644 index 00000000000..59cf3c835f3 --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/confetti.graphqls @@ -0,0 +1,166 @@ +schema { + query: Query +} + +"A type representing a formatted kotlinx.datetime.Instant" +scalar Instant + +"A type representing a formatted kotlinx.datetime.LocalDate" +scalar LocalDate + +"A type representing a formatted kotlinx.datetime.LocalDateTime" +scalar LocalDateTime + +type Query { + hello: String! +} + +type __Directive { + "The __Directive type represents a Directive that a server supports." + name: String! + description: String + isRepeatable: Boolean! + locations: [__DirectiveLocation!]! + args(includeDeprecated: Boolean = false): [__InputValue!]! +} + +"An enum describing valid locations where a directive can be placed" +enum __DirectiveLocation { + "Indicates the directive is valid on queries." + QUERY + "Indicates the directive is valid on mutations." + MUTATION + "Indicates the directive is valid on subscriptions." + SUBSCRIPTION + "Indicates the directive is valid on fields." + FIELD + "Indicates the directive is valid on fragment definitions." + FRAGMENT_DEFINITION + "Indicates the directive is valid on fragment spreads." + FRAGMENT_SPREAD + "Indicates the directive is valid on inline fragments." + INLINE_FRAGMENT + "Indicates the directive is valid on variable definitions." + VARIABLE_DEFINITION + "Indicates the directive is valid on a schema SDL definition." + SCHEMA + "Indicates the directive is valid on a scalar SDL definition." + SCALAR + "Indicates the directive is valid on an object SDL definition." + OBJECT + "Indicates the directive is valid on a field SDL definition." + FIELD_DEFINITION + "Indicates the directive is valid on a field argument SDL definition." + ARGUMENT_DEFINITION + "Indicates the directive is valid on an interface SDL definition." + INTERFACE + "Indicates the directive is valid on an union SDL definition." + UNION + "Indicates the directive is valid on an enum SDL definition." + ENUM + "Indicates the directive is valid on an enum value SDL definition." + ENUM_VALUE + "Indicates the directive is valid on an input object SDL definition." + INPUT_OBJECT + "Indicates the directive is valid on an input object field SDL definition." + INPUT_FIELD_DEFINITION +} + +type __EnumValue { + name: String! + description: String + isDeprecated: Boolean! + deprecationReason: String +} + +type __Field { + name: String! + description: String + args(includeDeprecated: Boolean = false): [__InputValue!]! + type: __Type! + isDeprecated: Boolean! + deprecationReason: String +} + +type __InputValue { + name: String! + description: String + type: __Type! + defaultValue: String + isDeprecated: Boolean + deprecationReason: String +} + +"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." +type __Schema { + description: String + "A list of all types supported by this server." + types: [__Type!]! + "The type that query operations will be rooted at." + queryType: __Type! + "If this server supports mutation, the type that mutation operations will be rooted at." + mutationType: __Type + "'A list of all directives supported by this server." + directives: [__Directive!]! + "'If this server support subscription, the type that subscription operations will be rooted at." + subscriptionType: __Type +} + +type __Type { + kind: __TypeKind! + name: String + description: String + fields(includeDeprecated: Boolean = false): [__Field!] + interfaces: [__Type!] + possibleTypes: [__Type!] + enumValues(includeDeprecated: Boolean = false): [__EnumValue!] + inputFields(includeDeprecated: Boolean = false): [__InputValue!] + ofType: __Type + specifiedByURL: String + specifiedByUrl: String @deprecated +} + +"An enum describing what kind of type a given __Type is" +enum __TypeKind { + "Indicates this type is a scalar. 'specifiedByURL' is a valid field" + SCALAR + "Indicates this type is an object. `fields` and `interfaces` are valid fields." + OBJECT + "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields." + INTERFACE + "Indicates this type is a union. `possibleTypes` is a valid field." + UNION + "Indicates this type is an enum. `enumValues` is a valid field." + ENUM + "Indicates this type is an input object. `inputFields` is a valid field." + INPUT_OBJECT + "Indicates this type is a list. `ofType` is a valid field." + LIST + "Indicates this type is a non-null. `ofType` is a valid field." + NON_NULL +} + +"Directs the executor to include this field or fragment only when the `if` argument is true" +directive @include( + "Included when true." + if: Boolean! +) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Directs the executor to skip this field or fragment when the `if` argument is true." +directive @skip( + "Skipped when true." + if: Boolean! +) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT + +"Marks the field, argument, input field or enum value as deprecated" +directive @deprecated( + "The reason for the deprecation" + reason: String = "No longer supported" +) on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION + +"Exposes a URL that specifies the behaviour of this scalar." +directive @specifiedBy( + "The URL that specifies the behaviour of this scalar." + url: String! +) on SCALAR + diff --git a/libraries/apollo-ast/test-fixtures/introspection/draft.json b/libraries/apollo-ast/test-fixtures/introspection/draft.json new file mode 100644 index 00000000000..3d5228b1b25 --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/draft.json @@ -0,0 +1,1172 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": null, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "Instant", + "description": "A type representing a formatted kotlinx.datetime.Instant", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDate", + "description": "A type representing a formatted kotlinx.datetime.LocalDate", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDateTime", + "description": "A type representing a formatted kotlinx.datetime.LocalDateTime", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": null, + "fields": [ + { + "name": "hello", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "_service", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "_Service", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "_Service", + "description": null, + "fields": [ + { + "name": "sdl", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": "The __Directive type represents a Directive that a server supports.", + "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": "isRepeatable", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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": "SUBSCRIPTION", + "description": "Indicates the directive is valid on subscriptions.", + "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": "VARIABLE_DEFINITION", + "description": "Indicates the directive is valid on variable definitions.", + "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, + "specifiedByURL": 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, + "specifiedByURL": 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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "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": "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, + "specifiedByURL": 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 + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "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, + "specifiedByURL": 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": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "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", + "ofType": null + } + } + } + }, + "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", + "ofType": null + } + } + } + }, + "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, + "specifiedByURL": 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", + "isDeprecated": false, + "deprecationReason": null + } + ], + "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", + "isDeprecated": false, + "deprecationReason": null + } + ], + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null + } + ], + "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 + }, + { + "name": "specifiedByURL", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByUrl", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This legacy name has been replaced by `specifiedByURL`" + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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. 'specifiedByURL' is a valid field", + "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, + "specifiedByURL": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "deprecated", + "description": "Marks the field, argument, input field or enum value as deprecated", + "locations": [ + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "ENUM_VALUE", + "INPUT_FIELD_DEFINITION" + ], + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": "\"No longer supported\"", + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "specifiedBy", + "description": "Exposes a URL that specifies the behaviour of this scalar.", + "locations": [ + "SCALAR" + ], + "args": [ + { + "name": "url", + "description": "The URL that specifies the behaviour of this scalar.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + } + ] + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/introspection/july2015.json b/libraries/apollo-ast/test-fixtures/introspection/july2015.json new file mode 100644 index 00000000000..8725a12e3f5 --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/july2015.json @@ -0,0 +1,1055 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Instant", + "description": "A type representing a formatted kotlinx.datetime.Instant", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "LocalDate", + "description": "A type representing a formatted kotlinx.datetime.LocalDate", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "LocalDateTime", + "description": "A type representing a formatted kotlinx.datetime.LocalDateTime", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": null, + "fields": [ + { + "name": "hello", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "_service", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "_Service", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "_Service", + "description": null, + "fields": [ + { + "name": "sdl", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": "The __Directive type represents a Directive that a server supports.", + "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": "isRepeatable", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "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": "SUBSCRIPTION", + "description": "Indicates the directive is valid on subscriptions.", + "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": "VARIABLE_DEFINITION", + "description": "Indicates the directive is valid on variable definitions.", + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "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": "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 + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "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": "__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": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "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", + "ofType": null + } + } + } + }, + "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", + "ofType": null + } + } + } + }, + "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": [ + { + "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": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByURL", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByUrl", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This legacy name has been replaced by `specifiedByURL`" + } + ], + "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. 'specifiedByURL' is a valid field", + "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" + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true." + }, + { + "name": "deprecated", + "description": "Marks the field, argument, input field or enum value as deprecated" + }, + { + "name": "specifiedBy", + "description": "Exposes a URL that specifies the behaviour of this scalar." + } + ] + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/introspection/june2018.json b/libraries/apollo-ast/test-fixtures/introspection/june2018.json new file mode 100644 index 00000000000..4352a1469ad --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/june2018.json @@ -0,0 +1,1135 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": null, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "Instant", + "description": "A type representing a formatted kotlinx.datetime.Instant", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "LocalDate", + "description": "A type representing a formatted kotlinx.datetime.LocalDate", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "LocalDateTime", + "description": "A type representing a formatted kotlinx.datetime.LocalDateTime", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": null, + "fields": [ + { + "name": "hello", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "_service", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "_Service", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "_Service", + "description": null, + "fields": [ + { + "name": "sdl", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": "The __Directive type represents a Directive that a server supports.", + "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": "isRepeatable", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "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": "SUBSCRIPTION", + "description": "Indicates the directive is valid on subscriptions.", + "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": "VARIABLE_DEFINITION", + "description": "Indicates the directive is valid on variable definitions.", + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "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": "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 + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "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": "__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": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "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", + "ofType": null + } + } + } + }, + "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", + "ofType": null + } + } + } + }, + "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": [ + { + "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": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByURL", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByUrl", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This legacy name has been replaced by `specifiedByURL`" + } + ], + "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. 'specifiedByURL' is a valid field", + "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", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ] + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ] + }, + { + "name": "deprecated", + "description": "Marks the field, argument, input field or enum value as deprecated", + "locations": [ + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "ENUM_VALUE", + "INPUT_FIELD_DEFINITION" + ], + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": "\"No longer supported\"" + } + ] + }, + { + "name": "specifiedBy", + "description": "Exposes a URL that specifies the behaviour of this scalar.", + "locations": [ + "SCALAR" + ], + "args": [ + { + "name": "url", + "description": "The URL that specifies the behaviour of this scalar.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ] + } + ] + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/introspection/missing_default_values.json b/libraries/apollo-ast/test-fixtures/introspection/missing_default_values.json new file mode 100644 index 00000000000..5e5e7acb8f3 --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/missing_default_values.json @@ -0,0 +1,1163 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": null, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "Instant", + "description": "A type representing a formatted kotlinx.datetime.Instant", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDate", + "description": "A type representing a formatted kotlinx.datetime.LocalDate", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDateTime", + "description": "A type representing a formatted kotlinx.datetime.LocalDateTime", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": null, + "fields": [ + { + "name": "hello", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "_service", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "_Service", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "_Service", + "description": null, + "fields": [ + { + "name": "sdl", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": "The __Directive type represents a Directive that a server supports.", + "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": "isRepeatable", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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": "SUBSCRIPTION", + "description": "Indicates the directive is valid on subscriptions.", + "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": "VARIABLE_DEFINITION", + "description": "Indicates the directive is valid on variable definitions.", + "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, + "specifiedByURL": 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, + "specifiedByURL": 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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "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": "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, + "specifiedByURL": 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 + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "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, + "specifiedByURL": 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": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "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", + "ofType": null + } + } + } + }, + "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", + "ofType": null + } + } + } + }, + "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, + "specifiedByURL": 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 + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "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 + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "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 + }, + { + "name": "specifiedByURL", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByUrl", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This legacy name has been replaced by `specifiedByURL`" + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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. 'specifiedByURL' is a valid field", + "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, + "specifiedByURL": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "deprecated", + "description": "Marks the field, argument, input field or enum value as deprecated", + "locations": [ + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "ENUM_VALUE", + "INPUT_FIELD_DEFINITION" + ], + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + }, + { + "name": "specifiedBy", + "description": "Exposes a URL that specifies the behaviour of this scalar.", + "locations": [ + "SCALAR" + ], + "args": [ + { + "name": "url", + "description": "The URL that specifies the behaviour of this scalar.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "isRepeatable": false + } + ] + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/introspection/october2021.json b/libraries/apollo-ast/test-fixtures/introspection/october2021.json new file mode 100644 index 00000000000..71e019d0c90 --- /dev/null +++ b/libraries/apollo-ast/test-fixtures/introspection/october2021.json @@ -0,0 +1,1154 @@ +{ + "data": { + "__schema": { + "queryType": { + "name": "Query" + }, + "mutationType": null, + "subscriptionType": null, + "types": [ + { + "kind": "SCALAR", + "name": "Boolean", + "description": "Built-in Boolean", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "Instant", + "description": "A type representing a formatted kotlinx.datetime.Instant", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDate", + "description": "A type representing a formatted kotlinx.datetime.LocalDate", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "LocalDateTime", + "description": "A type representing a formatted kotlinx.datetime.LocalDateTime", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "Query", + "description": null, + "fields": [ + { + "name": "hello", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "_service", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "_Service", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "SCALAR", + "name": "String", + "description": "Built-in String", + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "_Service", + "description": null, + "fields": [ + { + "name": "sdl", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": null + }, + { + "kind": "OBJECT", + "name": "__Directive", + "description": null, + "fields": [ + { + "name": "name", + "description": "The __Directive type represents a Directive that a server supports.", + "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": "isRepeatable", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "locations", + "description": null, + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "ofType": null + } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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": "SUBSCRIPTION", + "description": "Indicates the directive is valid on subscriptions.", + "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": "VARIABLE_DEFINITION", + "description": "Indicates the directive is valid on variable definitions.", + "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, + "specifiedByURL": 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, + "specifiedByURL": 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": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false" + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "__InputValue", + "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": "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, + "specifiedByURL": 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 + }, + { + "name": "isDeprecated", + "description": null, + "args": [], + "type": { + "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, + "specifiedByURL": 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": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "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", + "ofType": null + } + } + } + }, + "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", + "ofType": null + } + } + } + }, + "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, + "specifiedByURL": 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": [ + { + "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": "__InputValue", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "ofType", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByURL", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "specifiedByUrl", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This legacy name has been replaced by `specifiedByURL`" + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null, + "specifiedByURL": 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. 'specifiedByURL' is a valid field", + "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, + "specifiedByURL": null + } + ], + "directives": [ + { + "name": "include", + "description": "Directs the executor to include this field or fragment only when the `if` argument is true", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Included when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "isRepeatable": false + }, + { + "name": "skip", + "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", + "locations": [ + "FIELD", + "FRAGMENT_SPREAD", + "INLINE_FRAGMENT" + ], + "args": [ + { + "name": "if", + "description": "Skipped when true.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + "defaultValue": null + } + ], + "isRepeatable": false + }, + { + "name": "deprecated", + "description": "Marks the field, argument, input field or enum value as deprecated", + "locations": [ + "FIELD_DEFINITION", + "ARGUMENT_DEFINITION", + "ENUM_VALUE", + "INPUT_FIELD_DEFINITION" + ], + "args": [ + { + "name": "reason", + "description": "The reason for the deprecation", + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": "\"No longer supported\"" + } + ], + "isRepeatable": false + }, + { + "name": "specifiedBy", + "description": "Exposes a URL that specifies the behaviour of this scalar.", + "locations": [ + "SCALAR" + ], + "args": [ + { + "name": "url", + "description": "The URL that specifies the behaviour of this scalar.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + } + ], + "isRepeatable": false + } + ] + } + } +} \ No newline at end of file diff --git a/libraries/apollo-ast/test-fixtures/sdl/introspection.expected b/libraries/apollo-ast/test-fixtures/sdl/introspection.expected index 618e880dbf0..1f18fcb7c16 100644 --- a/libraries/apollo-ast/test-fixtures/sdl/introspection.expected +++ b/libraries/apollo-ast/test-fixtures/sdl/introspection.expected @@ -1,5 +1,5 @@ -schema { - query: Query +type Query { + foo: Int } # See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 @@ -30,168 +30,6 @@ Exposes a URL that specifies the behaviour of this scalar. """ directive @specifiedBy ("The URL that specifies the behaviour of this scalar." url: String!) on SCALAR -directive @defer (label: String, if: Boolean! = true) on FRAGMENT_SPREAD|INLINE_FRAGMENT - -type Query { - foo: Int -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __Schema { - description: String - - types: [__Type!]! - - queryType: __Type! - - mutationType: __Type - - subscriptionType: __Type - - directives: [__Directive!]! -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __Type { - kind: __TypeKind! - - name: String - - description: String - - fields(includeDeprecated: Boolean = false): [__Field!] - - interfaces: [__Type!] - - possibleTypes: [__Type!] - - enumValues(includeDeprecated: Boolean = false): [__EnumValue!] - - inputFields(includeDeprecated: Boolean = false): [__InputValue!] - - ofType: __Type - - specifiedByURL: String -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -enum __TypeKind { - SCALAR - - OBJECT - - INTERFACE - - UNION - - ENUM - - INPUT_OBJECT - - LIST - - NON_NULL -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __Field { - name: String! - - description: String - - args(includeDeprecated: Boolean = false): [__InputValue!]! - - type: __Type! - - isDeprecated: Boolean! - - deprecationReason: String -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __InputValue { - name: String! - - description: String - - type: __Type! - - defaultValue: String - - isDeprecated: Boolean! - - deprecationReason: String -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __EnumValue { - name: String! - - description: String - - isDeprecated: Boolean! - - deprecationReason: String -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -type __Directive { - name: String! - - description: String - - locations: [__DirectiveLocation!]! - - args(includeDeprecated: Boolean = false): [__InputValue!]! - - isRepeatable: Boolean! -} - -# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 -# noinspection GraphQLTypeRedefinition -enum __DirectiveLocation { - QUERY - - MUTATION - - SUBSCRIPTION - - FIELD - - FRAGMENT_DEFINITION - - FRAGMENT_SPREAD - - INLINE_FRAGMENT - - VARIABLE_DEFINITION - - SCHEMA - - SCALAR - - OBJECT - - FIELD_DEFINITION - - ARGUMENT_DEFINITION - - INTERFACE - - UNION - - ENUM - - ENUM_VALUE - - INPUT_OBJECT - - INPUT_FIELD_DEFINITION +schema { + query: Query } diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt index 187343279f2..6c8b0264a1a 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/ApolloCompiler.kt @@ -13,9 +13,9 @@ import com.apollographql.apollo3.ast.ParserOptions import com.apollographql.apollo3.ast.QueryDocumentMinifier import com.apollographql.apollo3.ast.Schema import com.apollographql.apollo3.ast.checkNoErrors -import com.apollographql.apollo3.ast.introspection.toSchemaGQLDocument import com.apollographql.apollo3.ast.parseAsGQLDocument import com.apollographql.apollo3.ast.pretty +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.validateAsExecutable import com.apollographql.apollo3.ast.validateAsSchemaAndAddApolloDefinition import com.apollographql.apollo3.compiler.codegen.java.JavaCodeGen @@ -53,7 +53,7 @@ object ApolloCompiler { ): CodegenSchema { val schemaDocuments = schemaFiles.map { - it.toSchemaGQLDocument() + it.toGQLDocument(allowJson = true) } if (schemaDocuments.isEmpty()) { @@ -61,9 +61,17 @@ object ApolloCompiler { } // Locate the mainSchemaDocument. It's the one that contains the operation roots - val mainSchemaDocuments = schemaDocuments.filter { - it.definitions.filterIsInstance().isNotEmpty() + val mainSchemaDocuments = mutableListOf() + var otherSchemaDocuments = mutableListOf() + schemaDocuments.forEach { + if ( + it.definitions.filterIsInstance().isNotEmpty() || it.definitions.filterIsInstance().any { it.name == "Query" } + ) { + mainSchemaDocuments.add(it) + } else { + otherSchemaDocuments.add(it) + } } if (mainSchemaDocuments.size > 1) { @@ -75,10 +83,12 @@ object ApolloCompiler { } val mainSchemaDocument = mainSchemaDocuments.single() - val schemaDefinitions = schemaDocuments.flatMap { it.definitions } + // Sort the other schema document as type extensions are order sensitive + val otherSchemaDocumentSorted = otherSchemaDocuments.sortedBy { it.sourceLocation?.filePath?.substringAfterLast(File.pathSeparator) } + val schemaDefinitions = (listOf(mainSchemaDocument) + otherSchemaDocumentSorted).flatMap { it.definitions } val schemaDocument = GQLDocument( definitions = schemaDefinitions, - filePath = null + sourceLocation = null ) /** @@ -144,7 +154,7 @@ object ApolloCompiler { */ val validationResult = GQLDocument( definitions = definitions + incomingFragments, - filePath = null + sourceLocation = null ).validateAsExecutable(schema, options.fieldsOnDisjointTypesMustMerge) validationResult.issues.checkNoErrors() diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkCapitalizedFields.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkCapitalizedFields.kt index 6da93dcdad0..5b0d840e224 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkCapitalizedFields.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkCapitalizedFields.kt @@ -11,7 +11,6 @@ import com.apollographql.apollo3.ast.GQLInlineFragment import com.apollographql.apollo3.ast.GQLOperationDefinition import com.apollographql.apollo3.ast.GQLSelection import com.apollographql.apollo3.ast.Issue -import com.apollographql.apollo3.ast.internal.IssuesScope @ApolloInternal fun checkCapitalizedFields(definitions: List, checkFragmentsOnly: Boolean): List { @@ -64,8 +63,8 @@ private fun ValidationScope.checkCapitalizedFields(selections: List +private interface ValidationScope { + val issues: MutableList val fragmentsByName: Map } diff --git a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkConditionalFragment.kt b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkConditionalFragment.kt index b1f87b630b8..3d61cb27443 100644 --- a/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkConditionalFragment.kt +++ b/libraries/apollo-compiler/src/main/kotlin/com/apollographql/apollo3/compiler/checkConditionalFragment.kt @@ -8,34 +8,31 @@ import com.apollographql.apollo3.ast.GQLInlineFragment import com.apollographql.apollo3.ast.GQLOperationDefinition import com.apollographql.apollo3.ast.GQLSelection import com.apollographql.apollo3.ast.Issue -import com.apollographql.apollo3.ast.internal.IssuesScope import com.apollographql.apollo3.compiler.ir.BooleanExpression import com.apollographql.apollo3.compiler.ir.toBooleanExpression internal fun checkConditionalFragments(definitions: List): List { - val scope = object : IssuesScope { - override val issues = mutableListOf() - } + val issues = mutableListOf() definitions.forEach { when (it) { - is GQLOperationDefinition -> scope.checkConditionalFragments(it.selections) - is GQLFragmentDefinition -> scope.checkConditionalFragments(it.selections) + is GQLOperationDefinition -> checkConditionalFragments(issues, it.selections) + is GQLFragmentDefinition -> checkConditionalFragments(issues, it.selections) else -> {} } } - return scope.issues + return issues } /** * Fragments with @include/@skip or @defer directives are hard to generate as responseBased models because they would * need multiple shapes depending on the condition. This is not supported at the moment */ -private fun IssuesScope.checkConditionalFragments(selections: List) { +private fun checkConditionalFragments(issues: MutableList, selections: List) { selections.forEach { when (it) { - is GQLField -> checkConditionalFragments(it.selections) + is GQLField -> checkConditionalFragments(issues, it.selections) is GQLInlineFragment -> { if (it.directives.toBooleanExpression() != BooleanExpression.True) { issues.add( @@ -45,7 +42,7 @@ private fun IssuesScope.checkConditionalFragments(selections: List ) ) } - checkConditionalFragments(it.selections) + checkConditionalFragments(issues, it.selections) } is GQLFragmentSpread -> { if (it.directives.toBooleanExpression() != BooleanExpression.True) { diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/CodegenTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/CodegenTest.kt index dd46d2ea26b..ba1705f315d 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/CodegenTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/CodegenTest.kt @@ -4,8 +4,8 @@ import com.apollographql.apollo3.annotations.ApolloExperimental import com.apollographql.apollo3.ast.GQLFragmentSpread import com.apollographql.apollo3.ast.GQLInlineFragment import com.apollographql.apollo3.ast.GQLNode -import com.apollographql.apollo3.ast.introspection.toSchemaGQLDocument import com.apollographql.apollo3.ast.parseAsGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.validateAsSchemaAndAddApolloDefinition import com.apollographql.apollo3.compiler.TargetLanguage.JAVA import com.apollographql.apollo3.compiler.TargetLanguage.KOTLIN_1_5 @@ -383,7 +383,7 @@ class CodegenTest { val packageNameGenerator = PackageNameGenerator.Flat(packageName) ApolloCompiler.writeSimple( - schema = schemaFile.toSchemaGQLDocument().validateAsSchemaAndAddApolloDefinition().getOrThrow(), + schema = schemaFile.toGQLDocument(allowJson = true).validateAsSchemaAndAddApolloDefinition().getOrThrow(), executableFiles = graphqlFiles, outputDir = outputDir, flattenModels = flattenModels, diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/PossibleTypesTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/PossibleTypesTest.kt index 72151b0f49d..fdccb8ade7e 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/PossibleTypesTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/PossibleTypesTest.kt @@ -1,6 +1,6 @@ package com.apollographql.apollo3.compiler -import com.apollographql.apollo3.ast.introspection.toSchema +import com.apollographql.apollo3.ast.toSchema import com.google.common.truth.Truth.assertThat import org.junit.Test import java.io.File diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/SdlWritingTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/SdlWritingTest.kt index 5cda8f34125..d3c75917af5 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/SdlWritingTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/SdlWritingTest.kt @@ -3,7 +3,8 @@ package com.apollographql.apollo3.compiler import com.apollographql.apollo3.ast.introspection.toGQLDocument import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema import com.apollographql.apollo3.ast.introspection.toJson -import com.apollographql.apollo3.ast.introspection.toSchema +import com.apollographql.apollo3.ast.toFullSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.ast.toUtf8 import org.junit.Assert @@ -101,7 +102,7 @@ class SdlWritingTest { } """.trimIndent() - val jsonSchema = src.buffer().toSchema().toIntrospectionSchema().toJson() + val jsonSchema = src.toGQLDocument().toFullSchemaGQLDocument().toIntrospectionSchema().toJson() assertTrue(jsonSchema.contains("\"defaultValue\":\"\\\"\\\"\"")) val sdlSchema = jsonSchema.toIntrospectionSchema().toGQLDocument().toUtf8() diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/StringEncodingTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/StringEncodingTest.kt index 70e020afd67..a8b8a3963b7 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/StringEncodingTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/StringEncodingTest.kt @@ -2,8 +2,8 @@ package com.apollographql.apollo3.compiler import com.apollographql.apollo3.ast.GQLObjectTypeDefinition import com.apollographql.apollo3.ast.GQLStringValue -import com.apollographql.apollo3.ast.builtinDefinitions import com.apollographql.apollo3.ast.encodeToGraphQLSingleQuoted +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSchema import com.google.common.truth.Truth import org.junit.Test @@ -31,7 +31,7 @@ class StringEncodingTest { } """.trimIndent() - val queryType = schema.buffer().toSchema().typeDefinition("Query") as GQLObjectTypeDefinition + val queryType = schema.toGQLDocument().toSchema().typeDefinition("Query") as GQLObjectTypeDefinition val defaultValue = (queryType.fields.first().arguments.first().defaultValue as GQLStringValue).value assertEquals("", defaultValue) } @@ -45,7 +45,7 @@ class StringEncodingTest { } """.trimIndent() - val queryType = schema.buffer().toSchema().typeDefinition("Query") as GQLObjectTypeDefinition + val queryType = schema.toGQLDocument().toSchema().typeDefinition("Query") as GQLObjectTypeDefinition val defaultValue = (queryType.fields.first().arguments.first().defaultValue as GQLStringValue).value assertEquals("", defaultValue) } diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TestUtils.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TestUtils.kt index 45b1649f080..2322d8f3e01 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TestUtils.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TestUtils.kt @@ -2,7 +2,7 @@ package com.apollographql.apollo3.compiler import com.apollographql.apollo3.ast.Issue import com.apollographql.apollo3.ast.Schema -import com.apollographql.apollo3.ast.introspection.toSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.validateAsSchemaAndAddApolloDefinition import com.google.common.truth.Truth.assertThat import okio.Buffer @@ -72,7 +72,7 @@ internal object TestUtils { return listOf("graphqls", "sdl", "json").map { File(dir, "schema.$it") } .firstOrNull { it.exists() } ?.let { - it.toSchemaGQLDocument().validateAsSchemaAndAddApolloDefinition().getOrThrow() + it.toGQLDocument(allowJson = true).validateAsSchemaAndAddApolloDefinition().getOrThrow() } } diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TypenameTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TypenameTest.kt index 4ae4a4423ad..11b40892a2a 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TypenameTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/TypenameTest.kt @@ -3,8 +3,8 @@ package com.apollographql.apollo3.compiler import com.apollographql.apollo3.ast.GQLDocument import com.apollographql.apollo3.ast.GQLFragmentDefinition import com.apollographql.apollo3.ast.GQLOperationDefinition -import com.apollographql.apollo3.ast.introspection.toSchema import com.apollographql.apollo3.ast.toExecutableDefinitions +import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.ast.toUtf8 import com.google.common.truth.Truth.assertThat import com.google.testing.junit.testparameterinjector.TestParameter @@ -36,7 +36,7 @@ class TypenameTest( else -> it } }, - filePath = null + sourceLocation = null ).toUtf8() val extra = when(addTypename) { diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/conditionalFragments/ConditionalFragmentsTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/conditionalFragments/ConditionalFragmentsTest.kt index 98e58caa0e1..ff2ec5deb05 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/conditionalFragments/ConditionalFragmentsTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/conditionalFragments/ConditionalFragmentsTest.kt @@ -1,6 +1,6 @@ package com.apollographql.apollo3.compiler.conditionalFragments -import com.apollographql.apollo3.ast.introspection.toSchema +import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.compiler.ApolloCompiler import com.apollographql.apollo3.compiler.MODELS_OPERATION_BASED import com.apollographql.apollo3.compiler.MODELS_RESPONSE_BASED diff --git a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/KeyFieldsTest.kt b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/KeyFieldsTest.kt index 0606969074d..28107ed38cd 100644 --- a/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/KeyFieldsTest.kt +++ b/libraries/apollo-compiler/src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/KeyFieldsTest.kt @@ -2,8 +2,9 @@ package com.apollographql.apollo3.compiler.keyfields import com.apollographql.apollo3.ast.GQLFragmentDefinition import com.apollographql.apollo3.ast.GQLOperationDefinition -import com.apollographql.apollo3.ast.introspection.toSchema import com.apollographql.apollo3.ast.parseAsGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument +import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.ast.validateAsSchema import com.apollographql.apollo3.compiler.addRequiredFields import com.apollographql.apollo3.compiler.checkKeyFields @@ -17,11 +18,13 @@ import kotlin.test.fail class KeyFieldsTest { @Test fun testAddRequiredFields() { - val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/schema.graphqls".toPath().toSchema() + val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/schema.graphqls" + .toPath() + .toGQLDocument() + .toSchema() val definitions = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/operations.graphql".toPath() - .parseAsGQLDocument() - .getOrThrow() + .toGQLDocument() .definitions val fragments = definitions.filterIsInstance().associateBy { it.name } @@ -43,14 +46,19 @@ class KeyFieldsTest { @Test fun testExtendInterfaceTypePolicyDirective() { - val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/extendsSchema.graphqls".toPath().toSchema() - schema.toGQLDocument().validateAsSchema() + val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/extendsSchema.graphqls" + .toPath() + .toGQLDocument() + .toSchema() assertEquals(setOf("id"), schema.keyFields("Node")) } @Test fun testExtendUnionTypePolicyDirective() { - val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/extendsSchema.graphqls".toPath().toSchema() + val schema = "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/extendsSchema.graphqls" + .toPath() + .toGQLDocument() + .toSchema() assertEquals(setOf("x"), schema.keyFields("Foo")) } @@ -58,8 +66,7 @@ class KeyFieldsTest { fun testObjectWithTypePolicyAndInterfaceTypePolicyErrors() { "src/test/kotlin/com/apollographql/apollo3/compiler/keyfields/objectAndInterfaceTypePolicySchema.graphqls" .toPath() - .parseAsGQLDocument() - .getOrThrow() + .toGQLDocument() .validateAsSchema() .issues .first() diff --git a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt index 8c914680ffd..3dc29be9ebc 100644 --- a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt +++ b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/ApolloConvertSchemaTask.kt @@ -3,7 +3,8 @@ package com.apollographql.apollo3.gradle.internal import com.apollographql.apollo3.ast.introspection.toGQLDocument import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema import com.apollographql.apollo3.ast.introspection.writeTo -import com.apollographql.apollo3.ast.introspection.toSchema +import com.apollographql.apollo3.ast.toFullSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toUtf8 import org.gradle.api.DefaultTask import org.gradle.api.provider.Property @@ -47,7 +48,7 @@ abstract class ApolloConvertSchemaTask : DefaultTask() { if (from.isIntrospection()) { from.toIntrospectionSchema().toGQLDocument().toUtf8(to) } else { - from.toSchema().toIntrospectionSchema().writeTo(to) + from.toGQLDocument().toFullSchemaGQLDocument().toIntrospectionSchema().writeTo(to) } } diff --git a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/SchemaExtensions.kt b/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/SchemaExtensions.kt deleted file mode 100644 index 4c233dfb705..00000000000 --- a/libraries/apollo-gradle-plugin-external/src/main/kotlin/com/apollographql/apollo3/gradle/internal/SchemaExtensions.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.apollographql.apollo3.gradle.internal - -import com.apollographql.apollo3.ast.GQLDocument -import com.apollographql.apollo3.ast.Issue -import com.apollographql.apollo3.ast.Schema -import com.apollographql.apollo3.ast.introspection.toSchemaGQLDocument -import com.apollographql.apollo3.ast.pretty -import com.apollographql.apollo3.ast.validateAsSchemaAndAddApolloDefinition -import org.gradle.api.logging.Logger -import java.io.File - -internal fun Iterable.toSchema(logger: Logger): Schema { - return map { - it.toSchemaGQLDocument() - }.flatMap { - it.definitions - }.let { - /** - * TODO: use `validateAsSchema` to not automatically add the apollo definitions - */ - val result = GQLDocument( - definitions = it, - filePath = null - ).validateAsSchemaAndAddApolloDefinition() - - result.issues.filter { it.severity == Issue.Severity.WARNING }.forEach { - // Using this format, IntelliJ will parse the warning and display it in the 'run' panel - logger.warn("w: ${it.sourceLocation.pretty()}: Apollo: ${it.message}") - } - - result.getOrThrow() - } -} diff --git a/libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo3/gradle/test/ConvertSchemaTests.kt b/libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo3/gradle/test/ConvertSchemaTests.kt index 9035ab110ab..2a5da76bcdf 100644 --- a/libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo3/gradle/test/ConvertSchemaTests.kt +++ b/libraries/apollo-gradle-plugin/src/test-java11/kotlin/com/apollographql/apollo3/gradle/test/ConvertSchemaTests.kt @@ -2,10 +2,10 @@ package com.apollographql.apollo3.gradle.test import com.apollographql.apollo3.ast.introspection.normalize import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema -import util.TestUtils import org.gradle.testkit.runner.TaskOutcome import org.junit.Assert import org.junit.Test +import util.TestUtils import java.io.File import org.assertj.core.api.Assertions.assertThat as assertjThat diff --git a/libraries/apollo-gradle-plugin/testProjects/convertSchema/schemas/schema.json b/libraries/apollo-gradle-plugin/testProjects/convertSchema/schemas/schema.json index 045d1a0d9f9..ecc780ce5f1 100644 --- a/libraries/apollo-gradle-plugin/testProjects/convertSchema/schemas/schema.json +++ b/libraries/apollo-gradle-plugin/testProjects/convertSchema/schemas/schema.json @@ -3,682 +3,1135 @@ "queryType": { "name": "Query" }, + "mutationType": null, + "subscriptionType": null, "types": [ { "kind": "OBJECT", "name": "Query", + "description": null, "fields": [ { "name": "greeting", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "INTERFACE", "name": "Foo", + "description": null, "fields": [ { "name": "x", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "Int" - } + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": [], - "possibleTypes": [] + "possibleTypes": [], + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "INTERFACE", "name": "Bar", + "description": null, "fields": [ { "name": "x", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "Int" - } + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "y", - "type": { - "kind": "SCALAR", - "name": "Int" - }, + "description": null, "args": [ { "name": "z", - "isDeprecated": true, - "deprecationReason": "This argument is deprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "Int" - } + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": true, + "deprecationReason": "This argument is deprecated" } - ] + ], + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "z", - "isDeprecated": true, - "deprecationReason": "This field is deprecated", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": true, + "deprecationReason": "This field is deprecated" } ], "interfaces": [ { "kind": "INTERFACE", - "name": "Foo" + "name": "Foo", + "ofType": null } ], - "possibleTypes": [] + "possibleTypes": [], + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "INPUT_OBJECT", "name": "MyInput", + "description": null, + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, "inputFields": [ { "name": "a", + "description": null, "type": { "kind": "SCALAR", - "name": "Int" - } + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null }, { "name": "b", - "isDeprecated": true, - "deprecationReason": "This input field is deprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": true, + "deprecationReason": "This input field is deprecated" } - ] + ], + "specifiedByURL": null }, { "kind": "SCALAR", "name": "Int", - "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1." + "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.", + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "SCALAR", "name": "Float", - "description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)." + "description": "The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).", + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "SCALAR", "name": "String", - "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." + "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "SCALAR", "name": "Boolean", - "description": "The `Boolean` scalar type represents `true` or `false`." + "description": "The `Boolean` scalar type represents `true` or `false`.", + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "SCALAR", "name": "ID", - "description": "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID." + "description": "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID.", + "fields": null, + "interfaces": null, + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__Schema", + "description": null, "fields": [ { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "types", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Type", + "ofType": null } } } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "queryType", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Type", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "mutationType", + "description": null, + "args": [], "type": { "kind": "OBJECT", - "name": "__Type" - } + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "subscriptionType", + "description": null, + "args": [], "type": { "kind": "OBJECT", - "name": "__Type" - } + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "directives", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Directive" + "name": "__Directive", + "ofType": null } } } - } + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__Type", + "description": null, "fields": [ { "name": "kind", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "ENUM", - "name": "__TypeKind" + "name": "__TypeKind", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "name", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "fields", - "type": { - "kind": "LIST", - "ofType": { - "kind": "NON_NULL", - "ofType": { - "kind": "OBJECT", - "name": "__Field" - } - } - }, + "description": null, "args": [ { "name": "includeDeprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null }, - "defaultValue": "false" + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null } - ] - }, - { - "name": "interfaces", + ], "type": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Field", + "ofType": null } } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "possibleTypes", + "name": "interfaces", + "description": null, + "args": [], "type": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Type", + "ofType": null } } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "enumValues", + "name": "possibleTypes", + "description": null, + "args": [], "type": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__EnumValue" + "name": "__Type", + "ofType": null } } }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "enumValues", + "description": null, "args": [ { "name": "includeDeprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null }, - "defaultValue": "false" + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null } - ] - }, - { - "name": "inputFields", + ], "type": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__InputValue" + "name": "__EnumValue", + "ofType": null } } }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "inputFields", + "description": null, "args": [ { "name": "includeDeprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null }, - "defaultValue": "false" + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "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" - } + "name": "__Type", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "specifiedByURL", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "ENUM", "name": "__TypeKind", + "description": null, + "fields": null, + "interfaces": null, + "possibleTypes": null, "enumValues": [ { - "name": "SCALAR" + "name": "SCALAR", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "OBJECT" + "name": "OBJECT", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INTERFACE" + "name": "INTERFACE", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "UNION" + "name": "UNION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "ENUM" + "name": "ENUM", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INPUT_OBJECT" + "name": "INPUT_OBJECT", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "LIST" + "name": "LIST", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "NON_NULL" + "name": "NON_NULL", + "description": null, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__Field", + "description": null, "fields": [ { "name": "name", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "args", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null + } + ], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__InputValue" + "name": "__InputValue", + "ofType": null } } } }, - "args": [ - { - "name": "includeDeprecated", - "type": { - "kind": "SCALAR", - "name": "Boolean" - }, - "defaultValue": "false" - } - ] + "isDeprecated": false, + "deprecationReason": null }, { "name": "type", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Type", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "isDeprecated", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "deprecationReason", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__InputValue", + "description": null, "fields": [ { "name": "name", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "type", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__Type" + "name": "__Type", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "defaultValue", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "isDeprecated", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "deprecationReason", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__EnumValue", + "description": null, "fields": [ { "name": "name", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "isDeprecated", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "deprecationReason", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "OBJECT", "name": "__Directive", + "description": null, "fields": [ { "name": "name", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "description", + "description": null, + "args": [], "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "locations", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "ENUM", - "name": "__DirectiveLocation" + "name": "__DirectiveLocation", + "ofType": null } } } - } + }, + "isDeprecated": false, + "deprecationReason": null }, { "name": "args", + "description": null, + "args": [ + { + "name": "includeDeprecated", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "defaultValue": "false", + "isDeprecated": false, + "deprecationReason": null + } + ], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "LIST", + "name": null, "ofType": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "OBJECT", - "name": "__InputValue" + "name": "__InputValue", + "ofType": null } } } }, - "args": [ - { - "name": "includeDeprecated", - "type": { - "kind": "SCALAR", - "name": "Boolean" - }, - "defaultValue": "false" - } - ] + "isDeprecated": false, + "deprecationReason": null }, { "name": "isRepeatable", + "description": null, + "args": [], "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "interfaces": [], + "possibleTypes": null, + "enumValues": null, + "inputFields": null, + "specifiedByURL": null }, { "kind": "ENUM", "name": "__DirectiveLocation", + "description": null, + "fields": null, + "interfaces": null, + "possibleTypes": null, "enumValues": [ { - "name": "QUERY" + "name": "QUERY", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "MUTATION" + "name": "MUTATION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "SUBSCRIPTION" + "name": "SUBSCRIPTION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "FIELD" + "name": "FIELD", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "FRAGMENT_DEFINITION" + "name": "FRAGMENT_DEFINITION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "FRAGMENT_SPREAD" + "name": "FRAGMENT_SPREAD", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INLINE_FRAGMENT" + "name": "INLINE_FRAGMENT", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "VARIABLE_DEFINITION" + "name": "VARIABLE_DEFINITION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "SCHEMA" + "name": "SCHEMA", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "SCALAR" + "name": "SCALAR", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "OBJECT" + "name": "OBJECT", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "FIELD_DEFINITION" + "name": "FIELD_DEFINITION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "ARGUMENT_DEFINITION" + "name": "ARGUMENT_DEFINITION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INTERFACE" + "name": "INTERFACE", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "UNION" + "name": "UNION", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "ENUM" + "name": "ENUM", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "ENUM_VALUE" + "name": "ENUM_VALUE", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INPUT_OBJECT" + "name": "INPUT_OBJECT", + "description": null, + "isDeprecated": false, + "deprecationReason": null }, { - "name": "INPUT_FIELD_DEFINITION" + "name": "INPUT_FIELD_DEFINITION", + "description": null, + "isDeprecated": false, + "deprecationReason": null } - ] + ], + "inputFields": null, + "specifiedByURL": null } ], "directives": [ { "name": "MyDirective1", + "description": null, "locations": [ "FIELD_DEFINITION", "SCALAR" @@ -686,25 +1139,34 @@ "args": [ { "name": "a", + "description": null, "type": { "kind": "SCALAR", - "name": "Int" - } + "name": "Int", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null }, { "name": "b", - "isDeprecated": true, - "deprecationReason": "This argument is deprecated", + "description": null, "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": true, + "deprecationReason": "This argument is deprecated" } ], "isRepeatable": false }, { "name": "skip", + "description": null, "locations": [ "FIELD", "FRAGMENT_SPREAD", @@ -713,19 +1175,26 @@ "args": [ { "name": "if", + "description": null, "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "isRepeatable": false }, { "name": "include", + "description": null, "locations": [ "FIELD", "FRAGMENT_SPREAD", @@ -734,19 +1203,26 @@ "args": [ { "name": "if", + "description": null, "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } - } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "isRepeatable": false }, { "name": "deprecated", + "description": null, "locations": [ "FIELD_DEFINITION", "ARGUMENT_DEFINITION", @@ -756,17 +1232,22 @@ "args": [ { "name": "reason", + "description": null, "type": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null }, - "defaultValue": "\"No longer supported\"" + "defaultValue": "\"No longer supported\"", + "isDeprecated": false, + "deprecationReason": null } ], "isRepeatable": false }, { "name": "defer", + "description": null, "locations": [ "FRAGMENT_SPREAD", "INLINE_FRAGMENT" @@ -774,44 +1255,62 @@ "args": [ { "name": "label", + "description": null, "type": { "kind": "SCALAR", - "name": "String" - } + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null }, { "name": "if", + "description": null, "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean" + "name": "Boolean", + "ofType": null } }, - "defaultValue": "true" + "defaultValue": "true", + "isDeprecated": false, + "deprecationReason": null } ], "isRepeatable": false }, { "name": "specifiedBy", + "description": null, "locations": [ "SCALAR" ], "args": [ { "name": "url", + "description": null, "type": { "kind": "NON_NULL", + "name": null, "ofType": { "kind": "SCALAR", - "name": "String" + "name": "String", + "ofType": null } - } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "isRepeatable": false } - ] + ], + "description": null } -} +} \ No newline at end of file diff --git a/libraries/apollo-tooling/src/main/graphql/graphql/july2015/README.md b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/README.md new file mode 100644 index 00000000000..447ca2b6a32 --- /dev/null +++ b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/README.md @@ -0,0 +1 @@ +We do not support this version, this is only here for informative purposes \ No newline at end of file diff --git a/libraries/apollo-tooling/src/main/graphql/graphql/july2015/operations.graphql b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/operations.graphql new file mode 100644 index 00000000000..a5182fd48c7 --- /dev/null +++ b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/operations.graphql @@ -0,0 +1,89 @@ +query IntrospectionQuery { + __schema { + queryType { name } + mutationType { name } + types { + ...FullType + } + directives { + name + description + onOperation + onFragment + onField + } + } +} + +fragment FullType on __Type { + kind + name + description + fields(includeDeprecated: true) { + name + description + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields{ + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + description + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } +} + +fragment InputValue on __InputValue { + name + description + type { ...TypeRef } + defaultValue +} + +fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + } + } + } + } +} diff --git a/libraries/apollo-tooling/src/main/graphql/graphql/july2015/schema.graphqls b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/schema.graphqls new file mode 100644 index 00000000000..07d2b7d026d --- /dev/null +++ b/libraries/apollo-tooling/src/main/graphql/graphql/july2015/schema.graphqls @@ -0,0 +1,80 @@ +# Draft spec as of 2015-07 + +type Query { + __schema: __Schema! + __type(name: String): __Type +} + +type __Schema { + types: [__Type!]! + queryType: __Type! + mutationType: __Type + directives: [__Directive!]! +} + +type __Type { + kind: __TypeKind! + name: String + description: String + + # OBJECT and INTERFACE only + fields(includeDeprecated: Boolean = false): [__Field!] + + # OBJECT only + interfaces: [__Type!] + + # INTERFACE and UNION only + possibleTypes: [__Type!] + + # ENUM only + enumValues(includeDeprecated: Boolean = false): [__EnumValue!] + + # INPUT_OBJECT only + inputFields: [__InputValue!] + + # NON_NULL and LIST only + ofType: __Type +} + +type __Field { + name: String! + description: String + args: [__InputValue!]! + type: __Type! + isDeprecated: Boolean! + deprecationReason: String +} + +type __InputValue { + name: String! + description: String + type: __Type! + defaultValue: String +} + +type __EnumValue { + name: String! + description: String + isDeprecated: Boolean! + deprecationReason: String +} + +enum __TypeKind { + SCALAR + OBJECT + INTERFACE + UNION + ENUM + INPUT_OBJECT + LIST + NON_NULL +} + +type __Directive { + name: String! + description: String + type: __Type + onOperation: Boolean! + onFragment: Boolean! + onField: Boolean! +} \ No newline at end of file diff --git a/libraries/apollo-tooling/src/main/graphql/graphql/october2021/operations.graphql b/libraries/apollo-tooling/src/main/graphql/graphql/october2021/operations.graphql index 23c5c2488ae..68deba8d570 100644 --- a/libraries/apollo-tooling/src/main/graphql/graphql/october2021/operations.graphql +++ b/libraries/apollo-tooling/src/main/graphql/graphql/october2021/operations.graphql @@ -34,7 +34,7 @@ fragment FullType on __Type { isDeprecated deprecationReason } - inputFields{ + inputFields { ...InputValue } interfaces { diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt index 6f5c248dc10..f08f5d54d7a 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt @@ -7,8 +7,9 @@ import com.apollographql.apollo3.ast.introspection.IntrospectionSchema import com.apollographql.apollo3.ast.introspection.toGQLDocument import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema import com.apollographql.apollo3.ast.introspection.writeTo +import com.apollographql.apollo3.ast.toFullSchemaGQLDocument +import com.apollographql.apollo3.ast.toGQLDocument import com.apollographql.apollo3.ast.toSDL -import com.apollographql.apollo3.ast.toSchema import com.apollographql.apollo3.exception.ApolloGraphQLException import com.apollographql.apollo3.network.okHttpClient import com.apollographql.apollo3.tooling.platformapi.public.DownloadSchemaQuery @@ -65,7 +66,7 @@ object SchemaDownloader { insecure: Boolean = false, headers: Map = emptyMap(), ) { - var introspectionSchemaJson: String? = null + var introspectionDataJson: String? = null var introspectionSchema: IntrospectionSchema? = null var sdlSchema: String? = null @@ -75,21 +76,20 @@ object SchemaDownloader { // Try the latest spec first for (specVersion in SpecVersion.values().reversed()) { try { - introspectionSchemaJson = downloadIntrospection( + introspectionDataJson = downloadIntrospection( endpoint = endpoint, headers = headers, insecure = insecure, specVersion = specVersion, ) - // Validates the JSON schema - introspectionSchema = introspectionSchemaJson.toIntrospectionSchema() + introspectionSchema = introspectionDataJson.toIntrospectionSchema() exception = null break } catch (e: Exception) { exception = e } } - if (introspectionSchemaJson == null) { + if (introspectionDataJson == null) { throw exception!! } } @@ -121,13 +121,14 @@ object SchemaDownloader { check(sdlSchema != null) // Convert from SDL to JSON sdlSchema - .toSchema() + .toGQLDocument() + .toFullSchemaGQLDocument() .toIntrospectionSchema() .writeTo(schema) } else { - check(introspectionSchemaJson != null) + check(introspectionDataJson != null) // Copy Json verbatim - schema.writeText(introspectionSchemaJson) + schema.writeText(introspectionDataJson) } } else { if (sdlSchema == null) {