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