1package resolvers
2
3import (
4 "context"
5
6 "github.com/git-bug/git-bug/api/auth"
7 "github.com/git-bug/git-bug/api/graphql/connections"
8 "github.com/git-bug/git-bug/api/graphql/graph"
9 "github.com/git-bug/git-bug/api/graphql/models"
10 "github.com/git-bug/git-bug/entities/bug"
11 "github.com/git-bug/git-bug/entity"
12 "github.com/git-bug/git-bug/query"
13)
14
15var _ graph.RepositoryResolver = &repoResolver{}
16
17type repoResolver struct{}
18
19func (repoResolver) Name(_ context.Context, obj *models.Repository) (*string, error) {
20 name := obj.Repo.Name()
21 return &name, nil
22}
23
24func (repoResolver) AllBugs(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int, queryStr *string) (*models.BugConnection, error) {
25 input := models.ConnectionInput{
26 Before: before,
27 After: after,
28 First: first,
29 Last: last,
30 }
31
32 var q *query.Query
33 if queryStr != nil {
34 query2, err := query.Parse(*queryStr)
35 if err != nil {
36 return nil, err
37 }
38 q = query2
39 } else {
40 q = query.NewQuery()
41 }
42
43 // Simply pass a []string with the ids to the pagination algorithm
44 source, err := obj.Repo.Bugs().Query(q)
45 if err != nil {
46 return nil, err
47 }
48
49 // The edger create a custom edge holding just the id
50 edger := func(id entity.Id, offset int) connections.Edge {
51 return connections.LazyBugEdge{
52 Id: id,
53 Cursor: connections.OffsetToCursor(offset),
54 }
55 }
56
57 // The conMaker will finally load and compile bugs from git to replace the selected edges
58 conMaker := func(lazyBugEdges []*connections.LazyBugEdge, lazyNode []entity.Id, info *models.PageInfo, totalCount int) (*models.BugConnection, error) {
59 edges := make([]*models.BugEdge, len(lazyBugEdges))
60 nodes := make([]models.BugWrapper, len(lazyBugEdges))
61
62 for i, lazyBugEdge := range lazyBugEdges {
63 excerpt, err := obj.Repo.Bugs().ResolveExcerpt(lazyBugEdge.Id)
64 if err != nil {
65 return nil, err
66 }
67
68 b := models.NewLazyBug(obj.Repo, excerpt)
69
70 edges[i] = &models.BugEdge{
71 Cursor: lazyBugEdge.Cursor,
72 Node: b,
73 }
74 nodes[i] = b
75 }
76
77 return &models.BugConnection{
78 Edges: edges,
79 Nodes: nodes,
80 PageInfo: info,
81 TotalCount: totalCount,
82 }, nil
83 }
84
85 return connections.LazyBugCon(source, edger, conMaker, input)
86}
87
88func (repoResolver) Bug(_ context.Context, obj *models.Repository, prefix string) (models.BugWrapper, error) {
89 excerpt, err := obj.Repo.Bugs().ResolveExcerptPrefix(prefix)
90 if err != nil {
91 return nil, err
92 }
93
94 return models.NewLazyBug(obj.Repo, excerpt), nil
95}
96
97func (repoResolver) AllIdentities(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int) (*models.IdentityConnection, error) {
98 input := models.ConnectionInput{
99 Before: before,
100 After: after,
101 First: first,
102 Last: last,
103 }
104
105 // Simply pass a []string with the ids to the pagination algorithm
106 source := obj.Repo.Identities().AllIds()
107
108 // The edger create a custom edge holding just the id
109 edger := func(id entity.Id, offset int) connections.Edge {
110 return connections.LazyIdentityEdge{
111 Id: id,
112 Cursor: connections.OffsetToCursor(offset),
113 }
114 }
115
116 // The conMaker will finally load and compile identities from git to replace the selected edges
117 conMaker := func(lazyIdentityEdges []*connections.LazyIdentityEdge, lazyNode []entity.Id, info *models.PageInfo, totalCount int) (*models.IdentityConnection, error) {
118 edges := make([]*models.IdentityEdge, len(lazyIdentityEdges))
119 nodes := make([]models.IdentityWrapper, len(lazyIdentityEdges))
120
121 for k, lazyIdentityEdge := range lazyIdentityEdges {
122 excerpt, err := obj.Repo.Identities().ResolveExcerpt(lazyIdentityEdge.Id)
123 if err != nil {
124 return nil, err
125 }
126
127 i := models.NewLazyIdentity(obj.Repo, excerpt)
128
129 edges[k] = &models.IdentityEdge{
130 Cursor: lazyIdentityEdge.Cursor,
131 Node: i,
132 }
133 nodes[k] = i
134 }
135
136 return &models.IdentityConnection{
137 Edges: edges,
138 Nodes: nodes,
139 PageInfo: info,
140 TotalCount: totalCount,
141 }, nil
142 }
143
144 return connections.LazyIdentityCon(source, edger, conMaker, input)
145}
146
147func (repoResolver) Identity(_ context.Context, obj *models.Repository, prefix string) (models.IdentityWrapper, error) {
148 excerpt, err := obj.Repo.Identities().ResolveExcerptPrefix(prefix)
149 if err != nil {
150 return nil, err
151 }
152
153 return models.NewLazyIdentity(obj.Repo, excerpt), nil
154}
155
156func (repoResolver) UserIdentity(ctx context.Context, obj *models.Repository) (models.IdentityWrapper, error) {
157 id, err := auth.UserFromCtx(ctx, obj.Repo)
158 if err == auth.ErrNotAuthenticated {
159 return nil, nil
160 } else if err != nil {
161 return nil, err
162 }
163 return models.NewLoadedIdentity(id.Identity), nil
164}
165
166func (repoResolver) ValidLabels(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int) (*models.LabelConnection, error) {
167 input := models.ConnectionInput{
168 Before: before,
169 After: after,
170 First: first,
171 Last: last,
172 }
173
174 edger := func(label bug.Label, offset int) connections.Edge {
175 return models.LabelEdge{
176 Node: label,
177 Cursor: connections.OffsetToCursor(offset),
178 }
179 }
180
181 conMaker := func(edges []*models.LabelEdge, nodes []bug.Label, info *models.PageInfo, totalCount int) (*models.LabelConnection, error) {
182 return &models.LabelConnection{
183 Edges: edges,
184 Nodes: nodes,
185 PageInfo: info,
186 TotalCount: totalCount,
187 }, nil
188 }
189
190 return connections.LabelCon(obj.Repo.Bugs().ValidLabels(), edger, conMaker, input)
191}