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/common"
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 (r repoResolver) AllBoards(ctx context.Context, obj *models.Repository, after *string, before *string, first *int, last *int, query *string) (*models.BoardConnection, error) {
25 input := models.ConnectionInput{
26 Before: before,
27 After: after,
28 First: first,
29 Last: last,
30 }
31
32 // Simply pass a []string with the ids to the pagination algorithm
33 source := obj.Repo.Boards().AllIds()
34
35 // The edger create a custom edge holding just the id
36 edger := func(id entity.Id, offset int) connections.Edge {
37 return connections.LazyBoardEdge{
38 Id: id,
39 Cursor: connections.OffsetToCursor(offset),
40 }
41 }
42
43 // The conMaker will finally load and compile boards from git to replace the selected edges
44 conMaker := func(lazyBoardEdges []*connections.LazyBoardEdge, lazyNode []entity.Id, info *models.PageInfo, totalCount int) (*models.BoardConnection, error) {
45 edges := make([]*models.BoardEdge, len(lazyBoardEdges))
46 nodes := make([]models.BoardWrapper, len(lazyBoardEdges))
47
48 for k, lazyBoardEdge := range lazyBoardEdges {
49 excerpt, err := obj.Repo.Boards().ResolveExcerpt(lazyBoardEdge.Id)
50 if err != nil {
51 return nil, err
52 }
53
54 i := models.NewLazyBoard(obj.Repo, excerpt)
55
56 edges[k] = &models.BoardEdge{
57 Cursor: lazyBoardEdge.Cursor,
58 Node: i,
59 }
60 nodes[k] = i
61 }
62
63 return &models.BoardConnection{
64 Edges: edges,
65 Nodes: nodes,
66 PageInfo: info,
67 TotalCount: totalCount,
68 }, nil
69 }
70
71 return connections.Connection(source, edger, conMaker, input)
72}
73
74func (r repoResolver) Board(ctx context.Context, obj *models.Repository, prefix string) (models.BoardWrapper, error) {
75 excerpt, err := obj.Repo.Boards().ResolveExcerptPrefix(prefix)
76 if err != nil {
77 return nil, err
78 }
79
80 return models.NewLazyBoard(obj.Repo, excerpt), nil
81}
82
83func (repoResolver) AllBugs(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int, queryStr *string) (*models.BugConnection, error) {
84 input := models.ConnectionInput{
85 Before: before,
86 After: after,
87 First: first,
88 Last: last,
89 }
90
91 var q *query.Query
92 if queryStr != nil {
93 query2, err := query.Parse(*queryStr)
94 if err != nil {
95 return nil, err
96 }
97 q = query2
98 } else {
99 q = query.NewQuery()
100 }
101
102 // Simply pass a []string with the ids to the pagination algorithm
103 source, err := obj.Repo.Bugs().Query(q)
104 if err != nil {
105 return nil, err
106 }
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.LazyBugEdge{
111 Id: id,
112 Cursor: connections.OffsetToCursor(offset),
113 }
114 }
115
116 // The conMaker will finally load and compile bugs from git to replace the selected edges
117 conMaker := func(lazyBugEdges []*connections.LazyBugEdge, lazyNode []entity.Id, info *models.PageInfo, totalCount int) (*models.BugConnection, error) {
118 edges := make([]*models.BugEdge, len(lazyBugEdges))
119 nodes := make([]models.BugWrapper, len(lazyBugEdges))
120
121 for i, lazyBugEdge := range lazyBugEdges {
122 excerpt, err := obj.Repo.Bugs().ResolveExcerpt(lazyBugEdge.Id)
123 if err != nil {
124 return nil, err
125 }
126
127 b := models.NewLazyBug(obj.Repo, excerpt)
128
129 edges[i] = &models.BugEdge{
130 Cursor: lazyBugEdge.Cursor,
131 Node: b,
132 }
133 nodes[i] = b
134 }
135
136 return &models.BugConnection{
137 Edges: edges,
138 Nodes: nodes,
139 PageInfo: info,
140 TotalCount: totalCount,
141 }, nil
142 }
143
144 return connections.Connection(source, edger, conMaker, input)
145}
146
147func (repoResolver) Bug(_ context.Context, obj *models.Repository, prefix string) (models.BugWrapper, error) {
148 excerpt, err := obj.Repo.Bugs().ResolveExcerptPrefix(prefix)
149 if err != nil {
150 return nil, err
151 }
152
153 return models.NewLazyBug(obj.Repo, excerpt), nil
154}
155
156func (repoResolver) AllIdentities(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int) (*models.IdentityConnection, error) {
157 input := models.ConnectionInput{
158 Before: before,
159 After: after,
160 First: first,
161 Last: last,
162 }
163
164 // Simply pass a []string with the ids to the pagination algorithm
165 source := obj.Repo.Identities().AllIds()
166
167 // The edger create a custom edge holding just the id
168 edger := func(id entity.Id, offset int) connections.Edge {
169 return connections.LazyIdentityEdge{
170 Id: id,
171 Cursor: connections.OffsetToCursor(offset),
172 }
173 }
174
175 // The conMaker will finally load and compile identities from git to replace the selected edges
176 conMaker := func(lazyIdentityEdges []*connections.LazyIdentityEdge, lazyNode []entity.Id, info *models.PageInfo, totalCount int) (*models.IdentityConnection, error) {
177 edges := make([]*models.IdentityEdge, len(lazyIdentityEdges))
178 nodes := make([]models.IdentityWrapper, len(lazyIdentityEdges))
179
180 for k, lazyIdentityEdge := range lazyIdentityEdges {
181 excerpt, err := obj.Repo.Identities().ResolveExcerpt(lazyIdentityEdge.Id)
182 if err != nil {
183 return nil, err
184 }
185
186 i := models.NewLazyIdentity(obj.Repo, excerpt)
187
188 edges[k] = &models.IdentityEdge{
189 Cursor: lazyIdentityEdge.Cursor,
190 Node: i,
191 }
192 nodes[k] = i
193 }
194
195 return &models.IdentityConnection{
196 Edges: edges,
197 Nodes: nodes,
198 PageInfo: info,
199 TotalCount: totalCount,
200 }, nil
201 }
202
203 return connections.Connection(source, edger, conMaker, input)
204}
205
206func (repoResolver) Identity(_ context.Context, obj *models.Repository, prefix string) (models.IdentityWrapper, error) {
207 excerpt, err := obj.Repo.Identities().ResolveExcerptPrefix(prefix)
208 if err != nil {
209 return nil, err
210 }
211
212 return models.NewLazyIdentity(obj.Repo, excerpt), nil
213}
214
215func (repoResolver) UserIdentity(ctx context.Context, obj *models.Repository) (models.IdentityWrapper, error) {
216 id, err := auth.UserFromCtx(ctx, obj.Repo)
217 if err == auth.ErrNotAuthenticated {
218 return nil, nil
219 } else if err != nil {
220 return nil, err
221 }
222 return models.NewLoadedIdentity(id.Identity), nil
223}
224
225func (repoResolver) ValidLabels(_ context.Context, obj *models.Repository, after *string, before *string, first *int, last *int) (*models.LabelConnection, error) {
226 input := models.ConnectionInput{
227 Before: before,
228 After: after,
229 First: first,
230 Last: last,
231 }
232
233 edger := func(label common.Label, offset int) connections.Edge {
234 return models.LabelEdge{
235 Node: label,
236 Cursor: connections.OffsetToCursor(offset),
237 }
238 }
239
240 conMaker := func(edges []*models.LabelEdge, nodes []common.Label, info *models.PageInfo, totalCount int) (*models.LabelConnection, error) {
241 return &models.LabelConnection{
242 Edges: edges,
243 Nodes: nodes,
244 PageInfo: info,
245 TotalCount: totalCount,
246 }, nil
247 }
248
249 return connections.Connection(obj.Repo.Bugs().ValidLabels(), edger, conMaker, input)
250}