aboutsummaryrefslogtreecommitdiffstats
path: root/graphql
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2018-07-29 18:58:42 +0200
committerMichael Muré <batolettre@gmail.com>2018-07-29 18:58:42 +0200
commit8fa0b258ac89781dae269790a4bde09cbcd2f324 (patch)
treeb9bcf0826f5739f128de52123447cede23291c02 /graphql
parent6363518c85cbd8247a5f6507b8a1dd3903cfb71d (diff)
downloadgit-bug-8fa0b258ac89781dae269790a4bde09cbcd2f324.tar.gz
cleaning
Diffstat (limited to 'graphql')
-rw-r--r--graphql/gqlgen.yml27
-rw-r--r--graphql/handler.go42
-rw-r--r--graphql/relay.go39
-rw-r--r--graphql/resolvers.go7
-rw-r--r--graphql/resolvers/bug.go61
-rw-r--r--graphql/resolvers/gen_graph.go2628
-rw-r--r--graphql/resolvers/gen_model.go88
-rw-r--r--graphql/resolvers/operations.go54
-rw-r--r--graphql/resolvers/pager_bug.go225
-rw-r--r--graphql/resolvers/pager_comment.go225
-rw-r--r--graphql/resolvers/pager_operation.go225
-rw-r--r--graphql/resolvers/pagers.go51
-rw-r--r--graphql/resolvers/pagers_template.go224
-rw-r--r--graphql/resolvers/query.go36
-rw-r--r--graphql/resolvers/repo.go26
-rw-r--r--graphql/resolvers/root.go53
-rw-r--r--graphql/schema.go54
-rw-r--r--graphql/schema.graphql181
-rw-r--r--graphql/types.go85
19 files changed, 4152 insertions, 179 deletions
diff --git a/graphql/gqlgen.yml b/graphql/gqlgen.yml
new file mode 100644
index 00000000..131a8b58
--- /dev/null
+++ b/graphql/gqlgen.yml
@@ -0,0 +1,27 @@
+schema: schema.graphql
+exec:
+ filename: resolvers/gen_graph.go
+model:
+ filename: resolvers/gen_model.go
+
+models:
+ Repository:
+ model: github.com/MichaelMure/git-bug/graphql/resolvers.repoResolver
+ Bug:
+ model: github.com/MichaelMure/git-bug/bug.Snapshot
+ Comment:
+ model: github.com/MichaelMure/git-bug/bug.Comment
+ Person:
+ model: github.com/MichaelMure/git-bug/bug.Person
+ Label:
+ model: github.com/MichaelMure/git-bug/bug.Label
+ CreateOperation:
+ model: github.com/MichaelMure/git-bug/bug/operations.CreateOperation
+ SetTitleOperation:
+ model: github.com/MichaelMure/git-bug/bug/operations.SetTitleOperation
+ AddCommentOperation:
+ model: github.com/MichaelMure/git-bug/bug/operations.AddCommentOperation
+ SetStatusOperation:
+ model: github.com/MichaelMure/git-bug/bug/operations.SetStatusOperation
+ LabelChangeOperation:
+ model: github.com/MichaelMure/git-bug/bug/operations.LabelChangeOperation
diff --git a/graphql/handler.go b/graphql/handler.go
index 0f2aaad8..d1906dda 100644
--- a/graphql/handler.go
+++ b/graphql/handler.go
@@ -1,42 +1,18 @@
+//go:generate gorunpkg github.com/vektah/gqlgen
+
package graphql
import (
- "context"
- "net/http"
-
- "github.com/MichaelMure/git-bug/cache"
+ "github.com/MichaelMure/git-bug/graphql/resolvers"
"github.com/MichaelMure/git-bug/repository"
- graphqlHandler "github.com/graphql-go/handler"
+ "github.com/vektah/gqlgen/handler"
+ "net/http"
)
-type Handler struct {
- handler *graphqlHandler.Handler
- cache cache.Cacher
-}
-
-func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- ctx := context.WithValue(r.Context(), "cache", h.cache)
- h.handler.ContextHandler(ctx, w, r)
-}
-
-func NewHandler(repo repository.Repo) (*Handler, error) {
- schema, err := graphqlSchema()
-
- if err != nil {
- return nil, err
- }
-
- h := graphqlHandler.New(&graphqlHandler.Config{
- Schema: &schema,
- Pretty: true,
- GraphiQL: true,
- })
+func NewHandler(repo repository.Repo) http.Handler {
+ backend := resolvers.NewRootResolver()
- c := cache.NewCache()
- c.RegisterDefaultRepository(repo)
+ backend.RegisterDefaultRepository(repo)
- return &Handler{
- handler: h,
- cache: c,
- }, nil
+ return handler.GraphQL(resolvers.NewExecutableSchema(backend))
}
diff --git a/graphql/relay.go b/graphql/relay.go
new file mode 100644
index 00000000..a73a38ef
--- /dev/null
+++ b/graphql/relay.go
@@ -0,0 +1,39 @@
+package graphql
+
+import (
+ "encoding/base64"
+ "strings"
+)
+
+
+type ResolvedGlobalID struct {
+ Type string `json:"type"`
+ ID string `json:"id"`
+}
+
+// Takes a type name and an ID specific to that type name, and returns a
+// "global ID" that is unique among all types.
+func ToGlobalID(ttype string, id string) string {
+ str := ttype + ":" + id
+ encStr := base64.StdEncoding.EncodeToString([]byte(str))
+ return encStr
+}
+
+// Takes the "global ID" created by toGlobalID, and returns the type name and ID
+// used to create it.
+func FromGlobalID(globalID string) *ResolvedGlobalID {
+ strID := ""
+ b, err := base64.StdEncoding.DecodeString(globalID)
+ if err == nil {
+ strID = string(b)
+ }
+ tokens := strings.Split(strID, ":")
+ if len(tokens) < 2 {
+ return nil
+ }
+ return &ResolvedGlobalID{
+ Type: tokens[0],
+ ID: tokens[1],
+ }
+}
+
diff --git a/graphql/resolvers.go b/graphql/resolvers.go
deleted file mode 100644
index ef20d0f2..00000000
--- a/graphql/resolvers.go
+++ /dev/null
@@ -1,7 +0,0 @@
-package graphql
-
-import "github.com/graphql-go/graphql"
-
-func resolveBug(p graphql.ResolveParams) (interface{}, error) {
- return "world", nil
-}
diff --git a/graphql/resolvers/bug.go b/graphql/resolvers/bug.go
new file mode 100644
index 00000000..ad6c288b
--- /dev/null
+++ b/graphql/resolvers/bug.go
@@ -0,0 +1,61 @@
+package resolvers
+
+import (
+ "context"
+ "github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/cache"
+)
+
+type bugResolver struct {
+ cache cache.Cacher
+}
+
+func (bugResolver) Status(ctx context.Context, obj *bug.Snapshot) (Status, error) {
+ return convertStatus(obj.Status)
+}
+
+func (bugResolver) Comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) {
+ var connection CommentConnection
+
+ edger := func(comment bug.Comment, offset int) Edge {
+ return CommentEdge{
+ Node: comment,
+ Cursor: offsetToCursor(offset),
+ }
+ }
+
+ edges, pageInfo, err := BugCommentPaginate(obj.Comments, edger, input)
+
+ if err != nil {
+ return connection, err
+ }
+
+ connection.Edges = edges
+ connection.PageInfo = pageInfo
+ connection.TotalCount = len(obj.Comments)
+
+ return connection, nil
+}
+
+func (bugResolver) Operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) {
+ var connection OperationConnection
+
+ edger := func(op bug.Operation, offset int) Edge {
+ return OperationEdge{
+ Node: op.(OperationUnion),
+ Cursor: offsetToCursor(offset),
+ }
+ }
+
+ edges, pageInfo, err := BugOperationPaginate(obj.Operations, edger, input)
+
+ if err != nil {
+ return connection, err
+ }
+
+ connection.Edges = edges
+ connection.PageInfo = pageInfo
+ connection.TotalCount = len(obj.Operations)
+
+ return connection, nil
+}
diff --git a/graphql/resolvers/gen_graph.go b/graphql/resolvers/gen_graph.go
new file mode 100644
index 00000000..3d752ddc
--- /dev/null
+++ b/graphql/resolvers/gen_graph.go
@@ -0,0 +1,2628 @@
+// Code generated by github.com/vektah/gqlgen, DO NOT EDIT.
+
+package resolvers
+
+import (
+ "bytes"
+ context "context"
+ fmt "fmt"
+ strconv "strconv"
+ time "time"
+
+ bug "github.com/MichaelMure/git-bug/bug"
+ operations "github.com/MichaelMure/git-bug/bug/operations"
+ graphql "github.com/vektah/gqlgen/graphql"
+ introspection "github.com/vektah/gqlgen/neelance/introspection"
+ query "github.com/vektah/gqlgen/neelance/query"
+ schema "github.com/vektah/gqlgen/neelance/schema"
+)
+
+// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface.
+func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {
+ return &executableSchema{resolvers: resolvers}
+}
+
+// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
+func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema {
+ return MakeExecutableSchema(shortMapper{r: resolvers})
+}
+
+type Resolvers interface {
+ AddCommentOperation_date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error)
+
+ Bug_status(ctx context.Context, obj *bug.Snapshot) (Status, error)
+
+ Bug_comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error)
+ Bug_operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error)
+
+ CreateOperation_date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error)
+
+ LabelChangeOperation_date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error)
+
+ Query_defaultRepository(ctx context.Context) (*repoResolver, error)
+ Query_repository(ctx context.Context, id string) (*repoResolver, error)
+
+ Repository_allBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error)
+ Repository_bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error)
+
+ SetStatusOperation_date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error)
+ SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error)
+
+ SetTitleOperation_date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error)
+}
+
+type ResolverRoot interface {
+ AddCommentOperation() AddCommentOperationResolver
+ Bug() BugResolver
+ CreateOperation() CreateOperationResolver
+ LabelChangeOperation() LabelChangeOperationResolver
+ Query() QueryResolver
+ Repository() RepositoryResolver
+ SetStatusOperation() SetStatusOperationResolver
+ SetTitleOperation() SetTitleOperationResolver
+}
+type AddCommentOperationResolver interface {
+ Date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error)
+}
+type BugResolver interface {
+ Status(ctx context.Context, obj *bug.Snapshot) (Status, error)
+
+ Comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error)
+ Operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error)
+}
+type CreateOperationResolver interface {
+ Date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error)
+}
+type LabelChangeOperationResolver interface {
+ Date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error)
+}
+type QueryResolver interface {
+ DefaultRepository(ctx context.Context) (*repoResolver, error)
+ Repository(ctx context.Context, id string) (*repoResolver, error)
+}
+type RepositoryResolver interface {
+ AllBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error)
+ Bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error)
+}
+type SetStatusOperationResolver interface {
+ Date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error)
+ Status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error)
+}
+type SetTitleOperationResolver interface {
+ Date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error)
+}
+
+type shortMapper struct {
+ r ResolverRoot
+}
+
+func (s shortMapper) AddCommentOperation_date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error) {
+ return s.r.AddCommentOperation().Date(ctx, obj)
+}
+
+func (s shortMapper) Bug_status(ctx context.Context, obj *bug.Snapshot) (Status, error) {
+ return s.r.Bug().Status(ctx, obj)
+}
+
+func (s shortMapper) Bug_comments(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (CommentConnection, error) {
+ return s.r.Bug().Comments(ctx, obj, input)
+}
+
+func (s shortMapper) Bug_operations(ctx context.Context, obj *bug.Snapshot, input ConnectionInput) (OperationConnection, error) {
+ return s.r.Bug().Operations(ctx, obj, input)
+}
+
+func (s shortMapper) CreateOperation_date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error) {
+ return s.r.CreateOperation().Date(ctx, obj)
+}
+
+func (s shortMapper) LabelChangeOperation_date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error) {
+ return s.r.LabelChangeOperation().Date(ctx, obj)
+}
+
+func (s shortMapper) Query_defaultRepository(ctx context.Context) (*repoResolver, error) {
+ return s.r.Query().DefaultRepository(ctx)
+}
+
+func (s shortMapper) Query_repository(ctx context.Context, id string) (*repoResolver, error) {
+ return s.r.Query().Repository(ctx, id)
+}
+
+func (s shortMapper) Repository_allBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) {
+ return s.r.Repository().AllBugs(ctx, obj, input)
+}
+
+func (s shortMapper) Repository_bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) {
+ return s.r.Repository().Bug(ctx, obj, prefix)
+}
+
+func (s shortMapper) SetStatusOperation_date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error) {
+ return s.r.SetStatusOperation().Date(ctx, obj)
+}
+
+func (s shortMapper) SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) {
+ return s.r.SetStatusOperation().Status(ctx, obj)
+}
+
+func (s shortMapper) SetTitleOperation_date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error) {
+ return s.r.SetTitleOperation().Date(ctx, obj)
+}
+
+type executableSchema struct {
+ resolvers Resolvers
+}
+
+func (e *executableSchema) Schema() *schema.Schema {
+ return parsedSchema
+}
+
+func (e *executableSchema) Query(ctx context.Context, op *query.Operation) *graphql.Response {
+ ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}
+
+ buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
+ data := ec._Query(ctx, op.Selections)
+ var buf bytes.Buffer
+ data.MarshalGQL(&buf)
+ return buf.Bytes()
+ })
+
+ return &graphql.Response{
+ Data: buf,
+ Errors: ec.Errors,
+ }
+}
+
+func (e *executableSchema) Mutation(ctx context.Context, op *query.Operation) *graphql.Response {
+ return graphql.ErrorResponse(ctx, "mutations are not supported")
+}
+
+func (e *executableSchema) Subscription(ctx context.Context, op *query.Operation) func() *graphql.Response {
+ return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported"))
+}
+
+type executionContext struct {
+ *graphql.RequestContext
+
+ resolvers Resolvers
+}
+
+var addCommentOperationImplementors = []string{"AddCommentOperation", "Operation", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _AddCommentOperation(ctx context.Context, sel []query.Selection, obj *operations.AddCommentOperation) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, addCommentOperationImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("AddCommentOperation")
+ case "author":
+ out.Values[i] = ec._AddCommentOperation_author(ctx, field, obj)
+ case "date":
+ out.Values[i] = ec._AddCommentOperation_date(ctx, field, obj)
+ case "message":
+ out.Values[i] = ec._AddCommentOperation_message(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _AddCommentOperation_author(ctx context.Context, field graphql.CollectedField, obj *operations.AddCommentOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "AddCommentOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _AddCommentOperation_date(ctx context.Context, field graphql.CollectedField, obj *operations.AddCommentOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "AddCommentOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.AddCommentOperation_date(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ return graphql.MarshalTime(res)
+ })
+}
+
+func (ec *executionContext) _AddCommentOperation_message(ctx context.Context, field graphql.CollectedField, obj *operations.AddCommentOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "AddCommentOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Message
+ return graphql.MarshalString(res)
+}
+
+var bugImplementors = []string{"Bug"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _Bug(ctx context.Context, sel []query.Selection, obj *bug.Snapshot) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, bugImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("Bug")
+ case "id":
+ out.Values[i] = ec._Bug_id(ctx, field, obj)
+ case "humanId":
+ out.Values[i] = ec._Bug_humanId(ctx, field, obj)
+ case "title":
+ out.Values[i] = ec._Bug_title(ctx, field, obj)
+ case "status":
+ out.Values[i] = ec._Bug_status(ctx, field, obj)
+ case "labels":
+ out.Values[i] = ec._Bug_labels(ctx, field, obj)
+ case "comments":
+ out.Values[i] = ec._Bug_comments(ctx, field, obj)
+ case "operations":
+ out.Values[i] = ec._Bug_operations(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _Bug_id(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Bug"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Id()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _Bug_humanId(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Bug"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.HumanId()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _Bug_title(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Bug"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Title
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _Bug_status(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Bug",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Bug_status(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(Status)
+ return res
+ })
+}
+
+func (ec *executionContext) _Bug_labels(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Bug"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Labels
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return res[idx1]
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) _Bug_comments(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 ConnectionInput
+ if tmp, ok := field.Args["input"]; ok {
+ var err error
+ arg0, err = UnmarshalConnectionInput(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["input"] = arg0
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Bug",
+ Args: args,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Bug_comments(ctx, obj, args["input"].(ConnectionInput))
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(CommentConnection)
+ return ec._CommentConnection(ctx, field.Selections, &res)
+ })
+}
+
+func (ec *executionContext) _Bug_operations(ctx context.Context, field graphql.CollectedField, obj *bug.Snapshot) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 ConnectionInput
+ if tmp, ok := field.Args["input"]; ok {
+ var err error
+ arg0, err = UnmarshalConnectionInput(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["input"] = arg0
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Bug",
+ Args: args,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Bug_operations(ctx, obj, args["input"].(ConnectionInput))
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(OperationConnection)
+ return ec._OperationConnection(ctx, field.Selections, &res)
+ })
+}
+
+var bugConnectionImplementors = []string{"BugConnection"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _BugConnection(ctx context.Context, sel []query.Selection, obj *BugConnection) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, bugConnectionImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("BugConnection")
+ case "edges":
+ out.Values[i] = ec._BugConnection_edges(ctx, field, obj)
+ case "pageInfo":
+ out.Values[i] = ec._BugConnection_pageInfo(ctx, field, obj)
+ case "totalCount":
+ out.Values[i] = ec._BugConnection_totalCount(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _BugConnection_edges(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "BugConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Edges
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ if res[idx1] == nil {
+ return graphql.Null
+ }
+ return ec._BugEdge(ctx, field.Selections, res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) _BugConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "BugConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.PageInfo
+ return ec._PageInfo(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _BugConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *BugConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "BugConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.TotalCount
+ return graphql.MarshalInt(res)
+}
+
+var bugEdgeImplementors = []string{"BugEdge"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _BugEdge(ctx context.Context, sel []query.Selection, obj *BugEdge) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, bugEdgeImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("BugEdge")
+ case "cursor":
+ out.Values[i] = ec._BugEdge_cursor(ctx, field, obj)
+ case "node":
+ out.Values[i] = ec._BugEdge_node(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _BugEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *BugEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "BugEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Cursor
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _BugEdge_node(ctx context.Context, field graphql.CollectedField, obj *BugEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "BugEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Node
+ return ec._Bug(ctx, field.Selections, &res)
+}
+
+var commentImplementors = []string{"Comment", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _Comment(ctx context.Context, sel []query.Selection, obj *bug.Comment) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, commentImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("Comment")
+ case "author":
+ out.Values[i] = ec._Comment_author(ctx, field, obj)
+ case "message":
+ out.Values[i] = ec._Comment_message(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _Comment_author(ctx context.Context, field graphql.CollectedField, obj *bug.Comment) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Comment"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _Comment_message(ctx context.Context, field graphql.CollectedField, obj *bug.Comment) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Comment"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Message
+ return graphql.MarshalString(res)
+}
+
+var commentConnectionImplementors = []string{"CommentConnection"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _CommentConnection(ctx context.Context, sel []query.Selection, obj *CommentConnection) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, commentConnectionImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("CommentConnection")
+ case "edges":
+ out.Values[i] = ec._CommentConnection_edges(ctx, field, obj)
+ case "pageInfo":
+ out.Values[i] = ec._CommentConnection_pageInfo(ctx, field, obj)
+ case "totalCount":
+ out.Values[i] = ec._CommentConnection_totalCount(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _CommentConnection_edges(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CommentConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Edges
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec._CommentEdge(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) _CommentConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CommentConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.PageInfo
+ return ec._PageInfo(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _CommentConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *CommentConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CommentConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.TotalCount
+ return graphql.MarshalInt(res)
+}
+
+var commentEdgeImplementors = []string{"CommentEdge"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _CommentEdge(ctx context.Context, sel []query.Selection, obj *CommentEdge) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, commentEdgeImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("CommentEdge")
+ case "cursor":
+ out.Values[i] = ec._CommentEdge_cursor(ctx, field, obj)
+ case "node":
+ out.Values[i] = ec._CommentEdge_node(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _CommentEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *CommentEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CommentEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Cursor
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _CommentEdge_node(ctx context.Context, field graphql.CollectedField, obj *CommentEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CommentEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Node
+ return ec._Comment(ctx, field.Selections, &res)
+}
+
+var createOperationImplementors = []string{"CreateOperation", "Operation", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _CreateOperation(ctx context.Context, sel []query.Selection, obj *operations.CreateOperation) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, createOperationImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("CreateOperation")
+ case "author":
+ out.Values[i] = ec._CreateOperation_author(ctx, field, obj)
+ case "date":
+ out.Values[i] = ec._CreateOperation_date(ctx, field, obj)
+ case "title":
+ out.Values[i] = ec._CreateOperation_title(ctx, field, obj)
+ case "message":
+ out.Values[i] = ec._CreateOperation_message(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _CreateOperation_author(ctx context.Context, field graphql.CollectedField, obj *operations.CreateOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CreateOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _CreateOperation_date(ctx context.Context, field graphql.CollectedField, obj *operations.CreateOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "CreateOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.CreateOperation_date(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ return graphql.MarshalTime(res)
+ })
+}
+
+func (ec *executionContext) _CreateOperation_title(ctx context.Context, field graphql.CollectedField, obj *operations.CreateOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CreateOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Title
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _CreateOperation_message(ctx context.Context, field graphql.CollectedField, obj *operations.CreateOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "CreateOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Message
+ return graphql.MarshalString(res)
+}
+
+var labelChangeOperationImplementors = []string{"LabelChangeOperation", "Operation", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _LabelChangeOperation(ctx context.Context, sel []query.Selection, obj *operations.LabelChangeOperation) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, labelChangeOperationImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("LabelChangeOperation")
+ case "author":
+ out.Values[i] = ec._LabelChangeOperation_author(ctx, field, obj)
+ case "date":
+ out.Values[i] = ec._LabelChangeOperation_date(ctx, field, obj)
+ case "added":
+ out.Values[i] = ec._LabelChangeOperation_added(ctx, field, obj)
+ case "removed":
+ out.Values[i] = ec._LabelChangeOperation_removed(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _LabelChangeOperation_author(ctx context.Context, field graphql.CollectedField, obj *operations.LabelChangeOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "LabelChangeOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _LabelChangeOperation_date(ctx context.Context, field graphql.CollectedField, obj *operations.LabelChangeOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "LabelChangeOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.LabelChangeOperation_date(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ return graphql.MarshalTime(res)
+ })
+}
+
+func (ec *executionContext) _LabelChangeOperation_added(ctx context.Context, field graphql.CollectedField, obj *operations.LabelChangeOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "LabelChangeOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Added
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return res[idx1]
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) _LabelChangeOperation_removed(ctx context.Context, field graphql.CollectedField, obj *operations.LabelChangeOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "LabelChangeOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Removed
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return res[idx1]
+ }())
+ }
+ return arr1
+}
+
+var operationConnectionImplementors = []string{"OperationConnection"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _OperationConnection(ctx context.Context, sel []query.Selection, obj *OperationConnection) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, operationConnectionImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("OperationConnection")
+ case "edges":
+ out.Values[i] = ec._OperationConnection_edges(ctx, field, obj)
+ case "pageInfo":
+ out.Values[i] = ec._OperationConnection_pageInfo(ctx, field, obj)
+ case "totalCount":
+ out.Values[i] = ec._OperationConnection_totalCount(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _OperationConnection_edges(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "OperationConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Edges
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec._OperationEdge(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) _OperationConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "OperationConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.PageInfo
+ return ec._PageInfo(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _OperationConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *OperationConnection) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "OperationConnection"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.TotalCount
+ return graphql.MarshalInt(res)
+}
+
+var operationEdgeImplementors = []string{"OperationEdge"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _OperationEdge(ctx context.Context, sel []query.Selection, obj *OperationEdge) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, operationEdgeImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("OperationEdge")
+ case "cursor":
+ out.Values[i] = ec._OperationEdge_cursor(ctx, field, obj)
+ case "node":
+ out.Values[i] = ec._OperationEdge_node(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _OperationEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *OperationEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "OperationEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Cursor
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _OperationEdge_node(ctx context.Context, field graphql.CollectedField, obj *OperationEdge) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "OperationEdge"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Node
+ return ec._OperationUnion(ctx, field.Selections, &res)
+}
+
+var pageInfoImplementors = []string{"PageInfo"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _PageInfo(ctx context.Context, sel []query.Selection, obj *PageInfo) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, pageInfoImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("PageInfo")
+ case "hasNextPage":
+ out.Values[i] = ec._PageInfo_hasNextPage(ctx, field, obj)
+ case "hasPreviousPage":
+ out.Values[i] = ec._PageInfo_hasPreviousPage(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field graphql.CollectedField, obj *PageInfo) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "PageInfo"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.HasNextPage
+ return graphql.MarshalBoolean(res)
+}
+
+func (ec *executionContext) _PageInfo_hasPreviousPage(ctx context.Context, field graphql.CollectedField, obj *PageInfo) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "PageInfo"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.HasPreviousPage
+ return graphql.MarshalBoolean(res)
+}
+
+var personImplementors = []string{"Person"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _Person(ctx context.Context, sel []query.Selection, obj *bug.Person) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, personImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("Person")
+ case "email":
+ out.Values[i] = ec._Person_email(ctx, field, obj)
+ case "name":
+ out.Values[i] = ec._Person_name(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _Person_email(ctx context.Context, field graphql.CollectedField, obj *bug.Person) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Person"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Email
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) _Person_name(ctx context.Context, field graphql.CollectedField, obj *bug.Person) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Person"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name
+ return graphql.MarshalString(res)
+}
+
+var queryImplementors = []string{"Query"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _Query(ctx context.Context, sel []query.Selection) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, queryImplementors, ec.Variables)
+
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Query",
+ })
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("Query")
+ case "defaultRepository":
+ out.Values[i] = ec._Query_defaultRepository(ctx, field)
+ case "repository":
+ out.Values[i] = ec._Query_repository(ctx, field)
+ case "__schema":
+ out.Values[i] = ec._Query___schema(ctx, field)
+ case "__type":
+ out.Values[i] = ec._Query___type(ctx, field)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _Query_defaultRepository(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Query",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Query_defaultRepository(ctx)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*repoResolver)
+ if res == nil {
+ return graphql.Null
+ }
+ return ec._Repository(ctx, field.Selections, res)
+ })
+}
+
+func (ec *executionContext) _Query_repository(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 string
+ if tmp, ok := field.Args["id"]; ok {
+ var err error
+ arg0, err = graphql.UnmarshalString(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["id"] = arg0
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Query",
+ Args: args,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Query_repository(ctx, args["id"].(string))
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*repoResolver)
+ if res == nil {
+ return graphql.Null
+ }
+ return ec._Repository(ctx, field.Selections, res)
+ })
+}
+
+func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Query"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := ec.introspectSchema()
+ if res == nil {
+ return graphql.Null
+ }
+ return ec.___Schema(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 string
+ if tmp, ok := field.Args["name"]; ok {
+ var err error
+ arg0, err = graphql.UnmarshalString(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["name"] = arg0
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "Query"
+ rctx.Args = args
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := ec.introspectType(args["name"].(string))
+ if res == nil {
+ return graphql.Null
+ }
+ return ec.___Type(ctx, field.Selections, res)
+}
+
+var repositoryImplementors = []string{"Repository"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _Repository(ctx context.Context, sel []query.Selection, obj *repoResolver) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, repositoryImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("Repository")
+ case "allBugs":
+ out.Values[i] = ec._Repository_allBugs(ctx, field, obj)
+ case "bug":
+ out.Values[i] = ec._Repository_bug(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graphql.CollectedField, obj *repoResolver) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 ConnectionInput
+ if tmp, ok := field.Args["input"]; ok {
+ var err error
+ arg0, err = UnmarshalConnectionInput(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["input"] = arg0
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Repository",
+ Args: args,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Repository_allBugs(ctx, obj, args["input"].(ConnectionInput))
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(BugConnection)
+ return ec._BugConnection(ctx, field.Selections, &res)
+ })
+}
+
+func (ec *executionContext) _Repository_bug(ctx context.Context, field graphql.CollectedField, obj *repoResolver) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 string
+ if tmp, ok := field.Args["prefix"]; ok {
+ var err error
+ arg0, err = graphql.UnmarshalString(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["prefix"] = arg0
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "Repository",
+ Args: args,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.Repository_bug(ctx, obj, args["prefix"].(string))
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(*bug.Snapshot)
+ if res == nil {
+ return graphql.Null
+ }
+ return ec._Bug(ctx, field.Selections, res)
+ })
+}
+
+var setStatusOperationImplementors = []string{"SetStatusOperation", "Operation", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _SetStatusOperation(ctx context.Context, sel []query.Selection, obj *operations.SetStatusOperation) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, setStatusOperationImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("SetStatusOperation")
+ case "author":
+ out.Values[i] = ec._SetStatusOperation_author(ctx, field, obj)
+ case "date":
+ out.Values[i] = ec._SetStatusOperation_date(ctx, field, obj)
+ case "status":
+ out.Values[i] = ec._SetStatusOperation_status(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _SetStatusOperation_author(ctx context.Context, field graphql.CollectedField, obj *operations.SetStatusOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "SetStatusOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _SetStatusOperation_date(ctx context.Context, field graphql.CollectedField, obj *operations.SetStatusOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "SetStatusOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.SetStatusOperation_date(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ return graphql.MarshalTime(res)
+ })
+}
+
+func (ec *executionContext) _SetStatusOperation_status(ctx context.Context, field graphql.CollectedField, obj *operations.SetStatusOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "SetStatusOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.SetStatusOperation_status(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(Status)
+ return res
+ })
+}
+
+var setTitleOperationImplementors = []string{"SetTitleOperation", "Operation", "Authored"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) _SetTitleOperation(ctx context.Context, sel []query.Selection, obj *operations.SetTitleOperation) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, setTitleOperationImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("SetTitleOperation")
+ case "author":
+ out.Values[i] = ec._SetTitleOperation_author(ctx, field, obj)
+ case "date":
+ out.Values[i] = ec._SetTitleOperation_date(ctx, field, obj)
+ case "title":
+ out.Values[i] = ec._SetTitleOperation_title(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) _SetTitleOperation_author(ctx context.Context, field graphql.CollectedField, obj *operations.SetTitleOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "SetTitleOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Author
+ return ec._Person(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) _SetTitleOperation_date(ctx context.Context, field graphql.CollectedField, obj *operations.SetTitleOperation) graphql.Marshaler {
+ ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
+ Object: "SetTitleOperation",
+ Args: nil,
+ Field: field,
+ })
+ return graphql.Defer(func() (ret graphql.Marshaler) {
+ defer func() {
+ if r := recover(); r != nil {
+ userErr := ec.Recover(ctx, r)
+ ec.Error(ctx, userErr)
+ ret = graphql.Null
+ }
+ }()
+
+ resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
+ return ec.resolvers.SetTitleOperation_date(ctx, obj)
+ })
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ if resTmp == nil {
+ return graphql.Null
+ }
+ res := resTmp.(time.Time)
+ return graphql.MarshalTime(res)
+ })
+}
+
+func (ec *executionContext) _SetTitleOperation_title(ctx context.Context, field graphql.CollectedField, obj *operations.SetTitleOperation) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "SetTitleOperation"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Title
+ return graphql.MarshalString(res)
+}
+
+var __DirectiveImplementors = []string{"__Directive"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___Directive(ctx context.Context, sel []query.Selection, obj *introspection.Directive) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __DirectiveImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__Directive")
+ case "name":
+ out.Values[i] = ec.___Directive_name(ctx, field, obj)
+ case "description":
+ out.Values[i] = ec.___Directive_description(ctx, field, obj)
+ case "locations":
+ out.Values[i] = ec.___Directive_locations(ctx, field, obj)
+ case "args":
+ out.Values[i] = ec.___Directive_args(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Directive"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Directive"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Description()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Directive"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Locations()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return graphql.MarshalString(res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Directive"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Args()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___InputValue(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+var __EnumValueImplementors = []string{"__EnumValue"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___EnumValue(ctx context.Context, sel []query.Selection, obj *introspection.EnumValue) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __EnumValueImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__EnumValue")
+ case "name":
+ out.Values[i] = ec.___EnumValue_name(ctx, field, obj)
+ case "description":
+ out.Values[i] = ec.___EnumValue_description(ctx, field, obj)
+ case "isDeprecated":
+ out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj)
+ case "deprecationReason":
+ out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__EnumValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__EnumValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Description()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__EnumValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.IsDeprecated()
+ return graphql.MarshalBoolean(res)
+}
+
+func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__EnumValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.DeprecationReason()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+var __FieldImplementors = []string{"__Field"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___Field(ctx context.Context, sel []query.Selection, obj *introspection.Field) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __FieldImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__Field")
+ case "name":
+ out.Values[i] = ec.___Field_name(ctx, field, obj)
+ case "description":
+ out.Values[i] = ec.___Field_description(ctx, field, obj)
+ case "args":
+ out.Values[i] = ec.___Field_args(ctx, field, obj)
+ case "type":
+ out.Values[i] = ec.___Field_type(ctx, field, obj)
+ case "isDeprecated":
+ out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj)
+ case "deprecationReason":
+ out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Description()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Args()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___InputValue(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Type()
+ return ec.___Type(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.IsDeprecated()
+ return graphql.MarshalBoolean(res)
+}
+
+func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Field"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.DeprecationReason()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+var __InputValueImplementors = []string{"__InputValue"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___InputValue(ctx context.Context, sel []query.Selection, obj *introspection.InputValue) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __InputValueImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__InputValue")
+ case "name":
+ out.Values[i] = ec.___InputValue_name(ctx, field, obj)
+ case "description":
+ out.Values[i] = ec.___InputValue_description(ctx, field, obj)
+ case "type":
+ out.Values[i] = ec.___InputValue_type(ctx, field, obj)
+ case "defaultValue":
+ out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__InputValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__InputValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Description()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__InputValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Type()
+ return ec.___Type(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__InputValue"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.DefaultValue()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+var __SchemaImplementors = []string{"__Schema"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___Schema(ctx context.Context, sel []query.Selection, obj *introspection.Schema) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __SchemaImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__Schema")
+ case "types":
+ out.Values[i] = ec.___Schema_types(ctx, field, obj)
+ case "queryType":
+ out.Values[i] = ec.___Schema_queryType(ctx, field, obj)
+ case "mutationType":
+ out.Values[i] = ec.___Schema_mutationType(ctx, field, obj)
+ case "subscriptionType":
+ out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj)
+ case "directives":
+ out.Values[i] = ec.___Schema_directives(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Schema"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Types()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___Type(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Schema"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.QueryType()
+ return ec.___Type(ctx, field.Selections, &res)
+}
+
+func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Schema"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.MutationType()
+ if res == nil {
+ return graphql.Null
+ }
+ return ec.___Type(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Schema"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.SubscriptionType()
+ if res == nil {
+ return graphql.Null
+ }
+ return ec.___Type(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Schema"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Directives()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___Directive(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+var __TypeImplementors = []string{"__Type"}
+
+// nolint: gocyclo, errcheck, gas, goconst
+func (ec *executionContext) ___Type(ctx context.Context, sel []query.Selection, obj *introspection.Type) graphql.Marshaler {
+ fields := graphql.CollectFields(ec.Doc, sel, __TypeImplementors, ec.Variables)
+
+ out := graphql.NewOrderedMap(len(fields))
+ for i, field := range fields {
+ out.Keys[i] = field.Alias
+
+ switch field.Name {
+ case "__typename":
+ out.Values[i] = graphql.MarshalString("__Type")
+ case "kind":
+ out.Values[i] = ec.___Type_kind(ctx, field, obj)
+ case "name":
+ out.Values[i] = ec.___Type_name(ctx, field, obj)
+ case "description":
+ out.Values[i] = ec.___Type_description(ctx, field, obj)
+ case "fields":
+ out.Values[i] = ec.___Type_fields(ctx, field, obj)
+ case "interfaces":
+ out.Values[i] = ec.___Type_interfaces(ctx, field, obj)
+ case "possibleTypes":
+ out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj)
+ case "enumValues":
+ out.Values[i] = ec.___Type_enumValues(ctx, field, obj)
+ case "inputFields":
+ out.Values[i] = ec.___Type_inputFields(ctx, field, obj)
+ case "ofType":
+ out.Values[i] = ec.___Type_ofType(ctx, field, obj)
+ default:
+ panic("unknown field " + strconv.Quote(field.Name))
+ }
+ }
+
+ return out
+}
+
+func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Kind()
+ return graphql.MarshalString(res)
+}
+
+func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Name()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Description()
+ if res == nil {
+ return graphql.Null
+ }
+ return graphql.MarshalString(*res)
+}
+
+func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 bool
+ if tmp, ok := field.Args["includeDeprecated"]; ok {
+ var err error
+ arg0, err = graphql.UnmarshalBoolean(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["includeDeprecated"] = arg0
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = args
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Fields(args["includeDeprecated"].(bool))
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___Field(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.Interfaces()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___Type(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.PossibleTypes()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___Type(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ args := map[string]interface{}{}
+ var arg0 bool
+ if tmp, ok := field.Args["includeDeprecated"]; ok {
+ var err error
+ arg0, err = graphql.UnmarshalBoolean(tmp)
+ if err != nil {
+ ec.Error(ctx, err)
+ return graphql.Null
+ }
+ }
+ args["includeDeprecated"] = arg0
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = args
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.EnumValues(args["includeDeprecated"].(bool))
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___EnumValue(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.InputFields()
+ arr1 := graphql.Array{}
+ for idx1 := range res {
+ arr1 = append(arr1, func() graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.PushIndex(idx1)
+ defer rctx.Pop()
+ return ec.___InputValue(ctx, field.Selections, &res[idx1])
+ }())
+ }
+ return arr1
+}
+
+func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler {
+ rctx := graphql.GetResolverContext(ctx)
+ rctx.Object = "__Type"
+ rctx.Args = nil
+ rctx.Field = field
+ rctx.PushField(field.Alias)
+ defer rctx.Pop()
+ res := obj.OfType()
+ if res == nil {
+ return graphql.Null
+ }
+ return ec.___Type(ctx, field.Selections, res)
+}
+
+func (ec *executionContext) _Authored(ctx context.Context, sel []query.Selection, obj *Authored) graphql.Marshaler {
+ switch obj := (*obj).(type) {
+ case nil:
+ return graphql.Null
+ case bug.Comment:
+ return ec._Comment(ctx, sel, &obj)
+ case *bug.Comment:
+ return ec._Comment(ctx, sel, obj)
+ case operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, &obj)
+ case *operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, obj)
+ case operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, &obj)
+ case *operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, obj)
+ case operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, &obj)
+ case *operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, obj)
+ case operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, &obj)
+ case *operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, obj)
+ case operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, &obj)
+ case *operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, obj)
+ default:
+ panic(fmt.Errorf("unexpected type %T", obj))
+ }
+}
+
+func (ec *executionContext) _Operation(ctx context.Context, sel []query.Selection, obj *Operation) graphql.Marshaler {
+ switch obj := (*obj).(type) {
+ case nil:
+ return graphql.Null
+ case operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, &obj)
+ case *operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, obj)
+ case operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, &obj)
+ case *operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, obj)
+ case operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, &obj)
+ case *operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, obj)
+ case operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, &obj)
+ case *operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, obj)
+ case operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, &obj)
+ case *operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, obj)
+ default:
+ panic(fmt.Errorf("unexpected type %T", obj))
+ }
+}
+
+func (ec *executionContext) _OperationUnion(ctx context.Context, sel []query.Selection, obj *OperationUnion) graphql.Marshaler {
+ switch obj := (*obj).(type) {
+ case nil:
+ return graphql.Null
+ case operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, &obj)
+ case *operations.CreateOperation:
+ return ec._CreateOperation(ctx, sel, obj)
+ case operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, &obj)
+ case *operations.SetTitleOperation:
+ return ec._SetTitleOperation(ctx, sel, obj)
+ case operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, &obj)
+ case *operations.AddCommentOperation:
+ return ec._AddCommentOperation(ctx, sel, obj)
+ case operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, &obj)
+ case *operations.SetStatusOperation:
+ return ec._SetStatusOperation(ctx, sel, obj)
+ case operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, &obj)
+ case *operations.LabelChangeOperation:
+ return ec._LabelChangeOperation(ctx, sel, obj)
+ default:
+ panic(fmt.Errorf("unexpected type %T", obj))
+ }
+}
+
+func UnmarshalConnectionInput(v interface{}) (ConnectionInput, error) {
+ var it ConnectionInput
+ var asMap = v.(map[string]interface{})
+
+ for k, v := range asMap {
+ switch k {
+ case "after":
+ var err error
+ var ptr1 string
+ if v != nil {
+ ptr1, err = graphql.UnmarshalString(v)
+ it.After = &ptr1
+ }
+
+ if err != nil {
+ return it, err
+ }
+ case "before":
+ var err error
+ var ptr1 string
+ if v != nil {
+ ptr1, err = graphql.UnmarshalString(v)
+ it.Before = &ptr1
+ }
+
+ if err != nil {
+ return it, err
+ }
+ case "first":
+ var err error
+ var ptr1 int
+ if v != nil {
+ ptr1, err = graphql.UnmarshalInt(v)
+ it.First = &ptr1
+ }
+
+ if err != nil {
+ return it, err
+ }
+ case "last":
+ var err error
+ var ptr1 int
+ if v != nil {
+ ptr1, err = graphql.UnmarshalInt(v)
+ it.Last = &ptr1
+ }
+
+ if err != nil {
+ return it, err
+ }
+ }
+ }
+
+ return it, nil
+}
+
+func (ec *executionContext) introspectSchema() *introspection.Schema {
+ return introspection.WrapSchema(parsedSchema)
+}
+
+func (ec *executionContext) introspectType(name string) *introspection.Type {
+ t := parsedSchema.Resolve(name)
+ if t == nil {
+ return nil
+ }
+ return introspection.WrapType(t)
+}
+
+var parsedSchema = schema.MustParse(`scalar Time
+scalar Label
+
+# 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
+}
+
+input ConnectionInput {
+ # 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
+}
+
+# Represents an person in a git object.
+type Person {
+ # The email of the person.
+ email: String
+
+ # The name of the person.
+ name: String
+}
+
+
+type CommentConnection {
+ edges: [CommentEdge!]!
+ pageInfo: PageInfo!
+ totalCount: Int!
+}
+
+type CommentEdge {
+ cursor: String!
+ node: Comment!
+}
+
+# Represents a comment on a bug.
+type Comment implements Authored {
+ # The author of this comment.
+ author: Person!
+
+ # The message of this comment.
+ message: String!
+}
+
+enum Status {
+ OPEN
+ CLOSED
+}
+
+# An object that has an author.
+interface Authored {
+ # The author of this object.
+ author: Person!
+}
+
+type OperationConnection {
+ edges: [OperationEdge!]!
+ pageInfo: PageInfo!
+ totalCount: Int!
+}
+
+type OperationEdge {
+ cursor: String!
+ node: OperationUnion!
+}
+
+# An operation applied to a bug.
+interface Operation {
+ # The operations author.
+ author: Person!
+
+ # The datetime when this operation was issued.
+ date: Time!
+}
+
+type CreateOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ title: String!
+ message: String!
+}
+
+type SetTitleOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ title: String!
+}
+
+type AddCommentOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ message: String!
+}
+
+type SetStatusOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ status: Status!
+}
+
+type LabelChangeOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ added: [Label!]!
+ removed: [Label!]!
+}
+
+union OperationUnion =
+ CreateOperation
+ | SetTitleOperation
+ | AddCommentOperation
+ | SetStatusOperation
+ | LabelChangeOperation
+
+# The connection type for Bug.
+type BugConnection {
+ # A list of edges.
+ edges: [BugEdge]!
+
+ # 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!
+}
+
+type Bug {
+ id: String!
+ humanId: String!
+ title: String!
+ status: Status!
+
+ # A list of labels associated with the repository.
+ labels: [Label!]!
+
+ comments(input: ConnectionInput!): CommentConnection!
+
+ operations(input: ConnectionInput!): OperationConnection!
+}
+
+type Repository {
+ allBugs(input: ConnectionInput!): BugConnection!
+ bug(prefix: String!): Bug
+}
+
+type Query {
+ defaultRepository: Repository
+ repository(id: String!): Repository
+}
+`)
diff --git a/graphql/resolvers/gen_model.go b/graphql/resolvers/gen_model.go
new file mode 100644
index 00000000..f6d78471
--- /dev/null
+++ b/graphql/resolvers/gen_model.go
@@ -0,0 +1,88 @@
+// Code generated by github.com/vektah/gqlgen, DO NOT EDIT.
+
+package resolvers
+
+import (
+ fmt "fmt"
+ io "io"
+ strconv "strconv"
+
+ bug "github.com/MichaelMure/git-bug/bug"
+)
+
+type Authored interface{}
+type BugConnection struct {
+ Edges []*BugEdge `json:"edges"`
+ PageInfo PageInfo `json:"pageInfo"`
+ TotalCount int `json:"totalCount"`
+}
+type BugEdge struct {
+ Cursor string `json:"cursor"`
+ Node bug.Snapshot `json:"node"`
+}
+type CommentConnection struct {
+ Edges []CommentEdge `json:"edges"`
+ PageInfo PageInfo `json:"pageInfo"`
+ TotalCount int `json:"totalCount"`
+}
+type CommentEdge struct {
+ Cursor string `json:"cursor"`
+ Node bug.Comment `json:"node"`
+}
+type ConnectionInput struct {
+ After *string `json:"after"`
+ Before *string `json:"before"`
+ First *int `json:"first"`
+ Last *int `json:"last"`
+}
+type Operation interface{}
+type OperationConnection struct {
+ Edges []OperationEdge `json:"edges"`
+ PageInfo PageInfo `json:"pageInfo"`
+ TotalCount int `json:"totalCount"`
+}
+type OperationEdge struct {
+ Cursor string `json:"cursor"`
+ Node OperationUnion `json:"node"`
+}
+type OperationUnion interface{}
+type PageInfo struct {
+ HasNextPage bool `json:"hasNextPage"`
+ HasPreviousPage bool `json:"hasPreviousPage"`
+}
+
+type Status string
+
+const (
+ StatusOpen Status = "OPEN"
+ StatusClosed Status = "CLOSED"
+)
+
+func (e Status) IsValid() bool {
+ switch e {
+ case StatusOpen, StatusClosed:
+ return true
+ }
+ return false
+}
+
+func (e Status) String() string {
+ return string(e)
+}
+
+func (e *Status) UnmarshalGQL(v interface{}) error {
+ str, ok := v.(string)
+ if !ok {
+ return fmt.Errorf("enums must be strings")
+ }
+
+ *e = Status(str)
+ if !e.IsValid() {
+ return fmt.Errorf("%s is not a valid Status", str)
+ }
+ return nil
+}
+
+func (e Status) MarshalGQL(w io.Writer) {
+ fmt.Fprint(w, strconv.Quote(e.String()))
+}
diff --git a/graphql/resolvers/operations.go b/graphql/resolvers/operations.go
new file mode 100644
index 00000000..1279a1b4
--- /dev/null
+++ b/graphql/resolvers/operations.go
@@ -0,0 +1,54 @@
+package resolvers
+
+import (
+ "context"
+ "fmt"
+ "github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/bug/operations"
+ "time"
+)
+
+type addCommentOperationResolver struct{}
+
+func (addCommentOperationResolver) Date(ctx context.Context, obj *operations.AddCommentOperation) (time.Time, error) {
+ return obj.Time(), nil
+}
+
+type createOperationResolver struct{}
+
+func (createOperationResolver) Date(ctx context.Context, obj *operations.CreateOperation) (time.Time, error) {
+ return obj.Time(), nil
+}
+
+type labelChangeOperation struct{}
+
+func (labelChangeOperation) Date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error) {
+ return obj.Time(), nil
+}
+
+type setStatusOperationResolver struct{}
+
+func (setStatusOperationResolver) Date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error) {
+ return obj.Time(), nil
+}
+
+func (setStatusOperationResolver) Status(ctx context.Context, obj *operations.SetStatusOperation) (Status, error) {
+ return convertStatus(obj.Status)
+}
+
+type setTitleOperationResolver struct{}
+
+func (setTitleOperationResolver) Date(ctx context.Context, obj *operations.SetTitleOperation) (time.Time, error) {
+ return obj.Time(), nil
+}
+
+func convertStatus(status bug.Status) (Status, error) {
+ switch status {
+ case bug.OpenStatus:
+ return StatusOpen, nil
+ case bug.ClosedStatus:
+ return StatusClosed, nil
+ }
+
+ return "", fmt.Errorf("Unknown status")
+}
diff --git a/graphql/resolvers/pager_bug.go b/graphql/resolvers/pager_bug.go
new file mode 100644
index 00000000..55acfcc4
--- /dev/null
+++ b/graphql/resolvers/pager_bug.go
@@ -0,0 +1,225 @@
+// This file was automatically generated by genny.
+// Any changes will be lost if this file is regenerated.
+// see https://github.com/cheekybits/genny
+
+package resolvers
+
+import (
+ "fmt"
+
+ "github.com/MichaelMure/git-bug/bug"
+)
+
+type BugSnapshotEdger func(value bug.Snapshot, offset int) Edge
+
+func BugSnapshotPaginate(source []bug.Snapshot, edger BugSnapshotEdger, input ConnectionInput) ([]BugEdge, PageInfo, error) {
+ var result []BugEdge
+ var pageInfo PageInfo
+
+ offset := 0
+
+ if input.After != nil {
+ for i, value := range source {
+ edge := edger(value, i)
+ if edge.GetCursor() == *input.After {
+ // remove all previous element including the "after" one
+ source = source[i+1:]
+ offset = i + 1
+ break
+ }
+ }
+ }
+
+ if input.Before != nil {
+ for i, value := range source {
+ edge := edger(value, i+offset)
+
+ if edge.GetCursor() == *input.Before {
+ // remove all after element including the "before" one
+ break
+ }
+
+ result = append(result, edge.(BugEdge))
+ }
+ } else {
+ result = make([]BugEdge, len(source))
+
+ for i, value := range source {
+ result[i] = edger(value, i+offset).(BugEdge)
+ }
+ }
+
+ if input.First != nil {
+ if *input.First < 0 {
+ return nil, PageInfo{}, fmt.Errorf("first less than zero")
+ }
+
+ if len(result) > *input.First {
+ // Slice result to be of length first by removing edges from the end
+ result = result[:*input.First]
+ pageInfo.HasNextPage = true
+ }
+ }
+
+ if input.Last != nil {
+ if *input.Last < 0 {
+ return nil, PageInfo{}, fmt.Errorf("last less than zero")
+ }
+
+ if len(result) > *input.Last {
+ // Slice result to be of length last by removing edges from the start
+ result = result[len(result)-*input.Last:]
+ pageInfo.HasPreviousPage = true
+ }
+ }
+
+ return result, pageInfo, nil
+}
+
+// Apply the before/after cursor params to the source and return an array of edges
+//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge {
+// var result []Edge
+//
+// if input.After != nil {
+// for i, value := range source {
+// edge := edger(value)
+// if edge.Cursor() == *input.After {
+// // remove all previous element including the "after" one
+// source = source[i+1:]
+// break
+// }
+// }
+// }
+//
+// if input.Before != nil {
+// for _, value := range source {
+// edge := edger(value)
+//
+// if edge.Cursor() == *input.Before {
+// // remove all after element including the "before" one
+// break
+// }
+//
+// result = append(result, edge)
+// }
+// } else {
+// result = make([]Edge, len(source))
+//
+// for i, value := range source {
+// result[i] = edger(value)
+// }
+// }
+//
+// return result
+//}
+
+// Apply the first/last cursor params to the edges
+//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) {
+// hasPreviousPage := false
+// hasNextPage := false
+//
+// if input.First != nil {
+// if *input.First < 0 {
+// return nil, nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(edges) > *input.First {
+// // Slice result to be of length first by removing edges from the end
+// edges = edges[:*input.First]
+// hasNextPage = true
+// }
+// }
+//
+// if input.Last != nil {
+// if *input.Last < 0 {
+// return nil, nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(edges) > *input.Last {
+// // Slice result to be of length last by removing edges from the start
+// edges = edges[len(edges)-*input.Last:]
+// hasPreviousPage = true
+// }
+// }
+//
+// pageInfo := PageInfo{
+// HasNextPage: hasNextPage,
+// HasPreviousPage: hasPreviousPage,
+// }
+//
+// return edges, pageInfo, nil
+//}
+
+//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) {
+// result := ApplyCursorToEdges(allEdges, before, after)
+//
+// if first != nil {
+// if *first < 0 {
+// return nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(result) > *first {
+// // Slice result to be of length first by removing edges from the end
+// result = result[:*first]
+// }
+// }
+//
+// if last != nil {
+// if *last < 0 {
+// return nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(result) > *last {
+// // Slice result to be of length last by removing edges from the start
+// result = result[len(result)-*last:]
+// }
+// }
+//
+// return result, nil
+//}
+
+//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge {
+// result := allEdges
+//
+// if after != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *after {
+// // remove all previous element including the "after" one
+// result = result[i+1:]
+// break
+// }
+// }
+// }
+//
+// if before != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *before {
+// // remove all after element including the "before" one
+// result = result[:i]
+// }
+// }
+// }
+//
+// return result
+//}
+
+//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool {
+// if last != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *last
+// }
+//
+// // TODO: handle "after", but according to the spec it's ok to return false
+//
+// return false
+//}
+//
+//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool {
+// if first != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *first
+// }
+//
+// // TODO: handle "before", but according to the spec it's ok to return false
+//
+// return false
diff --git a/graphql/resolvers/pager_comment.go b/graphql/resolvers/pager_comment.go
new file mode 100644
index 00000000..3dd11757
--- /dev/null
+++ b/graphql/resolvers/pager_comment.go
@@ -0,0 +1,225 @@
+// This file was automatically generated by genny.
+// Any changes will be lost if this file is regenerated.
+// see https://github.com/cheekybits/genny
+
+package resolvers
+
+import (
+ "fmt"
+
+ "github.com/MichaelMure/git-bug/bug"
+)
+
+type BugCommentEdger func(value bug.Comment, offset int) Edge
+
+func BugCommentPaginate(source []bug.Comment, edger BugCommentEdger, input ConnectionInput) ([]CommentEdge, PageInfo, error) {
+ var result []CommentEdge
+ var pageInfo PageInfo
+
+ offset := 0
+
+ if input.After != nil {
+ for i, value := range source {
+ edge := edger(value, i)
+ if edge.GetCursor() == *input.After {
+ // remove all previous element including the "after" one
+ source = source[i+1:]
+ offset = i + 1
+ break
+ }
+ }
+ }
+
+ if input.Before != nil {
+ for i, value := range source {
+ edge := edger(value, i+offset)
+
+ if edge.GetCursor() == *input.Before {
+ // remove all after element including the "before" one
+ break
+ }
+
+ result = append(result, edge.(CommentEdge))
+ }
+ } else {
+ result = make([]CommentEdge, len(source))
+
+ for i, value := range source {
+ result[i] = edger(value, i+offset).(CommentEdge)
+ }
+ }
+
+ if input.First != nil {
+ if *input.First < 0 {
+ return nil, PageInfo{}, fmt.Errorf("first less than zero")
+ }
+
+ if len(result) > *input.First {
+ // Slice result to be of length first by removing edges from the end
+ result = result[:*input.First]
+ pageInfo.HasNextPage = true
+ }
+ }
+
+ if input.Last != nil {
+ if *input.Last < 0 {
+ return nil, PageInfo{}, fmt.Errorf("last less than zero")
+ }
+
+ if len(result) > *input.Last {
+ // Slice result to be of length last by removing edges from the start
+ result = result[len(result)-*input.Last:]
+ pageInfo.HasPreviousPage = true
+ }
+ }
+
+ return result, pageInfo, nil
+}
+
+// Apply the before/after cursor params to the source and return an array of edges
+//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge {
+// var result []Edge
+//
+// if input.After != nil {
+// for i, value := range source {
+// edge := edger(value)
+// if edge.Cursor() == *input.After {
+// // remove all previous element including the "after" one
+// source = source[i+1:]
+// break
+// }
+// }
+// }
+//
+// if input.Before != nil {
+// for _, value := range source {
+// edge := edger(value)
+//
+// if edge.Cursor() == *input.Before {
+// // remove all after element including the "before" one
+// break
+// }
+//
+// result = append(result, edge)
+// }
+// } else {
+// result = make([]Edge, len(source))
+//
+// for i, value := range source {
+// result[i] = edger(value)
+// }
+// }
+//
+// return result
+//}
+
+// Apply the first/last cursor params to the edges
+//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) {
+// hasPreviousPage := false
+// hasNextPage := false
+//
+// if input.First != nil {
+// if *input.First < 0 {
+// return nil, nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(edges) > *input.First {
+// // Slice result to be of length first by removing edges from the end
+// edges = edges[:*input.First]
+// hasNextPage = true
+// }
+// }
+//
+// if input.Last != nil {
+// if *input.Last < 0 {
+// return nil, nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(edges) > *input.Last {
+// // Slice result to be of length last by removing edges from the start
+// edges = edges[len(edges)-*input.Last:]
+// hasPreviousPage = true
+// }
+// }
+//
+// pageInfo := PageInfo{
+// HasNextPage: hasNextPage,
+// HasPreviousPage: hasPreviousPage,
+// }
+//
+// return edges, pageInfo, nil
+//}
+
+//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) {
+// result := ApplyCursorToEdges(allEdges, before, after)
+//
+// if first != nil {
+// if *first < 0 {
+// return nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(result) > *first {
+// // Slice result to be of length first by removing edges from the end
+// result = result[:*first]
+// }
+// }
+//
+// if last != nil {
+// if *last < 0 {
+// return nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(result) > *last {
+// // Slice result to be of length last by removing edges from the start
+// result = result[len(result)-*last:]
+// }
+// }
+//
+// return result, nil
+//}
+
+//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge {
+// result := allEdges
+//
+// if after != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *after {
+// // remove all previous element including the "after" one
+// result = result[i+1:]
+// break
+// }
+// }
+// }
+//
+// if before != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *before {
+// // remove all after element including the "before" one
+// result = result[:i]
+// }
+// }
+// }
+//
+// return result
+//}
+
+//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool {
+// if last != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *last
+// }
+//
+// // TODO: handle "after", but according to the spec it's ok to return false
+//
+// return false
+//}
+//
+//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool {
+// if first != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *first
+// }
+//
+// // TODO: handle "before", but according to the spec it's ok to return false
+//
+// return false
diff --git a/graphql/resolvers/pager_operation.go b/graphql/resolvers/pager_operation.go
new file mode 100644
index 00000000..fe4eebc2
--- /dev/null
+++ b/graphql/resolvers/pager_operation.go
@@ -0,0 +1,225 @@
+// This file was automatically generated by genny.
+// Any changes will be lost if this file is regenerated.
+// see https://github.com/cheekybits/genny
+
+package resolvers
+
+import (
+ "fmt"
+
+ "github.com/MichaelMure/git-bug/bug"
+)
+
+type BugOperationEdger func(value bug.Operation, offset int) Edge
+
+func BugOperationPaginate(source []bug.Operation, edger BugOperationEdger, input ConnectionInput) ([]OperationEdge, PageInfo, error) {
+ var result []OperationEdge
+ var pageInfo PageInfo
+
+ offset := 0
+
+ if input.After != nil {
+ for i, value := range source {
+ edge := edger(value, i)
+ if edge.GetCursor() == *input.After {
+ // remove all previous element including the "after" one
+ source = source[i+1:]
+ offset = i + 1
+ break
+ }
+ }
+ }
+
+ if input.Before != nil {
+ for i, value := range source {
+ edge := edger(value, i+offset)
+
+ if edge.GetCursor() == *input.Before {
+ // remove all after element including the "before" one
+ break
+ }
+
+ result = append(result, edge.(OperationEdge))
+ }
+ } else {
+ result = make([]OperationEdge, len(source))
+
+ for i, value := range source {
+ result[i] = edger(value, i+offset).(OperationEdge)
+ }
+ }
+
+ if input.First != nil {
+ if *input.First < 0 {
+ return nil, PageInfo{}, fmt.Errorf("first less than zero")
+ }
+
+ if len(result) > *input.First {
+ // Slice result to be of length first by removing edges from the end
+ result = result[:*input.First]
+ pageInfo.HasNextPage = true
+ }
+ }
+
+ if input.Last != nil {
+ if *input.Last < 0 {
+ return nil, PageInfo{}, fmt.Errorf("last less than zero")
+ }
+
+ if len(result) > *input.Last {
+ // Slice result to be of length last by removing edges from the start
+ result = result[len(result)-*input.Last:]
+ pageInfo.HasPreviousPage = true
+ }
+ }
+
+ return result, pageInfo, nil
+}
+
+// Apply the before/after cursor params to the source and return an array of edges
+//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge {
+// var result []Edge
+//
+// if input.After != nil {
+// for i, value := range source {
+// edge := edger(value)
+// if edge.Cursor() == *input.After {
+// // remove all previous element including the "after" one
+// source = source[i+1:]
+// break
+// }
+// }
+// }
+//
+// if input.Before != nil {
+// for _, value := range source {
+// edge := edger(value)
+//
+// if edge.Cursor() == *input.Before {
+// // remove all after element including the "before" one
+// break
+// }
+//
+// result = append(result, edge)
+// }
+// } else {
+// result = make([]Edge, len(source))
+//
+// for i, value := range source {
+// result[i] = edger(value)
+// }
+// }
+//
+// return result
+//}
+
+// Apply the first/last cursor params to the edges
+//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) {
+// hasPreviousPage := false
+// hasNextPage := false
+//
+// if input.First != nil {
+// if *input.First < 0 {
+// return nil, nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(edges) > *input.First {
+// // Slice result to be of length first by removing edges from the end
+// edges = edges[:*input.First]
+// hasNextPage = true
+// }
+// }
+//
+// if input.Last != nil {
+// if *input.Last < 0 {
+// return nil, nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(edges) > *input.Last {
+// // Slice result to be of length last by removing edges from the start
+// edges = edges[len(edges)-*input.Last:]
+// hasPreviousPage = true
+// }
+// }
+//
+// pageInfo := PageInfo{
+// HasNextPage: hasNextPage,
+// HasPreviousPage: hasPreviousPage,
+// }
+//
+// return edges, pageInfo, nil
+//}
+
+//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) {
+// result := ApplyCursorToEdges(allEdges, before, after)
+//
+// if first != nil {
+// if *first < 0 {
+// return nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(result) > *first {
+// // Slice result to be of length first by removing edges from the end
+// result = result[:*first]
+// }
+// }
+//
+// if last != nil {
+// if *last < 0 {
+// return nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(result) > *last {
+// // Slice result to be of length last by removing edges from the start
+// result = result[len(result)-*last:]
+// }
+// }
+//
+// return result, nil
+//}
+
+//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge {
+// result := allEdges
+//
+// if after != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *after {
+// // remove all previous element including the "after" one
+// result = result[i+1:]
+// break
+// }
+// }
+// }
+//
+// if before != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *before {
+// // remove all after element including the "before" one
+// result = result[:i]
+// }
+// }
+// }
+//
+// return result
+//}
+
+//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool {
+// if last != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *last
+// }
+//
+// // TODO: handle "after", but according to the spec it's ok to return false
+//
+// return false
+//}
+//
+//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool {
+// if first != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *first
+// }
+//
+// // TODO: handle "before", but according to the spec it's ok to return false
+//
+// return false
diff --git a/graphql/resolvers/pagers.go b/graphql/resolvers/pagers.go
new file mode 100644
index 00000000..378dcdbf
--- /dev/null
+++ b/graphql/resolvers/pagers.go
@@ -0,0 +1,51 @@
+//go:generate genny -in=pagers_template.go -out=pager_bug.go gen "NodeType=bug.Snapshot EdgeType=BugEdge"
+//go:generate genny -in=pagers_template.go -out=pager_operation.go gen "NodeType=bug.Operation EdgeType=OperationEdge"
+//go:generate genny -in=pagers_template.go -out=pager_comment.go gen "NodeType=bug.Comment EdgeType=CommentEdge"
+
+package resolvers
+
+import (
+ "encoding/base64"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+const cursorPrefix = "cursor:"
+
+type Edge interface {
+ GetCursor() string
+}
+
+// Creates the cursor string from an offset
+func offsetToCursor(offset int) string {
+ str := fmt.Sprintf("%v%v", cursorPrefix, offset)
+ return base64.StdEncoding.EncodeToString([]byte(str))
+}
+
+// Re-derives the offset from the cursor string.
+func cursorToOffset(cursor string) (int, error) {
+ str := ""
+ b, err := base64.StdEncoding.DecodeString(cursor)
+ if err == nil {
+ str = string(b)
+ }
+ str = strings.Replace(str, cursorPrefix, "", -1)
+ offset, err := strconv.Atoi(str)
+ if err != nil {
+ return 0, fmt.Errorf("Invalid cursor")
+ }
+ return offset, nil
+}
+
+func (e OperationEdge) GetCursor() string {
+ return e.Cursor
+}
+
+func (e BugEdge) GetCursor() string {
+ return e.Cursor
+}
+
+func (e CommentEdge) GetCursor() string {
+ return e.Cursor
+}
diff --git a/graphql/resolvers/pagers_template.go b/graphql/resolvers/pagers_template.go
new file mode 100644
index 00000000..0ca7de75
--- /dev/null
+++ b/graphql/resolvers/pagers_template.go
@@ -0,0 +1,224 @@
+package resolvers
+
+import (
+ "fmt"
+ "github.com/cheekybits/genny/generic"
+)
+
+type NodeType generic.Type
+type EdgeType generic.Type
+
+type NodeTypeEdger func(value NodeType, offset int) Edge
+
+func NodeTypePaginate(source []NodeType, edger NodeTypeEdger, input ConnectionInput) ([]EdgeType, PageInfo, error) {
+ var result []EdgeType
+ var pageInfo PageInfo
+
+ offset := 0
+
+ if input.After != nil {
+ for i, value := range source {
+ edge := edger(value, i)
+ if edge.GetCursor() == *input.After {
+ // remove all previous element including the "after" one
+ source = source[i+1:]
+ offset = i + 1
+ break
+ }
+ }
+ }
+
+ if input.Before != nil {
+ for i, value := range source {
+ edge := edger(value, i+offset)
+
+ if edge.GetCursor() == *input.Before {
+ // remove all after element including the "before" one
+ break
+ }
+
+ result = append(result, edge.(EdgeType))
+ }
+ } else {
+ result = make([]EdgeType, len(source))
+
+ for i, value := range source {
+ result[i] = edger(value, i+offset).(EdgeType)
+ }
+ }
+
+ if input.First != nil {
+ if *input.First < 0 {
+ return nil, PageInfo{}, fmt.Errorf("first less than zero")
+ }
+
+ if len(result) > *input.First {
+ // Slice result to be of length first by removing edges from the end
+ result = result[:*input.First]
+ pageInfo.HasNextPage = true
+ }
+ }
+
+ if input.Last != nil {
+ if *input.Last < 0 {
+ return nil, PageInfo{}, fmt.Errorf("last less than zero")
+ }
+
+ if len(result) > *input.Last {
+ // Slice result to be of length last by removing edges from the start
+ result = result[len(result)-*input.Last:]
+ pageInfo.HasPreviousPage = true
+ }
+ }
+
+ return result, pageInfo, nil
+}
+
+// Apply the before/after cursor params to the source and return an array of edges
+//func ApplyCursorToEdges(source []interface{}, edger Edger, input ConnectionInput) []Edge {
+// var result []Edge
+//
+// if input.After != nil {
+// for i, value := range source {
+// edge := edger(value)
+// if edge.Cursor() == *input.After {
+// // remove all previous element including the "after" one
+// source = source[i+1:]
+// break
+// }
+// }
+// }
+//
+// if input.Before != nil {
+// for _, value := range source {
+// edge := edger(value)
+//
+// if edge.Cursor() == *input.Before {
+// // remove all after element including the "before" one
+// break
+// }
+//
+// result = append(result, edge)
+// }
+// } else {
+// result = make([]Edge, len(source))
+//
+// for i, value := range source {
+// result[i] = edger(value)
+// }
+// }
+//
+// return result
+//}
+
+// Apply the first/last cursor params to the edges
+//func EdgesToReturn(edges []Edge, input ConnectionInput) ([]Edge, PageInfo, error) {
+// hasPreviousPage := false
+// hasNextPage := false
+//
+// if input.First != nil {
+// if *input.First < 0 {
+// return nil, nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(edges) > *input.First {
+// // Slice result to be of length first by removing edges from the end
+// edges = edges[:*input.First]
+// hasNextPage = true
+// }
+// }
+//
+// if input.Last != nil {
+// if *input.Last < 0 {
+// return nil, nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(edges) > *input.Last {
+// // Slice result to be of length last by removing edges from the start
+// edges = edges[len(edges)-*input.Last:]
+// hasPreviousPage = true
+// }
+// }
+//
+// pageInfo := PageInfo{
+// HasNextPage: hasNextPage,
+// HasPreviousPage: hasPreviousPage,
+// }
+//
+// return edges, pageInfo, nil
+//}
+
+//func EdgesToReturn(allEdges []Edge, before *cursor, after *cursor, first *int, last *int) ([]Edge, error) {
+// result := ApplyCursorToEdges(allEdges, before, after)
+//
+// if first != nil {
+// if *first < 0 {
+// return nil, fmt.Errorf("first less than zero")
+// }
+//
+// if len(result) > *first {
+// // Slice result to be of length first by removing edges from the end
+// result = result[:*first]
+// }
+// }
+//
+// if last != nil {
+// if *last < 0 {
+// return nil, fmt.Errorf("last less than zero")
+// }
+//
+// if len(result) > *last {
+// // Slice result to be of length last by removing edges from the start
+// result = result[len(result)-*last:]
+// }
+// }
+//
+// return result, nil
+//}
+
+//func ApplyCursorToEdges(allEdges []Edge, before *cursor, after *cursor) []Edge {
+// result := allEdges
+//
+// if after != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *after {
+// // remove all previous element including the "after" one
+// result = result[i+1:]
+// break
+// }
+// }
+// }
+//
+// if before != nil {
+// for i, edge := range result {
+// if edge.Cursor() == *before {
+// // remove all after element including the "before" one
+// result = result[:i]
+// }
+// }
+// }
+//
+// return result
+//}
+
+//func HasPreviousPage(allEdges []Edge, before *cursor, after *cursor, last *int) bool {
+// if last != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *last
+// }
+//
+// // TODO: handle "after", but according to the spec it's ok to return false
+//
+// return false
+//}
+//
+//func HasNextPage(allEdges []Edge, before *cursor, after *cursor, first *int) bool {
+// if first != nil {
+// edges := ApplyCursorToEdges(allEdges, before, after)
+// return len(edges) > *first
+// }
+//
+// // TODO: handle "before", but according to the spec it's ok to return false
+//
+// return false
+//}
diff --git a/graphql/resolvers/query.go b/graphql/resolvers/query.go
new file mode 100644
index 00000000..cceca334
--- /dev/null
+++ b/graphql/resolvers/query.go
@@ -0,0 +1,36 @@
+package resolvers
+
+import (
+ "context"
+ "github.com/MichaelMure/git-bug/cache"
+)
+
+type rootQueryResolver struct {
+ cache cache.Cacher
+}
+
+func (r rootQueryResolver) DefaultRepository(ctx context.Context) (*repoResolver, error) {
+ repo, err := r.cache.DefaultRepo()
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &repoResolver{
+ cache: r.cache,
+ repo: repo,
+ }, nil
+}
+
+func (r rootQueryResolver) Repository(ctx context.Context, id string) (*repoResolver, error) {
+ repo, err := r.cache.ResolveRepo(id)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &repoResolver{
+ cache: r.cache,
+ repo: repo,
+ }, nil
+}
diff --git a/graphql/resolvers/repo.go b/graphql/resolvers/repo.go
new file mode 100644
index 00000000..14019b65
--- /dev/null
+++ b/graphql/resolvers/repo.go
@@ -0,0 +1,26 @@
+package resolvers
+
+import (
+ "context"
+ "github.com/MichaelMure/git-bug/bug"
+ "github.com/MichaelMure/git-bug/cache"
+)
+
+type repoResolver struct {
+ cache cache.Cacher
+ repo cache.RepoCacher
+}
+
+func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input ConnectionInput) (BugConnection, error) {
+ panic("implement me")
+}
+
+func (repoResolver) Bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) {
+ b, err := obj.repo.ResolveBugPrefix(prefix)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return b.Snapshot(), nil
+}
diff --git a/graphql/resolvers/root.go b/graphql/resolvers/root.go
new file mode 100644
index 00000000..e5f83060
--- /dev/null
+++ b/graphql/resolvers/root.go
@@ -0,0 +1,53 @@
+package resolvers
+
+import (
+ "github.com/MichaelMure/git-bug/cache"
+)
+
+type RootResolver struct {
+ cache.RootCache
+}
+
+func NewRootResolver() *RootResolver {
+ return &RootResolver{
+ RootCache: cache.NewCache(),
+ }
+}
+
+func (r RootResolver) Query() QueryResolver {
+ return &rootQueryResolver{
+ cache: &r.RootCache,
+ }
+}
+
+func (RootResolver) AddCommentOperation() AddCommentOperationResolver {
+ return &addCommentOperationResolver{}
+}
+
+func (r RootResolver) Bug() BugResolver {
+ return &bugResolver{
+ cache: &r.RootCache,
+ }
+}
+
+func (RootResolver) CreateOperation() CreateOperationResolver {
+ return &createOperationResolver{}
+}
+
+func (RootResolver) LabelChangeOperation() LabelChangeOperationResolver {
+ return &labelChangeOperation{}
+}
+
+func (r RootResolver) Repository() RepositoryResolver {
+ return &repoResolver{
+ cache: &r.RootCache,
+ }
+}
+
+func (RootResolver) SetStatusOperation() SetStatusOperationResolver {
+ return &setStatusOperationResolver{}
+}
+
+func (RootResolver) SetTitleOperation() SetTitleOperationResolver {
+ return &setTitleOperationResolver{}
+}
diff --git a/graphql/schema.go b/graphql/schema.go
deleted file mode 100644
index 8312933d..00000000
--- a/graphql/schema.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package graphql
-
-import (
- "github.com/MichaelMure/git-bug/bug"
- "github.com/MichaelMure/git-bug/repository"
- "github.com/graphql-go/graphql"
-)
-
-func graphqlSchema() (graphql.Schema, error) {
- fields := graphql.Fields{
- "bug": &graphql.Field{
- Type: bugType,
- Args: graphql.FieldConfigArgument{
- "id": &graphql.ArgumentConfig{
- Type: bugIdScalar,
- },
- },
- Resolve: func(p graphql.ResolveParams) (interface{}, error) {
- repo := p.Context.Value("repo").(repository.Repo)
- id, _ := p.Args["id"].(string)
- b, err := bug.FindLocalBug(repo, id)
- if err != nil {
- return nil, err
- }
-
- snapshot := b.Compile()
-
- return snapshot, nil
- },
- },
- // TODO: provide a relay-like schema with pagination
- "allBugs": &graphql.Field{
- Type: graphql.NewList(bugType),
- Resolve: func(p graphql.ResolveParams) (interface{}, error) {
- repo := p.Context.Value("repo").(repository.Repo)
-
- var snapshots []bug.Snapshot
-
- for sb := range bug.ReadAllLocalBugs(repo) {
- if sb.Err != nil {
- return nil, sb.Err
- }
-
- snapshots = append(snapshots, sb.Bug.Compile())
- }
-
- return snapshots, nil
- },
- },
- }
- rootQuery := graphql.ObjectConfig{Name: "RootQuery", Fields: fields}
- schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
- return graphql.NewSchema(schemaConfig)
-}
diff --git a/graphql/schema.graphql b/graphql/schema.graphql
new file mode 100644
index 00000000..47716488
--- /dev/null
+++ b/graphql/schema.graphql
@@ -0,0 +1,181 @@
+scalar Time
+scalar Label
+
+# 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
+}
+
+input ConnectionInput {
+ # 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
+}
+
+# Represents an person in a git object.
+type Person {
+ # The email of the person.
+ email: String
+
+ # The name of the person.
+ name: String
+}
+
+
+type CommentConnection {
+ edges: [CommentEdge!]!
+ pageInfo: PageInfo!
+ totalCount: Int!
+}
+
+type CommentEdge {
+ cursor: String!
+ node: Comment!
+}
+
+# Represents a comment on a bug.
+type Comment implements Authored {
+ # The author of this comment.
+ author: Person!
+
+ # The message of this comment.
+ message: String!
+}
+
+enum Status {
+ OPEN
+ CLOSED
+}
+
+# An object that has an author.
+interface Authored {
+ # The author of this object.
+ author: Person!
+}
+
+type OperationConnection {
+ edges: [OperationEdge!]!
+ pageInfo: PageInfo!
+ totalCount: Int!
+}
+
+type OperationEdge {
+ cursor: String!
+ node: OperationUnion!
+}
+
+# An operation applied to a bug.
+interface Operation {
+ # The operations author.
+ author: Person!
+
+ # The datetime when this operation was issued.
+ date: Time!
+}
+
+type CreateOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ title: String!
+ message: String!
+}
+
+type SetTitleOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ title: String!
+}
+
+type AddCommentOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ message: String!
+}
+
+type SetStatusOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ status: Status!
+}
+
+type LabelChangeOperation implements Operation, Authored {
+ author: Person!
+ date: Time!
+
+ added: [Label!]!
+ removed: [Label!]!
+}
+
+union OperationUnion =
+ CreateOperation
+ | SetTitleOperation
+ | AddCommentOperation
+ | SetStatusOperation
+ | LabelChangeOperation
+
+# The connection type for Bug.
+type BugConnection {
+ # A list of edges.
+ edges: [BugEdge]!
+
+ # 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!
+}
+
+type Bug {
+ id: String!
+ humanId: String!
+ title: String!
+ status: Status!
+
+ # A list of labels associated with the repository.
+ labels: [Label!]!
+
+ comments(input: ConnectionInput!): CommentConnection!
+
+ operations(input: ConnectionInput!): OperationConnection!
+}
+
+type Repository {
+ allBugs(input: ConnectionInput!): BugConnection!
+ bug(prefix: String!): Bug
+}
+
+type Query {
+ defaultRepository: Repository
+ repository(id: String!): Repository
+}
diff --git a/graphql/types.go b/graphql/types.go
deleted file mode 100644
index f1161687..00000000
--- a/graphql/types.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package graphql
-
-import (
- "fmt"
-
- "github.com/graphql-go/graphql"
- "github.com/graphql-go/graphql/language/ast"
-
- "github.com/MichaelMure/git-bug/bug"
-)
-
-func coerceString(value interface{}) interface{} {
- if v, ok := value.(*string); ok {
- return *v
- }
- return fmt.Sprintf("%v", value)
-}
-
-var bugIdScalar = graphql.NewScalar(graphql.ScalarConfig{
- Name: "BugID",
- Description: "TODO",
- Serialize: coerceString,
- ParseValue: coerceString,
- ParseLiteral: func(valueAST ast.Value) interface{} {
- switch valueAST := valueAST.(type) {
- case *ast.StringValue:
- return valueAST.Value
- }
- return nil
- },
-})
-
-// Internally, it's the Snapshot
-var bugType = graphql.NewObject(graphql.ObjectConfig{
- Name: "Bug",
- Fields: graphql.Fields{
- "id": &graphql.Field{
- Type: bugIdScalar,
- Resolve: func(p graphql.ResolveParams) (interface{}, error) {
- return p.Source.(bug.Snapshot).Id(), nil
- },
- },
- "status": &graphql.Field{
- Type: graphql.String,
- },
- "title": &graphql.Field{
- Type: graphql.String,
- },
- "comments": &graphql.Field{
- Type: graphql.NewList(commentType),
- },
- "labels": &graphql.Field{
- Type: graphql.NewList(graphql.String),
- Resolve: func(p graphql.ResolveParams) (interface{}, error) {
- return p.Source.(bug.Snapshot).Labels, nil
- },
- },
- // TODO: operations
- },
-})
-
-var commentType = graphql.NewObject(graphql.ObjectConfig{
- Name: "Comment",
- Fields: graphql.Fields{
- "author": &graphql.Field{
- Type: personType,
- },
- "message": &graphql.Field{
- Type: graphql.String,
- },
- // TODO: time
- },
-})
-
-var personType = graphql.NewObject(graphql.ObjectConfig{
- Name: "Person",
- Fields: graphql.Fields{
- "name": &graphql.Field{
- Type: graphql.String,
- },
- "email": &graphql.Field{
- Type: graphql.String,
- },
- },
-})