From 7b8cd1bce34ce543781376f42062bc7234e8d8d1 Mon Sep 17 00:00:00 2001
From: Richard Musiol <mail@richard-musiol.de>
Date: Fri, 21 Oct 2016 15:48:32 +0200
Subject: [PATCH] meta schema from graphql-js

---
 internal/exec/introspection.go | 175 ++++++++++++++++++++++++---------
 1 file changed, 126 insertions(+), 49 deletions(-)

diff --git a/internal/exec/introspection.go b/internal/exec/introspection.go
index 1095aff7f3..54546e9b8c 100644
--- a/internal/exec/introspection.go
+++ b/internal/exec/introspection.go
@@ -54,37 +54,72 @@ func introspectType(r *request, name string, selSet *query.SelectionSet) interfa
 }
 
 var metaSchemaSrc = `
-	type __Schema {
-		types: [__Type!]!
-		queryType: __Type!
-		mutationType: __Type
-		directives: [__Directive!]!
-	}
-
-	type __Type {
-		kind: __TypeKind!
-		name: String
+	# A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
+	#
+	# In some cases, you need to provide options to alter GraphQL's execution behavior
+	# in ways field arguments will not suffice, such as conditionally including or
+	# skipping a field. Directives provide this by describing additional information
+	# to the executor.
+	type __Directive {
+		name: String!
 		description: String
+		locations: [__DirectiveLocation!]!
+		args: [__InputValue!]!
+	}
 
-		# 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!]
+	# A Directive can be adjacent to many parts of the GraphQL language, a
+	# __DirectiveLocation describes one such possible adjacencies.
+	enum __DirectiveLocation {
+		# Location adjacent to a query operation.
+		QUERY
+		# Location adjacent to a mutation operation.
+		MUTATION
+		# Location adjacent to a subscription operation.
+		SUBSCRIPTION
+		# Location adjacent to a field.
+		FIELD
+		# Location adjacent to a fragment definition.
+		FRAGMENT_DEFINITION
+		# Location adjacent to a fragment spread.
+		FRAGMENT_SPREAD
+		# Location adjacent to an inline fragment.
+		INLINE_FRAGMENT
+		# Location adjacent to a schema definition.
+		SCHEMA
+		# Location adjacent to a scalar definition.
+		SCALAR
+		# Location adjacent to an object type definition.
+		OBJECT
+		# Location adjacent to a field definition.
+		FIELD_DEFINITION
+		# Location adjacent to an argument definition.
+		ARGUMENT_DEFINITION
+		# Location adjacent to an interface definition.
+		INTERFACE
+		# Location adjacent to a union definition.
+		UNION
+		# Location adjacent to an enum definition.
+		ENUM
+		# Location adjacent to an enum value definition.
+		ENUM_VALUE
+		# Location adjacent to an input object type definition.
+		INPUT_OBJECT
+		# Location adjacent to an input object field definition.
+		INPUT_FIELD_DEFINITION
+	}
 
-		# NON_NULL and LIST only
-		ofType: __Type
+	# One possible value for a given Enum. Enum values are unique values, not a
+	# placeholder for a string or numeric value. However an Enum value is returned in
+	# a JSON response as a string.
+	type __EnumValue {
+		name: String!
+		description: String
+		isDeprecated: Boolean!
+		deprecationReason: String
 	}
 
+	# Object and Interface types are described by a list of Fields, each of which has
+	# a name, potentially a list of arguments, and a return type.
 	type __Field {
 		name: String!
 		description: String
@@ -94,46 +129,72 @@ var metaSchemaSrc = `
 		deprecationReason: String
 	}
 
+	# Arguments provided to Fields or Directives and the input fields of an
+	# InputObject are represented as Input Values which describe their type and
+	# optionally a default value.
 	type __InputValue {
 		name: String!
 		description: String
 		type: __Type!
+		# A GraphQL-formatted string representing the default value for this input value.
 		defaultValue: String
 	}
 
-	type __EnumValue {
-		name: String!
-		description: String
-		isDeprecated: Boolean!
-		deprecationReason: String
+	# A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all
+	# available types and directives on the server, as well as the entry points for
+	# query, mutation, and subscription operations.
+	type __Schema {
+		# 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
+		# If this server support subscription, the type that subscription operations will be rooted at.
+		subscriptionType: __Type
+		# A list of all directives supported by this server.
+		directives: [__Directive!]!
 	}
 
+	# The fundamental unit of any GraphQL Schema is the type. There are many kinds of
+	# types in GraphQL as represented by the ` + "`" + `__TypeKind` + "`" + ` enum.
+	#
+	# Depending on the kind of a type, certain fields describe information about that
+	# type. Scalar types provide no information beyond a name and description, while
+	# Enum types provide their values. Object and Interface types provide the fields
+	# they describe. Abstract types, Union and Interface, provide the Object types
+	# possible at runtime. List and NonNull types compose other types.
+	type __Type {
+		kind: __TypeKind!
+		name: String
+		description: String
+		fields(includeDeprecated: Boolean = false): [__Field!]
+		interfaces: [__Type!]
+		possibleTypes: [__Type!]
+		enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
+		inputFields: [__InputValue!]
+		ofType: __Type
+	}
+	
+	# An enum describing what kind of type a given ` + "`" + `__Type` + "`" + ` is.
 	enum __TypeKind {
+		# Indicates this type is a scalar.
 		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
 	}
-
-	type __Directive {
-		name: String!
-		description: String
-		locations: [__DirectiveLocation!]!
-		args: [__InputValue!]!
-	}
-
-	enum __DirectiveLocation {
-		QUERY
-		MUTATION
-		FIELD
-		FRAGMENT_DEFINITION
-		FRAGMENT_SPREAD
-		INLINE_FRAGMENT
-	}
 `
 
 type schemaResolver struct {
@@ -160,11 +221,27 @@ func (r *schemaResolver) Types() []*typeResolver {
 }
 
 func (r *schemaResolver) QueryType() *typeResolver {
-	return &typeResolver{typ: r.schema.Types[r.schema.EntryPoints["query"]]}
+	t, ok := r.schema.Types[r.schema.EntryPoints["query"]]
+	if !ok {
+		return nil
+	}
+	return &typeResolver{typ: t}
 }
 
 func (r *schemaResolver) MutationType() *typeResolver {
-	return &typeResolver{typ: r.schema.Types[r.schema.EntryPoints["mutation"]]}
+	t, ok := r.schema.Types[r.schema.EntryPoints["mutation"]]
+	if !ok {
+		return nil
+	}
+	return &typeResolver{typ: t}
+}
+
+func (r *schemaResolver) SubscriptionType() *typeResolver {
+	t, ok := r.schema.Types[r.schema.EntryPoints["subscription"]]
+	if !ok {
+		return nil
+	}
+	return &typeResolver{typ: t}
 }
 
 func (r *schemaResolver) Directives() []*directiveResolver {