+48
-18
appview/db/issues.go
+48
-18
appview/db/issues.go
···
12
12
OwnerDid string
13
13
IssueId int
14
14
IssueAt string
15
-
Created *time.Time
15
+
Created time.Time
16
16
Title string
17
17
Body string
18
18
Open bool
19
+
20
+
// optionally, populate this when querying for reverse mappings
21
+
// like comment counts, parent repo etc.
19
22
Metadata *IssueMetadata
20
23
}
21
24
22
25
type IssueMetadata struct {
23
26
CommentCount int
27
+
Repo *Repo
24
28
// labels, assignee etc.
25
29
}
26
30
···
143
147
if err != nil {
144
148
return nil, err
145
149
}
146
-
issue.Created = &createdTime
150
+
issue.Created = createdTime
147
151
issue.Metadata = &metadata
148
152
149
153
issues = append(issues, issue)
···
156
160
return issues, nil
157
161
}
158
162
159
-
func GetIssuesByOwnerDid(e Execer, ownerDid string) ([]Issue, error) {
163
+
// timeframe here is directly passed into the sql query filter, and any
164
+
// timeframe in the past should be negative; e.g.: "-3 months"
165
+
func GetIssuesByOwnerDid(e Execer, ownerDid string, timeframe string) ([]Issue, error) {
160
166
var issues []Issue
161
167
162
168
rows, err := e.Query(
···
168
174
i.title,
169
175
i.body,
170
176
i.open,
171
-
count(c.id)
177
+
r.did,
178
+
r.name,
179
+
r.knot,
180
+
r.rkey,
181
+
r.created
172
182
from
173
183
issues i
174
-
left join
175
-
comments c on i.repo_at = c.repo_at and i.issue_id = c.issue_id
184
+
join
185
+
repos r on i.repo_at = r.at_uri
176
186
where
177
-
i.owner_did = ?
178
-
group by
179
-
i.id, i.owner_did, i.repo_at, i.issue_id, i.created, i.title, i.body, i.open
187
+
i.owner_did = ? and i.created >= date ('now', ?)
180
188
order by
181
189
i.created desc`,
182
-
ownerDid)
190
+
ownerDid, timeframe)
183
191
if err != nil {
184
192
return nil, err
185
193
}
···
187
195
188
196
for rows.Next() {
189
197
var issue Issue
190
-
var createdAt string
191
-
var metadata IssueMetadata
192
-
err := rows.Scan(&issue.OwnerDid, &issue.RepoAt, &issue.IssueId, &createdAt, &issue.Title, &issue.Body, &issue.Open, &metadata.CommentCount)
198
+
var issueCreatedAt, repoCreatedAt string
199
+
var repo Repo
200
+
err := rows.Scan(
201
+
&issue.OwnerDid,
202
+
&issue.RepoAt,
203
+
&issue.IssueId,
204
+
&issueCreatedAt,
205
+
&issue.Title,
206
+
&issue.Body,
207
+
&issue.Open,
208
+
&repo.Did,
209
+
&repo.Name,
210
+
&repo.Knot,
211
+
&repo.Rkey,
212
+
&repoCreatedAt,
213
+
)
193
214
if err != nil {
194
215
return nil, err
195
216
}
196
217
197
-
createdTime, err := time.Parse(time.RFC3339, createdAt)
218
+
issueCreatedTime, err := time.Parse(time.RFC3339, issueCreatedAt)
219
+
if err != nil {
220
+
return nil, err
221
+
}
222
+
issue.Created = issueCreatedTime
223
+
224
+
repoCreatedTime, err := time.Parse(time.RFC3339, repoCreatedAt)
198
225
if err != nil {
199
226
return nil, err
200
227
}
201
-
issue.Created = &createdTime
202
-
issue.Metadata = &metadata
228
+
repo.Created = repoCreatedTime
229
+
230
+
issue.Metadata = &IssueMetadata{
231
+
Repo: &repo,
232
+
}
203
233
204
234
issues = append(issues, issue)
205
235
}
···
226
256
if err != nil {
227
257
return nil, err
228
258
}
229
-
issue.Created = &createdTime
259
+
issue.Created = createdTime
230
260
231
261
return &issue, nil
232
262
}
···
246
276
if err != nil {
247
277
return nil, nil, err
248
278
}
249
-
issue.Created = &createdTime
279
+
issue.Created = createdTime
250
280
251
281
comments, err := GetComments(e, repoAt, issueId)
252
282
if err != nil {
+117
-48
appview/db/profile.go
+117
-48
appview/db/profile.go
···
1
1
package db
2
2
3
3
import (
4
+
"encoding/json"
4
5
"fmt"
5
-
"sort"
6
6
"time"
7
7
)
8
8
9
-
type ProfileTimelineEvent struct {
10
-
EventAt time.Time
11
-
Type string
12
-
*Issue
13
-
*Pull
14
-
*Repo
9
+
type RepoEvent struct {
10
+
Repo *Repo
11
+
Source *Repo
12
+
}
13
+
14
+
type ProfileTimeline struct {
15
+
ByMonth []ByMonth
16
+
}
17
+
18
+
type ByMonth struct {
19
+
RepoEvents []RepoEvent
20
+
IssueEvents IssueEvents
21
+
PullEvents PullEvents
22
+
}
23
+
24
+
type IssueEvents struct {
25
+
Items []*Issue
26
+
}
27
+
28
+
type IssueEventStats struct {
29
+
Open int
30
+
Closed int
31
+
}
32
+
33
+
func (i IssueEvents) Stats() IssueEventStats {
34
+
var open, closed int
35
+
for _, issue := range i.Items {
36
+
if issue.Open {
37
+
open += 1
38
+
} else {
39
+
closed += 1
40
+
}
41
+
}
42
+
43
+
return IssueEventStats{
44
+
Open: open,
45
+
Closed: closed,
46
+
}
47
+
}
48
+
49
+
type PullEvents struct {
50
+
Items []*Pull
51
+
}
52
+
53
+
func (p PullEvents) Stats() PullEventStats {
54
+
var open, merged, closed int
55
+
for _, pull := range p.Items {
56
+
switch pull.State {
57
+
case PullOpen:
58
+
open += 1
59
+
case PullMerged:
60
+
merged += 1
61
+
case PullClosed:
62
+
closed += 1
63
+
}
64
+
}
65
+
66
+
return PullEventStats{
67
+
Open: open,
68
+
Merged: merged,
69
+
Closed: closed,
70
+
}
71
+
}
15
72
16
-
// optional: populate only if Repo is a fork
17
-
Source *Repo
73
+
type PullEventStats struct {
74
+
Closed int
75
+
Open int
76
+
Merged int
18
77
}
19
78
20
-
func MakeProfileTimeline(e Execer, forDid string) ([]ProfileTimelineEvent, error) {
21
-
timeline := []ProfileTimelineEvent{}
22
-
limit := 30
79
+
const TimeframeMonths = 3
80
+
81
+
func MakeProfileTimeline(e Execer, forDid string) (*ProfileTimeline, error) {
82
+
timeline := ProfileTimeline{
83
+
ByMonth: make([]ByMonth, TimeframeMonths),
84
+
}
85
+
currentMonth := time.Now().Month()
86
+
timeframe := fmt.Sprintf("-%d months", TimeframeMonths)
23
87
24
-
pulls, err := GetPullsByOwnerDid(e, forDid)
88
+
pulls, err := GetPullsByOwnerDid(e, forDid, timeframe)
25
89
if err != nil {
26
-
return timeline, fmt.Errorf("error getting pulls by owner did: %w", err)
90
+
return nil, fmt.Errorf("error getting pulls by owner did: %w", err)
27
91
}
28
92
93
+
// group pulls by month
29
94
for _, pull := range pulls {
30
-
repo, err := GetRepoByAtUri(e, string(pull.RepoAt))
31
-
if err != nil {
32
-
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
95
+
pullMonth := pull.Created.Month()
96
+
97
+
if currentMonth-pullMonth > TimeframeMonths {
98
+
// shouldn't happen; but times are weird
99
+
continue
33
100
}
34
101
35
-
timeline = append(timeline, ProfileTimelineEvent{
36
-
EventAt: pull.Created,
37
-
Type: "pull",
38
-
Pull: &pull,
39
-
Repo: repo,
40
-
})
102
+
idx := currentMonth - pullMonth
103
+
items := &timeline.ByMonth[idx].PullEvents.Items
104
+
105
+
*items = append(*items, &pull)
41
106
}
42
107
43
-
issues, err := GetIssuesByOwnerDid(e, forDid)
108
+
issues, err := GetIssuesByOwnerDid(e, forDid, timeframe)
44
109
if err != nil {
45
-
return timeline, fmt.Errorf("error getting issues by owner did: %w", err)
110
+
return nil, fmt.Errorf("error getting issues by owner did: %w", err)
46
111
}
47
112
48
113
for _, issue := range issues {
49
-
repo, err := GetRepoByAtUri(e, string(issue.RepoAt))
50
-
if err != nil {
51
-
return timeline, fmt.Errorf("error getting repo by at uri: %w", err)
114
+
issueMonth := issue.Created.Month()
115
+
116
+
if currentMonth-issueMonth > TimeframeMonths {
117
+
// shouldn't happen; but times are weird
118
+
continue
52
119
}
53
120
54
-
timeline = append(timeline, ProfileTimelineEvent{
55
-
EventAt: *issue.Created,
56
-
Type: "issue",
57
-
Issue: &issue,
58
-
Repo: repo,
59
-
})
121
+
idx := currentMonth - issueMonth
122
+
items := &timeline.ByMonth[idx].IssueEvents.Items
123
+
124
+
*items = append(*items, &issue)
60
125
}
61
126
62
127
repos, err := GetAllReposByDid(e, forDid)
63
128
if err != nil {
64
-
return timeline, fmt.Errorf("error getting all repos by did: %w", err)
129
+
return nil, fmt.Errorf("error getting all repos by did: %w", err)
65
130
}
66
131
67
132
for _, repo := range repos {
133
+
// TODO: get this in the original query; requires COALESCE because nullable
68
134
var sourceRepo *Repo
69
135
if repo.Source != "" {
70
136
sourceRepo, err = GetRepoByAtUri(e, repo.Source)
···
73
139
}
74
140
}
75
141
76
-
timeline = append(timeline, ProfileTimelineEvent{
77
-
EventAt: repo.Created,
78
-
Type: "repo",
79
-
Repo: &repo,
80
-
Source: sourceRepo,
142
+
repoMonth := repo.Created.Month()
143
+
144
+
if currentMonth-repoMonth > TimeframeMonths {
145
+
// shouldn't happen; but times are weird
146
+
continue
147
+
}
148
+
149
+
idx := currentMonth - repoMonth
150
+
151
+
items := &timeline.ByMonth[idx].RepoEvents
152
+
*items = append(*items, RepoEvent{
153
+
Repo: &repo,
154
+
Source: sourceRepo,
81
155
})
82
156
}
83
157
84
-
sort.Slice(timeline, func(i, j int) bool {
85
-
return timeline[i].EventAt.After(timeline[j].EventAt)
86
-
})
87
-
88
-
if len(timeline) > limit {
89
-
timeline = timeline[:limit]
90
-
}
158
+
x, _ := json.MarshalIndent(timeline, "", "\t")
159
+
fmt.Println(string(x))
91
160
92
-
return timeline, nil
161
+
return &timeline, nil
93
162
}
+40
-14
appview/db/pulls.go
+40
-14
appview/db/pulls.go
···
64
64
// meta
65
65
Created time.Time
66
66
PullSource *PullSource
67
+
68
+
// optionally, populate this when querying for reverse mappings
69
+
Repo *Repo
67
70
}
68
71
69
72
type PullSource struct {
···
522
525
return &pull, nil
523
526
}
524
527
525
-
func GetPullsByOwnerDid(e Execer, did string) ([]Pull, error) {
528
+
// timeframe here is directly passed into the sql query filter, and any
529
+
// timeframe in the past should be negative; e.g.: "-3 months"
530
+
func GetPullsByOwnerDid(e Execer, did, timeframe string) ([]Pull, error) {
526
531
var pulls []Pull
527
532
528
533
rows, err := e.Query(`
529
534
select
530
-
owner_did,
531
-
repo_at,
532
-
pull_id,
533
-
created,
534
-
title,
535
-
state
535
+
p.owner_did,
536
+
p.repo_at,
537
+
p.pull_id,
538
+
p.created,
539
+
p.title,
540
+
p.state,
541
+
r.did,
542
+
r.name,
543
+
r.knot,
544
+
r.rkey,
545
+
r.created
536
546
from
537
-
pulls
547
+
pulls p
548
+
join
549
+
repos r on p.repo_at = r.at_uri
538
550
where
539
-
owner_did = ?
551
+
p.owner_did = ? and p.created >= date ('now', ?)
540
552
order by
541
-
created desc`, did)
553
+
p.created desc`, did, timeframe)
542
554
if err != nil {
543
555
return nil, err
544
556
}
···
546
558
547
559
for rows.Next() {
548
560
var pull Pull
549
-
var createdAt string
561
+
var repo Repo
562
+
var pullCreatedAt, repoCreatedAt string
550
563
err := rows.Scan(
551
564
&pull.OwnerDid,
552
565
&pull.RepoAt,
553
566
&pull.PullId,
554
-
&createdAt,
567
+
&pullCreatedAt,
555
568
&pull.Title,
556
569
&pull.State,
570
+
&repo.Did,
571
+
&repo.Name,
572
+
&repo.Knot,
573
+
&repo.Rkey,
574
+
&repoCreatedAt,
557
575
)
558
576
if err != nil {
559
577
return nil, err
560
578
}
561
579
562
-
createdTime, err := time.Parse(time.RFC3339, createdAt)
580
+
pullCreatedTime, err := time.Parse(time.RFC3339, pullCreatedAt)
563
581
if err != nil {
564
582
return nil, err
565
583
}
566
-
pull.Created = createdTime
584
+
pull.Created = pullCreatedTime
585
+
586
+
repoCreatedTime, err := time.Parse(time.RFC3339, repoCreatedAt)
587
+
if err != nil {
588
+
return nil, err
589
+
}
590
+
repo.Created = repoCreatedTime
591
+
592
+
pull.Repo = &repo
567
593
568
594
pulls = append(pulls, pull)
569
595
}
+3
-1
appview/db/repos.go
+3
-1
appview/db/repos.go
+3
-2
appview/pages/pages.go
+3
-2
appview/pages/pages.go
···
178
178
CollaboratingRepos []db.Repo
179
179
ProfileStats ProfileStats
180
180
FollowStatus db.FollowStatus
181
-
DidHandleMap map[string]string
182
181
AvatarUri string
183
-
ProfileTimeline []db.ProfileTimelineEvent
182
+
ProfileTimeline *db.ProfileTimeline
183
+
184
+
DidHandleMap map[string]string
184
185
}
185
186
186
187
type ProfileStats struct {
+179
-2
appview/pages/templates/user/profile.html
+179
-2
appview/pages/templates/user/profile.html
···
9
9
{{ block "ownRepos" . }}{{ end }}
10
10
{{ block "collaboratingRepos" . }}{{ end }}
11
11
</div>
12
-
13
12
<div class="md:col-span-2 order-3 md:order-3">
14
-
{{ block "profileTimeline" . }}{{ end }}
13
+
{{ block "profileTimeline2" . }}{{ end }}
15
14
</div>
16
15
</div>
17
16
{{ end }}
18
17
18
+
{{ define "profileTimeline2" }}
19
+
<p class="text-sm font-bold py-2 dark:text-white">ACTIVITY</p>
20
+
<div class="flex flex-col gap-6 relative">
21
+
{{ with .ProfileTimeline }}
22
+
{{ range $idx, $byMonth := .ByMonth }}
23
+
{{ with $byMonth }}
24
+
<div>
25
+
{{ if eq $idx 0 }}
26
+
<p class="text-sm font-bold py-2 dark:text-white">This month</p>
27
+
{{ else }}
28
+
{{ $s := "s" }}
29
+
{{ if eq $idx 1 }}
30
+
{{ $s = "" }}
31
+
{{ end }}
32
+
<p class="text-sm font-bold py-2 dark:text-white">{{$idx}} month{{$s}} ago</p>
33
+
{{ end }}
34
+
35
+
<div class="flex flex-col gap-4">
36
+
{{ block "repoEvents" (list .RepoEvents $.DidHandleMap) }} {{ end }}
37
+
{{ block "issueEvents" (list .IssueEvents $.DidHandleMap) }} {{ end }}
38
+
{{ block "pullEvents" (list .PullEvents $.DidHandleMap) }} {{ end }}
39
+
</div>
40
+
</div>
41
+
42
+
{{ end }}
43
+
{{ else }}
44
+
<p class="dark:text-white">This user does not have any activity yet.</p>
45
+
{{ end }}
46
+
{{ end }}
47
+
</div>
48
+
{{ end }}
49
+
50
+
{{ define "repoEvents" }}
51
+
{{ $items := index . 0 }}
52
+
{{ $handleMap := index . 1 }}
53
+
54
+
{{ if gt (len $items) 0 }}
55
+
<details open>
56
+
<summary class="list-none cursor-pointer">
57
+
<div class="flex items-center gap-2">
58
+
{{ i "unfold-vertical" "w-4 h-4" }}
59
+
created {{ len $items }} repositories
60
+
</div>
61
+
</summary>
62
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
63
+
{{ range $items }}
64
+
<div class="flex flex-wrap items-center gap-2">
65
+
<span class="text-gray-500 dark:text-gray-400">
66
+
{{ if .Source }}
67
+
{{ i "git-fork" "w-4 h-4" }}
68
+
{{ else }}
69
+
{{ i "book-plus" "w-4 h-4" }}
70
+
{{ end }}
71
+
</span>
72
+
<a href="/{{ index $handleMap .Repo.Did }}/{{ .Repo.Name }}" class="no-underline hover:underline">
73
+
{{- .Repo.Name -}}
74
+
</a>
75
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Repo.Created | shortTimeFmt }}</time>
76
+
</div>
77
+
{{ end }}
78
+
</div>
79
+
</details>
80
+
{{ end }}
81
+
{{ end }}
82
+
83
+
{{ define "issueEvents" }}
84
+
{{ $i := index . 0 }}
85
+
{{ $items := $i.Items }}
86
+
{{ $stats := $i.Stats }}
87
+
{{ $handleMap := index . 1 }}
88
+
89
+
{{ if gt (len $items) 0 }}
90
+
<details open>
91
+
<summary class="list-none cursor-pointer">
92
+
<div class="flex items-center gap-2">
93
+
{{ i "unfold-vertical" "w-4 h-4" }}
94
+
<span>
95
+
created {{ len $items }} issues
96
+
</span>
97
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-green-600 dark:bg-green-700">
98
+
{{$stats.Open}} open
99
+
</span>
100
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-gray-800 dark:bg-gray-700">
101
+
{{$stats.Closed}} closed
102
+
</span>
103
+
</div>
104
+
</summary>
105
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
106
+
{{ range $items }}
107
+
{{ $repoOwner := index $handleMap .Metadata.Repo.Did }}
108
+
{{ $repoName := .Metadata.Repo.Name }}
109
+
{{ $repoUrl := printf "%s/%s" $repoOwner $repoName }}
110
+
111
+
<div class="flex flex-wrap items-center gap-2 text-gray-600 dark:text-gray-300">
112
+
{{ if .Open }}
113
+
<span class="text-green-600 dark:text-green-500">
114
+
{{ i "circle-dot" "w-4 h-4" }}
115
+
</span>
116
+
{{ else }}
117
+
<span class="text-gray-500 dark:text-gray-400">
118
+
{{ i "ban" "w-4 h-4" }}
119
+
</span>
120
+
{{ end }}
121
+
<a href="/{{$repoUrl}}/issues/{{ .IssueId }}" class="no-underline hover:underline">
122
+
<span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span>
123
+
{{ .Title -}}
124
+
</a>
125
+
on
126
+
<a href="/{{$repoUrl}}" class="no-underline hover:underline">
127
+
{{$repoUrl}}
128
+
</a>
129
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Created | shortTimeFmt }}</time>
130
+
</p>
131
+
{{ end }}
132
+
</div>
133
+
</details>
134
+
{{ end }}
135
+
{{ end }}
136
+
137
+
{{ define "pullEvents" }}
138
+
{{ $i := index . 0 }}
139
+
{{ $items := $i.Items }}
140
+
{{ $stats := $i.Stats }}
141
+
{{ $handleMap := index . 1 }}
142
+
{{ if gt (len $items) 0 }}
143
+
<details open>
144
+
<summary class="list-none cursor-pointer">
145
+
<div class="flex items-center gap-2">
146
+
{{ i "unfold-vertical" "w-4 h-4" }}
147
+
<span>
148
+
created {{ len $items }} pull requests
149
+
</span>
150
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-green-600 dark:bg-green-700">
151
+
{{$stats.Open}} open
152
+
</span>
153
+
<span class="px-2 py-1/2 text-sm rounded-sm text-white bg-purple-600 dark:bg-purple-700">
154
+
{{$stats.Merged}} merged
155
+
</span>
156
+
<span class="px-2 py-1/2 text-sm rounded-sm text-black dark:text-white bg-gray-50 dark:bg-gray-700 ">
157
+
{{$stats.Closed}} closed
158
+
</span>
159
+
</div>
160
+
</summary>
161
+
<div class="p-2 pl-8 text-sm flex flex-col gap-3">
162
+
{{ range $items }}
163
+
{{ $repoOwner := index $handleMap .Repo.Did }}
164
+
{{ $repoName := .Repo.Name }}
165
+
{{ $repoUrl := printf "%s/%s" $repoOwner $repoName }}
166
+
167
+
<div class="flex flex-wrap items-center gap-2 text-gray-600 dark:text-gray-300">
168
+
{{ if .State.IsOpen }}
169
+
<span class="text-green-600 dark:text-green-500">
170
+
{{ i "git-pull-request" "w-4 h-4" }}
171
+
</span>
172
+
{{ else if .State.IsMerged }}
173
+
<span class="text-purple-600 dark:text-purple-500">
174
+
{{ i "git-merge" "w-4 h-4" }}
175
+
</span>
176
+
{{ else }}
177
+
<span class="text-gray-600 dark:text-gray-300">
178
+
{{ i "git-pull-request-closed" "w-4 h-4" }}
179
+
</span>
180
+
{{ end }}
181
+
<a href="/{{$repoUrl}}/pulls/{{ .PullId }}" class="no-underline hover:underline">
182
+
<span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span>
183
+
{{ .Title -}}
184
+
</a>
185
+
on
186
+
<a href="/{{$repoUrl}}" class="no-underline hover:underline">
187
+
{{$repoUrl}}
188
+
</a>
189
+
<time class="text-gray-700 dark:text-gray-400 text-xs ml-2">{{ .Created | shortTimeFmt }}</time>
190
+
</p>
191
+
{{ end }}
192
+
</div>
193
+
</details>
194
+
{{ end }}
195
+
{{ end }}
19
196
20
197
{{ define "profileTimeline" }}
21
198
<div class="flex flex-col gap-3 relative">
+11
-5
appview/state/profile.go
+11
-5
appview/state/profile.go
···
43
43
for _, r := range collaboratingRepos {
44
44
didsToResolve = append(didsToResolve, r.Did)
45
45
}
46
-
for _, evt := range timeline {
47
-
if evt.Repo != nil {
48
-
if evt.Repo.Source != "" {
49
-
didsToResolve = append(didsToResolve, evt.Source.Did)
46
+
for _, byMonth := range timeline.ByMonth {
47
+
for _, pe := range byMonth.PullEvents.Items {
48
+
didsToResolve = append(didsToResolve, pe.Repo.Did)
49
+
}
50
+
for _, ie := range byMonth.IssueEvents.Items {
51
+
didsToResolve = append(didsToResolve, ie.Metadata.Repo.Did)
52
+
}
53
+
for _, re := range byMonth.RepoEvents {
54
+
didsToResolve = append(didsToResolve, re.Repo.Did)
55
+
if re.Source != nil {
56
+
didsToResolve = append(didsToResolve, re.Source.Did)
50
57
}
51
58
}
52
-
didsToResolve = append(didsToResolve, evt.Repo.Did)
53
59
}
54
60
55
61
resolvedIds := s.resolver.ResolveIdents(r.Context(), didsToResolve)