upgrade to gqlgen master, waiting for a release

Michael Muré created

Change summary

commands/webui.go             |    4 
go.mod                        |    6 
go.sum                        |   20 
graphql/graph/gen_graph.go    | 1494 +++++++++++++++++++++---------------
graphql/graphql_test.go       |    4 
graphql/handler.go            |    7 
graphql/resolvers/identity.go |   39 
7 files changed, 895 insertions(+), 679 deletions(-)

Detailed changes

commands/webui.go 🔗

@@ -12,7 +12,7 @@ import (
 	"os/signal"
 	"time"
 
-	"github.com/99designs/gqlgen/handler"
+	"github.com/99designs/gqlgen/graphql/playground"
 	"github.com/gorilla/mux"
 	"github.com/phayes/freeport"
 	"github.com/skratchdot/open-golang/open"
@@ -57,7 +57,7 @@ func runWebUI(cmd *cobra.Command, args []string) error {
 	}
 
 	// Routes
-	router.Path("/playground").Handler(handler.Playground("git-bug", "/graphql"))
+	router.Path("/playground").Handler(playground.Handler("git-bug", "/graphql"))
 	router.Path("/graphql").Handler(graphqlHandler)
 	router.Path("/gitfile/{hash}").Handler(newGitFileHandler(repo))
 	router.Path("/upload").Methods("POST").Handler(newGitUploadFileHandler(repo))

go.mod 🔗

@@ -3,7 +3,7 @@ module github.com/MichaelMure/git-bug
 go 1.10
 
 require (
-	github.com/99designs/gqlgen v0.9.2
+	github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6
 	github.com/MichaelMure/go-term-text v0.2.4
 	github.com/araddon/dateparse v0.0.0-20190622164848-0fb0a474d195
 	github.com/awesome-gocui/gocui v0.6.1-0.20191115151952-a34ffb055986
@@ -26,9 +26,9 @@ require (
 	github.com/spf13/cobra v0.0.5
 	github.com/stretchr/testify v1.4.0
 	github.com/theckman/goconstraint v1.11.0
-	github.com/vektah/gqlparser v1.1.2
+	github.com/vektah/gqlparser v1.2.1
 	github.com/xanzy/go-gitlab v0.22.1
-	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
+	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
 	golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
 	golang.org/x/sync v0.0.0-20190423024810-112230192c58
 	golang.org/x/text v0.3.0

go.sum 🔗

@@ -1,5 +1,5 @@
-github.com/99designs/gqlgen v0.9.2 h1:sYL+xoM+PeMyh7RWwikT+1G+6GVtFur5ZJ1V73ra1w4=
-github.com/99designs/gqlgen v0.9.2/go.mod h1:HrrG7ic9EgLPsULxsZh/Ti+p0HNWgR3XRuvnD0pb5KY=
+github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6 h1:WU+9Z7AoCyl+HlB2kE0O+4/3BaVqLQfnX5dHigV5p8A=
+github.com/99designs/gqlgen v0.10.3-0.20200205113530-b941b970f0b6/go.mod h1:28v/ATDVwPUriwNtAIrQEhRHXJjdi5dVGqxSqPna1I8=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
 github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
@@ -66,6 +66,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
 github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
@@ -119,18 +120,24 @@ github.com/theckman/goconstraint v1.11.0/go.mod h1:zkCR/f2kOULTk/h1ujgyB9BlCNLaq
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
-github.com/vektah/gqlparser v1.1.2 h1:ZsyLGn7/7jDNI+y4SEhI4yAxRChlv15pUHMjijT+e68=
-github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
+github.com/vektah/gqlparser v1.2.1 h1:C+L7Go/eUbN0w6Y0kaiq2W6p2wN5j8wU82EdDXxDivc=
+github.com/vektah/gqlparser v1.2.1/go.mod h1:bkVf0FX+Stjg/MHnm8mEyubuaArhNEqfQhF+OTiAL74=
 github.com/xanzy/go-gitlab v0.22.1 h1:TVxgHmoa35jQL+9FCkG0nwPDxU9dQZXknBTDtGaSFno=
 github.com/xanzy/go-gitlab v0.22.1/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
 golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -141,10 +148,15 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
+golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

graphql/graph/gen_graph.go 🔗

@@ -204,7 +204,7 @@ type ComplexityRoot struct {
 	}
 
 	Identity struct {
-		AvatarURL   func(childComplexity int) int
+		AvatarUrl   func(childComplexity int) int
 		DisplayName func(childComplexity int) int
 		Email       func(childComplexity int) int
 		HumanID     func(childComplexity int) int
@@ -418,14 +418,8 @@ type EditCommentOperationResolver interface {
 	Target(ctx context.Context, obj *bug.EditCommentOperation) (string, error)
 }
 type IdentityResolver interface {
-	ID(ctx context.Context, obj *identity.Interface) (string, error)
-	HumanID(ctx context.Context, obj *identity.Interface) (string, error)
-	Name(ctx context.Context, obj *identity.Interface) (*string, error)
-	Email(ctx context.Context, obj *identity.Interface) (*string, error)
-	Login(ctx context.Context, obj *identity.Interface) (*string, error)
-	DisplayName(ctx context.Context, obj *identity.Interface) (string, error)
-	AvatarURL(ctx context.Context, obj *identity.Interface) (*string, error)
-	IsProtected(ctx context.Context, obj *identity.Interface) (bool, error)
+	ID(ctx context.Context, obj identity.Interface) (string, error)
+	HumanID(ctx context.Context, obj identity.Interface) (string, error)
 }
 type LabelResolver interface {
 	Name(ctx context.Context, obj *bug.Label) (string, error)
@@ -1104,11 +1098,11 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 		return e.complexity.EditCommentOperation.Target(childComplexity), true
 
 	case "Identity.avatarUrl":
-		if e.complexity.Identity.AvatarURL == nil {
+		if e.complexity.Identity.AvatarUrl == nil {
 			break
 		}
 
-		return e.complexity.Identity.AvatarURL(childComplexity), true
+		return e.complexity.Identity.AvatarUrl(childComplexity), true
 
 	case "Identity.displayName":
 		if e.complexity.Identity.DisplayName == nil {
@@ -1828,46 +1822,48 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
 	return 0, false
 }
 
-func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
-	ec := executionContext{graphql.GetRequestContext(ctx), e}
+func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
+	rc := graphql.GetOperationContext(ctx)
+	ec := executionContext{rc, e}
+	first := true
 
-	buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
-		data := ec._Query(ctx, op.SelectionSet)
-		var buf bytes.Buffer
-		data.MarshalGQL(&buf)
-		return buf.Bytes()
-	})
-
-	return &graphql.Response{
-		Data:       buf,
-		Errors:     ec.Errors,
-		Extensions: ec.Extensions,
-	}
-}
+	switch rc.Operation.Operation {
+	case ast.Query:
+		return func(ctx context.Context) *graphql.Response {
+			if !first {
+				return nil
+			}
+			first = false
+			data := ec._Query(ctx, rc.Operation.SelectionSet)
+			var buf bytes.Buffer
+			data.MarshalGQL(&buf)
 
-func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
-	ec := executionContext{graphql.GetRequestContext(ctx), e}
+			return &graphql.Response{
+				Data: buf.Bytes(),
+			}
+		}
+	case ast.Mutation:
+		return func(ctx context.Context) *graphql.Response {
+			if !first {
+				return nil
+			}
+			first = false
+			data := ec._Mutation(ctx, rc.Operation.SelectionSet)
+			var buf bytes.Buffer
+			data.MarshalGQL(&buf)
 
-	buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
-		data := ec._Mutation(ctx, op.SelectionSet)
-		var buf bytes.Buffer
-		data.MarshalGQL(&buf)
-		return buf.Bytes()
-	})
+			return &graphql.Response{
+				Data: buf.Bytes(),
+			}
+		}
 
-	return &graphql.Response{
-		Data:       buf,
-		Errors:     ec.Errors,
-		Extensions: ec.Extensions,
+	default:
+		return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
 	}
 }
 
-func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
-	return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported"))
-}
-
 type executionContext struct {
-	*graphql.RequestContext
+	*graphql.OperationContext
 	*executableSchema
 }
 
@@ -1886,637 +1882,877 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er
 }
 
 var parsedSchema = gqlparser.MustLoadSchema(
-	&ast.Source{Name: "schema/bug.graphql", Input: `"""Represents a comment on a bug."""
-type Comment implements Authored {
-  """The author of this comment."""
-  author: Identity!
-
-  """The message of this comment."""
-  message: String!
-
-  """All media's hash referenced in this comment"""
-  files: [Hash!]!
-}
-
-type CommentConnection {
-  edges: [CommentEdge!]!
-  nodes: [Comment!]!
-  pageInfo: PageInfo!
-  totalCount: Int!
+	&ast.Source{Name: "schema.graphql", Input: `input AddCommentInput {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
+	"""
+	The first message of the new bug.
+	"""
+	message: String!
+	"""
+	The collection of file's hash required for the first message.
+	"""
+	files: [Hash!]
 }
-
-type CommentEdge {
-  cursor: String!
-  node: Comment!
+type AddCommentOperation implements Operation & Authored {
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	message: String!
+	files: [Hash!]!
 }
-
-enum Status {
-  OPEN
-  CLOSED
+type AddCommentPayload {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation.
+	"""
+	operation: AddCommentOperation!
+}
+"""
+AddCommentTimelineItem is a TimelineItem that represent a Comment and its edition history
+"""
+type AddCommentTimelineItem implements TimelineItem & Authored {
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+	author: Identity!
+	message: String!
+	messageIsEmpty: Boolean!
+	files: [Hash!]!
+	createdAt: Time!
+	lastEdit: Time!
+	edited: Boolean!
+	history: [CommentHistoryStep!]!
+}
+"""
+An object that has an author.
+"""
+interface Authored {
+	"""
+	The author of this object.
+	"""
+	author: Identity!
 }
-
 type Bug implements Authored {
-  """The identifier for this bug"""
-  id: String!
-  """The human version (truncated) identifier for this bug"""
-  humanId: String!
-  status: Status!
-  title: String!
-  labels: [Label!]!
-  author: Identity!
-  createdAt: Time!
-  lastEdit: Time!
-
-  """The actors of the bug. Actors are Identity that have interacted with the bug."""
-  actors(
-    """Returns the elements in the list that come after the specified cursor."""
-    after: String
-    """Returns the elements in the list that come before the specified cursor."""
-    before: String
-    """Returns the first _n_ elements from the list."""
-    first: Int
-    """Returns the last _n_ elements from the list."""
-    last: Int
-  ): IdentityConnection!
-
-  """The participants of the bug. Participants are Identity that have created or
-  added a comment on the bug."""
-  participants(
-    """Returns the elements in the list that come after the specified cursor."""
-    after: String
-    """Returns the elements in the list that come before the specified cursor."""
-    before: String
-    """Returns the first _n_ elements from the list."""
-    first: Int
-    """Returns the last _n_ elements from the list."""
-    last: Int
-  ): IdentityConnection!
-
-  comments(
-    """Returns the elements in the list that come after the specified cursor."""
-    after: String
-    """Returns the elements in the list that come before the specified cursor."""
-    before: String
-    """Returns the first _n_ elements from the list."""
-    first: Int
-    """Returns the last _n_ elements from the list."""
-    last: Int
-  ): CommentConnection!
-
-  timeline(
-    """Returns the elements in the list that come after the specified cursor."""
-    after: String
-    """Returns the elements in the list that come before the specified cursor."""
-    before: String
-    """Returns the first _n_ elements from the list."""
-    first: Int
-    """Returns the last _n_ elements from the list."""
-    last: Int
-  ): TimelineItemConnection!
-
-  operations(
-    """Returns the elements in the list that come after the specified cursor."""
-    after: String
-    """Returns the elements in the list that come before the specified cursor."""
-    before: String
-    """Returns the first _n_ elements from the list."""
-    first: Int
-    """Returns the last _n_ elements from the list."""
-    last: Int
-  ): OperationConnection!
-}
-
-"""The connection type for Bug."""
+	"""
+	The identifier for this bug
+	"""
+	id: String!
+	"""
+	The human version (truncated) identifier for this bug
+	"""
+	humanId: String!
+	status: Status!
+	title: String!
+	labels: [Label!]!
+	author: Identity!
+	createdAt: Time!
+	lastEdit: Time!
+	"""
+	The actors of the bug. Actors are Identity that have interacted with the bug.
+	"""
+	actors("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): IdentityConnection!
+	"""
+	The participants of the bug. Participants are Identity that have created or
+	  added a comment on the bug.
+	"""
+	participants("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): IdentityConnection!
+	comments("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): CommentConnection!
+	timeline("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): TimelineItemConnection!
+	operations("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): OperationConnection!
+}
+"""
+The connection type for Bug.
+"""
 type BugConnection {
-  """A list of edges."""
-  edges: [BugEdge!]!
-  nodes: [Bug!]!
-  """Information to aid in pagination."""
-  pageInfo: PageInfo!
-  """Identifies the total count of items in the connection."""
-  totalCount: Int!
-}
-
-"""An edge in a connection."""
+	"""
+	A list of edges.
+	"""
+	edges: [BugEdge!]!
+	nodes: [Bug!]!
+	"""
+	Information to aid in pagination.
+	"""
+	pageInfo: PageInfo!
+	"""
+	Identifies the total count of items in the connection.
+	"""
+	totalCount: Int!
+}
+"""
+An edge in a connection.
+"""
 type BugEdge {
-  """A cursor for use in pagination."""
-  cursor: String!
-  """The item at the end of the edge."""
-  node: Bug!
-}
-`},
-	&ast.Source{Name: "schema/identity.graphql", Input: `"""Represents an identity"""
-type Identity {
-    """The identifier for this identity"""
-    id: String!
-    """The human version (truncated) identifier for this identity"""
-    humanId: String!
-    """The name of the person, if known."""
-    name: String
-    """The email of the person, if known."""
-    email: String
-    """The login of the person, if known."""
-    login: String
-    """A string containing the either the name of the person, its login or both"""
-    displayName: String!
-    """An url to an avatar"""
-    avatarUrl: String
-    """isProtected is true if the chain of git commits started to be signed.
-    If that's the case, only signed commit with a valid key for this identity can be added."""
-    isProtected: Boolean!
-}
-
-type IdentityConnection {
-    edges: [IdentityEdge!]!
-    nodes: [Identity!]!
-    pageInfo: PageInfo!
-    totalCount: Int!
-}
-
-type IdentityEdge {
-    cursor: String!
-    node: Identity!
-}`},
-	&ast.Source{Name: "schema/label.graphql", Input: `"""Label for a bug."""
-type Label {
-    """The name of the label."""
-    name: String!
-    """Color of the label."""
-    color: Color!
-}
-
-type LabelConnection {
-    edges: [LabelEdge!]!
-    nodes: [Label!]!
-    pageInfo: PageInfo!
-    totalCount: Int!
-}
-
-type LabelEdge {
-    cursor: String!
-    node: Label!
-}`},
-	&ast.Source{Name: "schema/mutations.graphql", Input: `input NewBugInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The title of the new bug."""
-    title: String!
-    """The first message of the new bug."""
-    message: String!
-    """The collection of file's hash required for the first message."""
-    files: [Hash!]
-}
-
-type NewBugPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The created bug."""
-    bug: Bug!
-    """The resulting operation."""
-    operation: CreateOperation!
-}
-
-input AddCommentInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
-    """The first message of the new bug."""
-    message: String!
-    """The collection of file's hash required for the first message."""
-    files: [Hash!]
-}
-
-type AddCommentPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-    """The resulting operation."""
-    operation: AddCommentOperation!
+	"""
+	A cursor for use in pagination.
+	"""
+	cursor: String!
+	"""
+	The item at the end of the edge.
+	"""
+	node: Bug!
 }
-
 input ChangeLabelInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
-    """The list of label to add."""
-    added: [String!]
-    """The list of label to remove."""
-    Removed: [String!]
-}
-
-enum LabelChangeStatus {
-    ADDED
-    REMOVED
-    DUPLICATE_IN_OP
-    ALREADY_EXIST
-    DOESNT_EXIST
-}
-
-type LabelChangeResult {
-    """The source label."""
-    label: Label!
-    """The effect this label had."""
-    status: LabelChangeStatus!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
+	"""
+	The list of label to add.
+	"""
+	added: [String!]
+	"""
+	The list of label to remove.
+	"""
+	Removed: [String!]
 }
-
 type ChangeLabelPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-    """The resulting operation."""
-    operation: LabelChangeOperation!
-    """The effect each source label had."""
-    results: [LabelChangeResult]!
-}
-
-input OpenBugInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation.
+	"""
+	operation: LabelChangeOperation!
+	"""
+	The effect each source label had.
+	"""
+	results: [LabelChangeResult]!
 }
-
-type OpenBugPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-    """The resulting operation."""
-    operation: SetStatusOperation!
-}
-
 input CloseBugInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
 }
-
 type CloseBugPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-    """The resulting operation."""
-    operation: SetStatusOperation!
-}
-
-input SetTitleInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
-    """The new title."""
-    title: String!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation.
+	"""
+	operation: SetStatusOperation!
+}
+"""
+Defines a color by red, green and blue components.
+"""
+type Color {
+	"""
+	Red component of the color.
+	"""
+	R: Int!
+	"""
+	Green component of the color.
+	"""
+	G: Int!
+	"""
+	Blue component of the color.
+	"""
+	B: Int!
+}
+"""
+Represents a comment on a bug.
+"""
+type Comment implements Authored {
+	"""
+	The author of this comment.
+	"""
+	author: Identity!
+	"""
+	The message of this comment.
+	"""
+	message: String!
+	"""
+	All media's hash referenced in this comment
+	"""
+	files: [Hash!]!
 }
-
-type SetTitlePayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-    """The resulting operation"""
-    operation: SetTitleOperation!
+type CommentConnection {
+	edges: [CommentEdge!]!
+	nodes: [Comment!]!
+	pageInfo: PageInfo!
+	totalCount: Int!
 }
-
-input CommitInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
+type CommentEdge {
+	cursor: String!
+	node: Comment!
 }
-
-type CommitPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
+"""
+CommentHistoryStep hold one version of a message in the history
+"""
+type CommentHistoryStep {
+	message: String!
+	date: Time!
 }
-
 input CommitAsNeededInput {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """"The name of the repository. If not set, the default repository is used."""
-    repoRef: String
-    """The bug ID's prefix."""
-    prefix: String!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
 }
-
 type CommitAsNeededPayload {
-    """A unique identifier for the client performing the mutation."""
-    clientMutationId: String
-    """The affected bug."""
-    bug: Bug!
-}
-`},
-	&ast.Source{Name: "schema/operations.graphql", Input: `"""An operation applied to a bug."""
-interface Operation {
-    """The identifier of the operation"""
-    id: String!
-    """The operations author."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
 }
-
-# Connection
-
-"""The connection type for an Operation"""
-type OperationConnection {
-    edges: [OperationEdge!]!
-    nodes: [Operation!]!
-    pageInfo: PageInfo!
-    totalCount: Int!
+input CommitInput {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
 }
-
-"""Represent an Operation"""
-type OperationEdge {
-    cursor: String!
-    node: Operation!
+type CommitPayload {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
 }
-
-# Operations
-
 type CreateOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    title: String!
-    message: String!
-    files: [Hash!]!
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	title: String!
+	message: String!
+	files: [Hash!]!
+}
+"""
+CreateTimelineItem is a TimelineItem that represent the creation of a bug and its message edition history
+"""
+type CreateTimelineItem implements TimelineItem & Authored {
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+	author: Identity!
+	message: String!
+	messageIsEmpty: Boolean!
+	files: [Hash!]!
+	createdAt: Time!
+	lastEdit: Time!
+	edited: Boolean!
+	history: [CommentHistoryStep!]!
 }
-
-type SetTitleOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    title: String!
-    was: String!
+type EditCommentOperation implements Operation & Authored {
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	target: String!
+	message: String!
+	files: [Hash!]!
 }
-
-type AddCommentOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    message: String!
-    files: [Hash!]!
+scalar Hash
+"""
+Represents an identity
+"""
+type Identity {
+	"""
+	The identifier for this identity
+	"""
+	id: String!
+	"""
+	The human version (truncated) identifier for this identity
+	"""
+	humanId: String!
+	"""
+	The name of the person, if known.
+	"""
+	name: String
+	"""
+	The email of the person, if known.
+	"""
+	email: String
+	"""
+	The login of the person, if known.
+	"""
+	login: String
+	"""
+	A string containing the either the name of the person, its login or both
+	"""
+	displayName: String!
+	"""
+	An url to an avatar
+	"""
+	avatarUrl: String
+	"""
+	isProtected is true if the chain of git commits started to be signed.
+	    If that's the case, only signed commit with a valid key for this identity can be added.
+	"""
+	isProtected: Boolean!
 }
-
-type EditCommentOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    target: String!
-    message: String!
-    files: [Hash!]!
+type IdentityConnection {
+	edges: [IdentityEdge!]!
+	nodes: [Identity!]!
+	pageInfo: PageInfo!
+	totalCount: Int!
 }
-
-type SetStatusOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    status: Status!
+type IdentityEdge {
+	cursor: String!
+	node: Identity!
+}
+"""
+Label for a bug.
+"""
+type Label {
+	"""
+	The name of the label.
+	"""
+	name: String!
+	"""
+	Color of the label.
+	"""
+	color: Color!
 }
-
 type LabelChangeOperation implements Operation & Authored {
-    """The identifier of the operation"""
-    id: String!
-    """The author of this object."""
-    author: Identity!
-    """The datetime when this operation was issued."""
-    date: Time!
-
-    added: [Label!]!
-    removed: [Label!]!
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	added: [Label!]!
+	removed: [Label!]!
 }
-`},
-	&ast.Source{Name: "schema/repository.graphql", Input: `
-type Repository {
-    """All the bugs"""
-    allBugs(
-        """Returns the elements in the list that come after the specified cursor."""
-        after: String
-        """Returns the elements in the list that come before the specified cursor."""
-        before: String
-        """Returns the first _n_ elements from the list."""
-        first: Int
-        """Returns the last _n_ elements from the list."""
-        last: Int
-        """A query to select and order bugs"""
-        query: String
-    ): BugConnection!
-
-    bug(prefix: String!): Bug
-
-    """All the identities"""
-    allIdentities(
-        """Returns the elements in the list that come after the specified cursor."""
-        after: String
-        """Returns the elements in the list that come before the specified cursor."""
-        before: String
-        """Returns the first _n_ elements from the list."""
-        first: Int
-        """Returns the last _n_ elements from the list."""
-        last: Int
-    ): IdentityConnection!
-
-    identity(prefix: String!): Identity
-
-    """The identity created or selected by the user as its own"""
-    userIdentity: Identity
-
-    """List of valid labels."""
-    validLabels(
-        """Returns the elements in the list that come after the specified cursor."""
-        after: String
-        """Returns the elements in the list that come before the specified cursor."""
-        before: String
-        """Returns the first _n_ elements from the list."""
-        first: Int
-        """Returns the last _n_ elements from the list."""
-        last: Int
-    ): LabelConnection!
-}`},
-	&ast.Source{Name: "schema/root.graphql", Input: `type Query {
-    """The default unnamend repository."""
-    defaultRepository: Repository
-    """Access a repository by reference/name."""
-    repository(ref: String!): Repository
+type LabelChangeResult {
+	"""
+	The source label.
+	"""
+	label: Label!
+	"""
+	The effect this label had.
+	"""
+	status: LabelChangeStatus!
+}
+enum LabelChangeStatus {
+	ADDED
+	REMOVED
+	DUPLICATE_IN_OP
+	ALREADY_EXIST
+	DOESNT_EXIST
+}
+"""
+LabelChangeTimelineItem is a TimelineItem that represent a change in the labels of a bug
+"""
+type LabelChangeTimelineItem implements TimelineItem & Authored {
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+	author: Identity!
+	date: Time!
+	added: [Label!]!
+	removed: [Label!]!
+}
+type LabelConnection {
+	edges: [LabelEdge!]!
+	nodes: [Label!]!
+	pageInfo: PageInfo!
+	totalCount: Int!
+}
+type LabelEdge {
+	cursor: String!
+	node: Label!
 }
-
 type Mutation {
-    """Create a new bug"""
-    newBug(input: NewBugInput!): NewBugPayload!
-    """Add a new comment to a bug"""
-    addComment(input: AddCommentInput!): AddCommentPayload!
-    """Add or remove a set of label on a bug"""
-    changeLabels(input: ChangeLabelInput): ChangeLabelPayload!
-    """Change a bug's status to open"""
-    openBug(input: OpenBugInput!): OpenBugPayload!
-    """Change a bug's status to closed"""
-    closeBug(input: CloseBugInput!): CloseBugPayload!
-    """Change a bug's title"""
-    setTitle(input: SetTitleInput!): SetTitlePayload!
-    """Commit write the pending operations into storage. This mutation fail if nothing is pending"""
-    commit(input: CommitInput!): CommitPayload!
-    """Commit write the pending operations into storage. This mutation succed if nothing is pending"""
-    commitAsNeeded(input: CommitAsNeededInput!): CommitAsNeededPayload!
+	"""
+	Create a new bug
+	"""
+	newBug(input: NewBugInput!): NewBugPayload!
+	"""
+	Add a new comment to a bug
+	"""
+	addComment(input: AddCommentInput!): AddCommentPayload!
+	"""
+	Add or remove a set of label on a bug
+	"""
+	changeLabels(input: ChangeLabelInput): ChangeLabelPayload!
+	"""
+	Change a bug's status to open
+	"""
+	openBug(input: OpenBugInput!): OpenBugPayload!
+	"""
+	Change a bug's status to closed
+	"""
+	closeBug(input: CloseBugInput!): CloseBugPayload!
+	"""
+	Change a bug's title
+	"""
+	setTitle(input: SetTitleInput!): SetTitlePayload!
+	"""
+	Commit write the pending operations into storage. This mutation fail if nothing is pending
+	"""
+	commit(input: CommitInput!): CommitPayload!
+	"""
+	Commit write the pending operations into storage. This mutation succed if nothing is pending
+	"""
+	commitAsNeeded(input: CommitAsNeededInput!): CommitAsNeededPayload!
+}
+input NewBugInput {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The title of the new bug.
+	"""
+	title: String!
+	"""
+	The first message of the new bug.
+	"""
+	message: String!
+	"""
+	The collection of file's hash required for the first message.
+	"""
+	files: [Hash!]
 }
-`},
-	&ast.Source{Name: "schema/timeline.graphql", Input: `"""An item in the timeline of events"""
-interface TimelineItem {
-    """The identifier of the source operation"""
-    id: String!
+type NewBugPayload {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The created bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation.
+	"""
+	operation: CreateOperation!
 }
-
-"""CommentHistoryStep hold one version of a message in the history"""
-type CommentHistoryStep {
-    message: String!
-    date: Time!
+input OpenBugInput {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
 }
-
-# Connection
-
-"""The connection type for TimelineItem"""
-type TimelineItemConnection {
-    edges: [TimelineItemEdge!]!
-    nodes: [TimelineItem!]!
-    pageInfo: PageInfo!
-    totalCount: Int!
+type OpenBugPayload {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation.
+	"""
+	operation: SetStatusOperation!
+}
+"""
+An operation applied to a bug.
+"""
+interface Operation {
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The operations author.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+}
+"""
+The connection type for an Operation
+"""
+type OperationConnection {
+	edges: [OperationEdge!]!
+	nodes: [Operation!]!
+	pageInfo: PageInfo!
+	totalCount: Int!
+}
+"""
+Represent an Operation
+"""
+type OperationEdge {
+	cursor: String!
+	node: Operation!
 }
-
-"""Represent a TimelineItem"""
-type TimelineItemEdge {
-    cursor: String!
-    node: TimelineItem!
+"""
+Information about pagination in a connection.
+"""
+type PageInfo {
+	"""
+	When paginating forwards, are there more items?
+	"""
+	hasNextPage: Boolean!
+	"""
+	When paginating backwards, are there more items?
+	"""
+	hasPreviousPage: Boolean!
+	"""
+	When paginating backwards, the cursor to continue.
+	"""
+	startCursor: String!
+	"""
+	When paginating forwards, the cursor to continue.
+	"""
+	endCursor: String!
+}
+type Query {
+	"""
+	The default unnamend repository.
+	"""
+	defaultRepository: Repository
+	"""
+	Access a repository by reference/name.
+	"""
+	repository(ref: String!): Repository
 }
-
-# Items
-
-"""CreateTimelineItem is a TimelineItem that represent the creation of a bug and its message edition history"""
-type CreateTimelineItem implements TimelineItem & Authored {
-    """The identifier of the source operation"""
-    id: String!
-    author: Identity!
-    message: String!
-    messageIsEmpty: Boolean!
-    files: [Hash!]!
-    createdAt: Time!
-    lastEdit: Time!
-    edited: Boolean!
-    history: [CommentHistoryStep!]!
-}
-
-"""AddCommentTimelineItem is a TimelineItem that represent a Comment and its edition history"""
-type AddCommentTimelineItem implements TimelineItem & Authored {
-    """The identifier of the source operation"""
-    id: String!
-    author: Identity!
-    message: String!
-    messageIsEmpty: Boolean!
-    files: [Hash!]!
-    createdAt: Time!
-    lastEdit: Time!
-    edited: Boolean!
-    history: [CommentHistoryStep!]!
-}
-
-"""LabelChangeTimelineItem is a TimelineItem that represent a change in the labels of a bug"""
-type LabelChangeTimelineItem implements TimelineItem & Authored {
-    """The identifier of the source operation"""
-    id: String!
-    author: Identity!
-    date: Time!
-    added: [Label!]!
-    removed: [Label!]!
+type Repository {
+	"""
+	All the bugs
+	"""
+	allBugs("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int, """
+	A query to select and order bugs
+	"""
+	query: String): BugConnection!
+	bug(prefix: String!): Bug
+	"""
+	All the identities
+	"""
+	allIdentities("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): IdentityConnection!
+	identity(prefix: String!): Identity
+	"""
+	The identity created or selected by the user as its own
+	"""
+	userIdentity: Identity
+	"""
+	List of valid labels.
+	"""
+	validLabels("""
+	Returns the elements in the list that come after the specified cursor.
+	"""
+	after: String, """
+	Returns the elements in the list that come before the specified cursor.
+	"""
+	before: String, """
+	Returns the first _n_ elements from the list.
+	"""
+	first: Int, """
+	Returns the last _n_ elements from the list.
+	"""
+	last: Int): LabelConnection!
 }
-
-"""SetStatusTimelineItem is a TimelineItem that represent a change in the status of a bug"""
+type SetStatusOperation implements Operation & Authored {
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	status: Status!
+}
+"""
+SetStatusTimelineItem is a TimelineItem that represent a change in the status of a bug
+"""
 type SetStatusTimelineItem implements TimelineItem & Authored {
-    """The identifier of the source operation"""
-    id: String!
-    author: Identity!
-    date: Time!
-    status: Status!
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+	author: Identity!
+	date: Time!
+	status: Status!
 }
-
-"""LabelChangeTimelineItem is a TimelineItem that represent a change in the title of a bug"""
-type SetTitleTimelineItem implements TimelineItem & Authored {
-    """The identifier of the source operation"""
-    id: String!
-    author: Identity!
-    date: Time!
-    title: String!
-    was: String!
+input SetTitleInput {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	"The name of the repository. If not set, the default repository is used.
+	"""
+	repoRef: String
+	"""
+	The bug ID's prefix.
+	"""
+	prefix: String!
+	"""
+	The new title.
+	"""
+	title: String!
 }
-`},
-	&ast.Source{Name: "schema/types.graphql", Input: `scalar Time
-scalar Hash
-
-"""Defines a color by red, green and blue components."""
-type Color {
-    """Red component of the color."""
-    R: Int!
-    """Green component of the color."""
-    G: Int!
-    """Blue component of the color."""
-    B: Int!
+type SetTitleOperation implements Operation & Authored {
+	"""
+	The identifier of the operation
+	"""
+	id: String!
+	"""
+	The author of this object.
+	"""
+	author: Identity!
+	"""
+	The datetime when this operation was issued.
+	"""
+	date: Time!
+	title: String!
+	was: String!
 }
-
-"""Information about pagination in a connection."""
-type PageInfo {
-    """When paginating forwards, are there more items?"""
-    hasNextPage: Boolean!
-    """When paginating backwards, are there more items?"""
-    hasPreviousPage: Boolean!
-    """When paginating backwards, the cursor to continue."""
-    startCursor: String!
-    """When paginating forwards, the cursor to continue."""
-    endCursor: String!
+type SetTitlePayload {
+	"""
+	A unique identifier for the client performing the mutation.
+	"""
+	clientMutationId: String
+	"""
+	The affected bug.
+	"""
+	bug: Bug!
+	"""
+	The resulting operation
+	"""
+	operation: SetTitleOperation!
+}
+"""
+LabelChangeTimelineItem is a TimelineItem that represent a change in the title of a bug
+"""
+type SetTitleTimelineItem implements TimelineItem & Authored {
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+	author: Identity!
+	date: Time!
+	title: String!
+	was: String!
 }
-
-"""An object that has an author."""
-interface Authored {
-    """The author of this object."""
-    author: Identity!
+enum Status {
+	OPEN
+	CLOSED
+}
+scalar Time
+"""
+An item in the timeline of events
+"""
+interface TimelineItem {
+	"""
+	The identifier of the source operation
+	"""
+	id: String!
+}
+"""
+The connection type for TimelineItem
+"""
+type TimelineItemConnection {
+	edges: [TimelineItemEdge!]!
+	nodes: [TimelineItem!]!
+	pageInfo: PageInfo!
+	totalCount: Int!
+}
+"""
+Represent a TimelineItem
+"""
+type TimelineItemEdge {
+	cursor: String!
+	node: TimelineItem!
 }
 `},
 )

graphql/graphql_test.go 🔗

@@ -1,7 +1,6 @@
 package graphql
 
 import (
-	"net/http/httptest"
 	"testing"
 
 	"github.com/99designs/gqlgen/client"
@@ -22,8 +21,7 @@ func TestQueries(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	srv := httptest.NewServer(handler)
-	c := client.New(srv.URL)
+	c := client.New(handler)
 
 	query := `
      query {

graphql/handler.go 🔗

@@ -6,7 +6,8 @@ package graphql
 import (
 	"net/http"
 
-	"github.com/99designs/gqlgen/handler"
+	"github.com/99designs/gqlgen/graphql/handler"
+
 	"github.com/MichaelMure/git-bug/graphql/graph"
 	"github.com/MichaelMure/git-bug/graphql/resolvers"
 	"github.com/MichaelMure/git-bug/repository"
@@ -14,7 +15,7 @@ import (
 
 // Handler is the root GraphQL http handler
 type Handler struct {
-	http.HandlerFunc
+	http.Handler
 	*resolvers.RootResolver
 }
 
@@ -32,7 +33,7 @@ func NewHandler(repo repository.ClockedRepo) (Handler, error) {
 		Resolvers: h.RootResolver,
 	}
 
-	h.HandlerFunc = handler.GraphQL(graph.NewExecutableSchema(config))
+	h.Handler = handler.NewDefaultServer(graph.NewExecutableSchema(config))
 
 	return h, nil
 }

graphql/resolvers/identity.go 🔗

@@ -11,41 +11,10 @@ var _ graph.IdentityResolver = &identityResolver{}
 
 type identityResolver struct{}
 
-func (identityResolver) ID(ctx context.Context, obj *identity.Interface) (string, error) {
-	return (*obj).Id().String(), nil
+func (identityResolver) ID(ctx context.Context, obj identity.Interface) (string, error) {
+	return obj.Id().String(), nil
 }
 
-func (identityResolver) HumanID(ctx context.Context, obj *identity.Interface) (string, error) {
-	return (*obj).Id().Human(), nil
-}
-
-func (identityResolver) Name(ctx context.Context, obj *identity.Interface) (*string, error) {
-	return nilIfEmpty((*obj).Name())
-}
-
-func (identityResolver) Email(ctx context.Context, obj *identity.Interface) (*string, error) {
-	return nilIfEmpty((*obj).Email())
-}
-
-func (identityResolver) Login(ctx context.Context, obj *identity.Interface) (*string, error) {
-	return nilIfEmpty((*obj).Login())
-}
-
-func (identityResolver) DisplayName(ctx context.Context, obj *identity.Interface) (string, error) {
-	return (*obj).DisplayName(), nil
-}
-
-func (identityResolver) AvatarURL(ctx context.Context, obj *identity.Interface) (*string, error) {
-	return nilIfEmpty((*obj).AvatarUrl())
-}
-
-func (identityResolver) IsProtected(ctx context.Context, obj *identity.Interface) (bool, error) {
-	return (*obj).IsProtected(), nil
-}
-
-func nilIfEmpty(s string) (*string, error) {
-	if s == "" {
-		return nil, nil
-	}
-	return &s, nil
+func (identityResolver) HumanID(ctx context.Context, obj identity.Interface) (string, error) {
+	return obj.Id().Human(), nil
 }