better-review 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -25647,6 +25647,16 @@ var trackedEntrySchema = external_exports.union([
|
|
|
25647
25647
|
]);
|
|
25648
25648
|
var diffSideSchema = external_exports.enum(["LEFT", "RIGHT"]);
|
|
25649
25649
|
var reviewEventSchema = external_exports.enum(["COMMENT", "APPROVE", "REQUEST_CHANGES"]);
|
|
25650
|
+
var reactionContentSchema = external_exports.enum([
|
|
25651
|
+
"THUMBS_UP",
|
|
25652
|
+
"THUMBS_DOWN",
|
|
25653
|
+
"LAUGH",
|
|
25654
|
+
"HOORAY",
|
|
25655
|
+
"CONFUSED",
|
|
25656
|
+
"HEART",
|
|
25657
|
+
"ROCKET",
|
|
25658
|
+
"EYES"
|
|
25659
|
+
]);
|
|
25650
25660
|
var newThreadSchema = external_exports.discriminatedUnion("subjectType", [
|
|
25651
25661
|
external_exports.object({
|
|
25652
25662
|
subjectType: external_exports.literal("LINE"),
|
|
@@ -25782,148 +25792,15 @@ var GitHub = class {
|
|
|
25782
25792
|
};
|
|
25783
25793
|
|
|
25784
25794
|
// ../server/src/github/queries.ts
|
|
25785
|
-
var
|
|
25795
|
+
var REACTION_FIELDS = (
|
|
25786
25796
|
/* GraphQL */
|
|
25787
25797
|
`
|
|
25788
|
-
fragment
|
|
25789
|
-
|
|
25790
|
-
|
|
25791
|
-
|
|
25792
|
-
|
|
25793
|
-
|
|
25794
|
-
createdAt
|
|
25795
|
-
updatedAt
|
|
25796
|
-
additions
|
|
25797
|
-
deletions
|
|
25798
|
-
changedFiles
|
|
25799
|
-
headRefOid
|
|
25800
|
-
reviewDecision
|
|
25801
|
-
repository {
|
|
25802
|
-
nameWithOwner
|
|
25803
|
-
}
|
|
25804
|
-
author {
|
|
25805
|
-
login
|
|
25806
|
-
avatarUrl
|
|
25807
|
-
}
|
|
25808
|
-
labels(first: 10) {
|
|
25809
|
-
nodes {
|
|
25810
|
-
name
|
|
25811
|
-
color
|
|
25812
|
-
}
|
|
25813
|
-
}
|
|
25814
|
-
commits(last: 1) {
|
|
25815
|
-
nodes {
|
|
25816
|
-
commit {
|
|
25817
|
-
statusCheckRollup {
|
|
25818
|
-
state
|
|
25819
|
-
}
|
|
25820
|
-
}
|
|
25821
|
-
}
|
|
25822
|
-
}
|
|
25823
|
-
reviewRequests(first: 20) {
|
|
25824
|
-
totalCount
|
|
25825
|
-
nodes {
|
|
25826
|
-
requestedReviewer {
|
|
25827
|
-
__typename
|
|
25828
|
-
... on User {
|
|
25829
|
-
login
|
|
25830
|
-
}
|
|
25831
|
-
... on Team {
|
|
25832
|
-
slug
|
|
25833
|
-
}
|
|
25834
|
-
}
|
|
25835
|
-
}
|
|
25836
|
-
}
|
|
25837
|
-
latestOpinionatedReviews(first: 20) {
|
|
25838
|
-
nodes {
|
|
25839
|
-
state
|
|
25840
|
-
author {
|
|
25841
|
-
login
|
|
25842
|
-
avatarUrl
|
|
25843
|
-
}
|
|
25844
|
-
}
|
|
25845
|
-
}
|
|
25846
|
-
viewerLatestReview {
|
|
25847
|
-
state
|
|
25848
|
-
submittedAt
|
|
25849
|
-
commit {
|
|
25850
|
-
oid
|
|
25851
|
-
}
|
|
25852
|
-
}
|
|
25853
|
-
reviewThreads(first: 100) {
|
|
25854
|
-
nodes {
|
|
25855
|
-
isResolved
|
|
25856
|
-
comments(last: 1) {
|
|
25857
|
-
nodes {
|
|
25858
|
-
author {
|
|
25859
|
-
login
|
|
25860
|
-
}
|
|
25861
|
-
createdAt
|
|
25862
|
-
}
|
|
25863
|
-
}
|
|
25864
|
-
}
|
|
25865
|
-
}
|
|
25866
|
-
comments(last: 1) {
|
|
25867
|
-
nodes {
|
|
25868
|
-
author {
|
|
25869
|
-
login
|
|
25870
|
-
}
|
|
25871
|
-
createdAt
|
|
25872
|
-
}
|
|
25873
|
-
}
|
|
25874
|
-
files(first: 100) {
|
|
25875
|
-
totalCount
|
|
25876
|
-
nodes {
|
|
25877
|
-
viewerViewedState
|
|
25878
|
-
}
|
|
25879
|
-
}
|
|
25880
|
-
}
|
|
25881
|
-
`
|
|
25882
|
-
);
|
|
25883
|
-
var INBOX_SECTION_IDS = [
|
|
25884
|
-
"requested",
|
|
25885
|
-
"reviewed",
|
|
25886
|
-
"mine",
|
|
25887
|
-
"involved",
|
|
25888
|
-
"stale",
|
|
25889
|
-
"unreviewed"
|
|
25890
|
-
];
|
|
25891
|
-
var INBOX_IDS_QUERY = (
|
|
25892
|
-
/* GraphQL */
|
|
25893
|
-
`
|
|
25894
|
-
query InboxIds(${INBOX_SECTION_IDS.map((id) => `$${id}: String!`).join(", ")}) {
|
|
25895
|
-
viewer { login avatarUrl }
|
|
25896
|
-
${INBOX_SECTION_IDS.map(
|
|
25897
|
-
(id) => `${id}: search(query: $${id}, type: ISSUE, first: 50) {
|
|
25898
|
-
nodes { ... on PullRequest { id } }
|
|
25899
|
-
}`
|
|
25900
|
-
).join("\n")}
|
|
25901
|
-
}
|
|
25902
|
-
`
|
|
25903
|
-
);
|
|
25904
|
-
var PR_SUMMARIES_QUERY = (
|
|
25905
|
-
/* GraphQL */
|
|
25906
|
-
`
|
|
25907
|
-
query PrSummaries($ids: [ID!]!) {
|
|
25908
|
-
nodes(ids: $ids) {
|
|
25909
|
-
...PrSummary
|
|
25910
|
-
}
|
|
25911
|
-
}
|
|
25912
|
-
${PR_SUMMARY}
|
|
25913
|
-
`
|
|
25914
|
-
);
|
|
25915
|
-
var INBOX_FINGERPRINT_QUERY = (
|
|
25916
|
-
/* GraphQL */
|
|
25917
|
-
`
|
|
25918
|
-
query InboxFingerprint($q: String!) {
|
|
25919
|
-
search(query: $q, type: ISSUE, first: 100) {
|
|
25920
|
-
issueCount
|
|
25921
|
-
nodes {
|
|
25922
|
-
... on PullRequest {
|
|
25923
|
-
id
|
|
25924
|
-
updatedAt
|
|
25925
|
-
headRefOid
|
|
25926
|
-
}
|
|
25798
|
+
fragment ReactionFields on Reactable {
|
|
25799
|
+
reactionGroups {
|
|
25800
|
+
content
|
|
25801
|
+
viewerHasReacted
|
|
25802
|
+
reactors {
|
|
25803
|
+
totalCount
|
|
25927
25804
|
}
|
|
25928
25805
|
}
|
|
25929
25806
|
}
|
|
@@ -25954,7 +25831,9 @@ var REVIEW_COMMENT_FIELDS = (
|
|
|
25954
25831
|
}
|
|
25955
25832
|
viewerCanUpdate
|
|
25956
25833
|
viewerCanDelete
|
|
25834
|
+
...ReactionFields
|
|
25957
25835
|
}
|
|
25836
|
+
${REACTION_FIELDS}
|
|
25958
25837
|
`
|
|
25959
25838
|
);
|
|
25960
25839
|
var THREAD_FIELDS = (
|
|
@@ -26009,6 +25888,7 @@ var PR_QUERY = (
|
|
|
26009
25888
|
updatedAt
|
|
26010
25889
|
body
|
|
26011
25890
|
bodyHTML
|
|
25891
|
+
...ReactionFields
|
|
26012
25892
|
baseRefName
|
|
26013
25893
|
headRefName
|
|
26014
25894
|
baseRefOid
|
|
@@ -26025,31 +25905,6 @@ var PR_QUERY = (
|
|
|
26025
25905
|
headRepository {
|
|
26026
25906
|
nameWithOwner
|
|
26027
25907
|
}
|
|
26028
|
-
lastCommit: commits(last: 1) {
|
|
26029
|
-
nodes {
|
|
26030
|
-
commit {
|
|
26031
|
-
statusCheckRollup {
|
|
26032
|
-
state
|
|
26033
|
-
contexts(first: 100) {
|
|
26034
|
-
nodes {
|
|
26035
|
-
__typename
|
|
26036
|
-
... on CheckRun {
|
|
26037
|
-
name
|
|
26038
|
-
conclusion
|
|
26039
|
-
status
|
|
26040
|
-
detailsUrl
|
|
26041
|
-
}
|
|
26042
|
-
... on StatusContext {
|
|
26043
|
-
context
|
|
26044
|
-
state
|
|
26045
|
-
targetUrl
|
|
26046
|
-
}
|
|
26047
|
-
}
|
|
26048
|
-
}
|
|
26049
|
-
}
|
|
26050
|
-
}
|
|
26051
|
-
}
|
|
26052
|
-
}
|
|
26053
25908
|
reviewRequests(first: 20) {
|
|
26054
25909
|
nodes {
|
|
26055
25910
|
requestedReviewer {
|
|
@@ -26111,6 +25966,7 @@ var PR_QUERY = (
|
|
|
26111
25966
|
url
|
|
26112
25967
|
body
|
|
26113
25968
|
bodyHTML
|
|
25969
|
+
...ReactionFields
|
|
26114
25970
|
createdAt
|
|
26115
25971
|
author {
|
|
26116
25972
|
login
|
|
@@ -26125,6 +25981,7 @@ var PR_QUERY = (
|
|
|
26125
25981
|
state
|
|
26126
25982
|
body
|
|
26127
25983
|
bodyHTML
|
|
25984
|
+
...ReactionFields
|
|
26128
25985
|
submittedAt
|
|
26129
25986
|
createdAt
|
|
26130
25987
|
url
|
|
@@ -26271,48 +26128,242 @@ async function fetchTexts(gh, ref, expressions) {
|
|
|
26271
26128
|
return texts;
|
|
26272
26129
|
}
|
|
26273
26130
|
|
|
26131
|
+
// ../server/src/github/inboxQueries.ts
|
|
26132
|
+
var BOARD_FIELDS = (
|
|
26133
|
+
/* GraphQL */
|
|
26134
|
+
`
|
|
26135
|
+
fragment BoardFields on PullRequest {
|
|
26136
|
+
id
|
|
26137
|
+
number
|
|
26138
|
+
title
|
|
26139
|
+
url
|
|
26140
|
+
isDraft
|
|
26141
|
+
createdAt
|
|
26142
|
+
updatedAt
|
|
26143
|
+
headRefOid
|
|
26144
|
+
reviewDecision
|
|
26145
|
+
isInMergeQueue
|
|
26146
|
+
mergedAt
|
|
26147
|
+
repository {
|
|
26148
|
+
nameWithOwner
|
|
26149
|
+
}
|
|
26150
|
+
author {
|
|
26151
|
+
login
|
|
26152
|
+
avatarUrl
|
|
26153
|
+
}
|
|
26154
|
+
reviews {
|
|
26155
|
+
totalCount
|
|
26156
|
+
}
|
|
26157
|
+
latestOpinionatedReviews(first: 10) {
|
|
26158
|
+
nodes {
|
|
26159
|
+
state
|
|
26160
|
+
author {
|
|
26161
|
+
login
|
|
26162
|
+
avatarUrl
|
|
26163
|
+
}
|
|
26164
|
+
}
|
|
26165
|
+
}
|
|
26166
|
+
reviewRequests(first: 10) {
|
|
26167
|
+
nodes {
|
|
26168
|
+
requestedReviewer {
|
|
26169
|
+
__typename
|
|
26170
|
+
... on User {
|
|
26171
|
+
login
|
|
26172
|
+
}
|
|
26173
|
+
... on Team {
|
|
26174
|
+
slug
|
|
26175
|
+
}
|
|
26176
|
+
}
|
|
26177
|
+
}
|
|
26178
|
+
}
|
|
26179
|
+
}
|
|
26180
|
+
`
|
|
26181
|
+
);
|
|
26182
|
+
var BOARD_QUERY = (
|
|
26183
|
+
/* GraphQL */
|
|
26184
|
+
`
|
|
26185
|
+
query Board($ids: [ID!]!) {
|
|
26186
|
+
nodes(ids: $ids) {
|
|
26187
|
+
...BoardFields
|
|
26188
|
+
}
|
|
26189
|
+
}
|
|
26190
|
+
${BOARD_FIELDS}
|
|
26191
|
+
`
|
|
26192
|
+
);
|
|
26193
|
+
var CHECKS_FIELDS = (
|
|
26194
|
+
/* GraphQL */
|
|
26195
|
+
`
|
|
26196
|
+
commits(last: 1) {
|
|
26197
|
+
nodes {
|
|
26198
|
+
commit {
|
|
26199
|
+
statusCheckRollup {
|
|
26200
|
+
state
|
|
26201
|
+
}
|
|
26202
|
+
}
|
|
26203
|
+
}
|
|
26204
|
+
}
|
|
26205
|
+
`
|
|
26206
|
+
);
|
|
26207
|
+
var CHECKS_QUERY = (
|
|
26208
|
+
/* GraphQL */
|
|
26209
|
+
`
|
|
26210
|
+
query BoardChecks($ids: [ID!]!) {
|
|
26211
|
+
nodes(ids: $ids) {
|
|
26212
|
+
... on PullRequest {
|
|
26213
|
+
id
|
|
26214
|
+
${CHECKS_FIELDS}
|
|
26215
|
+
reviewThreads(first: 100) {
|
|
26216
|
+
nodes {
|
|
26217
|
+
isResolved
|
|
26218
|
+
}
|
|
26219
|
+
}
|
|
26220
|
+
}
|
|
26221
|
+
}
|
|
26222
|
+
}
|
|
26223
|
+
`
|
|
26224
|
+
);
|
|
26225
|
+
var DETAILS_QUERY = (
|
|
26226
|
+
/* GraphQL */
|
|
26227
|
+
`
|
|
26228
|
+
query BoardDetails($ids: [ID!]!) {
|
|
26229
|
+
nodes(ids: $ids) {
|
|
26230
|
+
... on PullRequest {
|
|
26231
|
+
id
|
|
26232
|
+
additions
|
|
26233
|
+
deletions
|
|
26234
|
+
${CHECKS_FIELDS}
|
|
26235
|
+
viewerLatestReview {
|
|
26236
|
+
state
|
|
26237
|
+
commit {
|
|
26238
|
+
oid
|
|
26239
|
+
}
|
|
26240
|
+
}
|
|
26241
|
+
comments(last: 1) {
|
|
26242
|
+
nodes {
|
|
26243
|
+
author {
|
|
26244
|
+
login
|
|
26245
|
+
}
|
|
26246
|
+
createdAt
|
|
26247
|
+
}
|
|
26248
|
+
}
|
|
26249
|
+
reviewThreads(first: 100) {
|
|
26250
|
+
nodes {
|
|
26251
|
+
isResolved
|
|
26252
|
+
comments(last: 1) {
|
|
26253
|
+
nodes {
|
|
26254
|
+
author {
|
|
26255
|
+
login
|
|
26256
|
+
}
|
|
26257
|
+
createdAt
|
|
26258
|
+
}
|
|
26259
|
+
}
|
|
26260
|
+
}
|
|
26261
|
+
}
|
|
26262
|
+
files(first: 100) {
|
|
26263
|
+
totalCount
|
|
26264
|
+
nodes {
|
|
26265
|
+
viewerViewedState
|
|
26266
|
+
}
|
|
26267
|
+
}
|
|
26268
|
+
}
|
|
26269
|
+
}
|
|
26270
|
+
}
|
|
26271
|
+
`
|
|
26272
|
+
);
|
|
26273
|
+
var SEARCH_IDS_QUERY = (
|
|
26274
|
+
/* GraphQL */
|
|
26275
|
+
`
|
|
26276
|
+
query SearchIds($q: String!, $after: String) {
|
|
26277
|
+
viewer {
|
|
26278
|
+
login
|
|
26279
|
+
avatarUrl
|
|
26280
|
+
}
|
|
26281
|
+
search(query: $q, type: ISSUE, first: 100, after: $after) {
|
|
26282
|
+
issueCount
|
|
26283
|
+
pageInfo {
|
|
26284
|
+
hasNextPage
|
|
26285
|
+
endCursor
|
|
26286
|
+
}
|
|
26287
|
+
nodes {
|
|
26288
|
+
... on PullRequest {
|
|
26289
|
+
id
|
|
26290
|
+
}
|
|
26291
|
+
}
|
|
26292
|
+
}
|
|
26293
|
+
}
|
|
26294
|
+
`
|
|
26295
|
+
);
|
|
26296
|
+
var INBOX_FINGERPRINT_QUERY = (
|
|
26297
|
+
/* GraphQL */
|
|
26298
|
+
`
|
|
26299
|
+
query InboxFingerprint($q: String!) {
|
|
26300
|
+
search(query: $q, type: ISSUE, first: 100) {
|
|
26301
|
+
issueCount
|
|
26302
|
+
nodes {
|
|
26303
|
+
... on PullRequest {
|
|
26304
|
+
id
|
|
26305
|
+
updatedAt
|
|
26306
|
+
headRefOid
|
|
26307
|
+
reviewDecision
|
|
26308
|
+
isInMergeQueue
|
|
26309
|
+
${CHECKS_FIELDS}
|
|
26310
|
+
}
|
|
26311
|
+
}
|
|
26312
|
+
}
|
|
26313
|
+
}
|
|
26314
|
+
`
|
|
26315
|
+
);
|
|
26316
|
+
|
|
26274
26317
|
// ../server/src/inbox.ts
|
|
26318
|
+
var MERGED_WINDOW_MS = 24 * 36e5;
|
|
26319
|
+
function scopeTerms(config2) {
|
|
26320
|
+
return [...config2.repos.map((r) => `repo:${r}`), ...config2.orgs.map((o) => `user:${o}`)];
|
|
26321
|
+
}
|
|
26275
26322
|
var SCOPE_CHUNK = 20;
|
|
26276
26323
|
function scopeChunks(config2) {
|
|
26277
|
-
const terms =
|
|
26324
|
+
const terms = scopeTerms(config2);
|
|
26278
26325
|
const chunks = [];
|
|
26279
26326
|
for (let i = 0; i < terms.length; i += SCOPE_CHUNK) chunks.push(terms.slice(i, i + SCOPE_CHUNK).join(" "));
|
|
26280
26327
|
return chunks;
|
|
26281
26328
|
}
|
|
26282
|
-
function searchQueries(scope,
|
|
26283
|
-
const
|
|
26284
|
-
const
|
|
26329
|
+
function searchQueries(scope, mergedSince) {
|
|
26330
|
+
const open2 = `is:pr is:open archived:false ${scope}`;
|
|
26331
|
+
const since = new Date(mergedSince).toISOString().replace(/\.\d+Z$/, "Z");
|
|
26285
26332
|
return {
|
|
26286
|
-
|
|
26287
|
-
|
|
26288
|
-
|
|
26289
|
-
|
|
26290
|
-
|
|
26291
|
-
unreviewed: `${base} draft:false review:none`
|
|
26333
|
+
open: `${open2} sort:updated-desc`,
|
|
26334
|
+
requested: `${open2} review-requested:@me`,
|
|
26335
|
+
involved: `${open2} involves:@me -author:@me`,
|
|
26336
|
+
reviewed: `${open2} reviewed-by:@me -author:@me`,
|
|
26337
|
+
merged: `is:pr is:merged archived:false ${scope} merged:>=${since} sort:updated-desc`
|
|
26292
26338
|
};
|
|
26293
26339
|
}
|
|
26294
26340
|
function prKey(owner, repo, number4) {
|
|
26295
26341
|
return `${owner}/${repo}#${number4}`.toLowerCase();
|
|
26296
26342
|
}
|
|
26343
|
+
function isApproved(decision, states) {
|
|
26344
|
+
if (decision !== null) return decision === "APPROVED";
|
|
26345
|
+
return states.includes("APPROVED") && !states.includes("CHANGES_REQUESTED");
|
|
26346
|
+
}
|
|
26297
26347
|
function toInboxPr(node2, me, visit2) {
|
|
26298
26348
|
const [owner = "", repo = ""] = node2.repository.nameWithOwner.split("/");
|
|
26299
|
-
let
|
|
26300
|
-
let awaitingMyReply = 0;
|
|
26349
|
+
let threads;
|
|
26301
26350
|
let lastOtherActivity = 0;
|
|
26302
|
-
|
|
26303
|
-
|
|
26304
|
-
const
|
|
26305
|
-
|
|
26306
|
-
|
|
26307
|
-
if (
|
|
26351
|
+
if (node2.reviewThreads) {
|
|
26352
|
+
threads = { total: node2.reviewThreads.nodes.length, open: 0, awaitingMyReply: 0 };
|
|
26353
|
+
for (const thread of node2.reviewThreads.nodes) {
|
|
26354
|
+
const last = thread.comments?.nodes[0];
|
|
26355
|
+
const lastIsOther = last?.author?.login !== me;
|
|
26356
|
+
if (!thread.isResolved) {
|
|
26357
|
+
threads.open++;
|
|
26358
|
+
if (last && lastIsOther) threads.awaitingMyReply++;
|
|
26359
|
+
}
|
|
26360
|
+
if (last && lastIsOther) lastOtherActivity = Math.max(lastOtherActivity, Date.parse(last.createdAt));
|
|
26308
26361
|
}
|
|
26309
|
-
if (last && lastIsOther) lastOtherActivity = Math.max(lastOtherActivity, Date.parse(last.createdAt));
|
|
26310
26362
|
}
|
|
26311
|
-
const lastComment = node2.comments
|
|
26363
|
+
const lastComment = node2.comments?.nodes[0];
|
|
26312
26364
|
if (lastComment && lastComment.author?.login !== me) {
|
|
26313
26365
|
lastOtherActivity = Math.max(lastOtherActivity, Date.parse(lastComment.createdAt));
|
|
26314
26366
|
}
|
|
26315
|
-
const files = node2.files?.nodes ?? [];
|
|
26316
26367
|
const myReview = node2.viewerLatestReview;
|
|
26317
26368
|
return {
|
|
26318
26369
|
id: node2.id,
|
|
@@ -26322,15 +26373,13 @@ function toInboxPr(node2, me, visit2) {
|
|
|
26322
26373
|
title: node2.title,
|
|
26323
26374
|
url: node2.url,
|
|
26324
26375
|
isDraft: node2.isDraft,
|
|
26376
|
+
inMergeQueue: node2.isInMergeQueue,
|
|
26377
|
+
mergedAt: node2.mergedAt,
|
|
26325
26378
|
author: node2.author,
|
|
26326
26379
|
createdAt: node2.createdAt,
|
|
26327
26380
|
updatedAt: node2.updatedAt,
|
|
26328
|
-
additions: node2.additions,
|
|
26329
|
-
deletions: node2.deletions,
|
|
26330
|
-
changedFiles: node2.changedFiles,
|
|
26331
|
-
labels: node2.labels.nodes,
|
|
26332
|
-
ci: node2.commits.nodes[0]?.commit.statusCheckRollup?.state ?? null,
|
|
26333
26381
|
reviewDecision: node2.reviewDecision,
|
|
26382
|
+
reviewCount: node2.reviews.totalCount,
|
|
26334
26383
|
reviews: node2.latestOpinionatedReviews.nodes.flatMap(
|
|
26335
26384
|
(r) => r.author ? [{ login: r.author.login, avatarUrl: r.author.avatarUrl, state: r.state }] : []
|
|
26336
26385
|
),
|
|
@@ -26338,115 +26387,183 @@ function toInboxPr(node2, me, visit2) {
|
|
|
26338
26387
|
const name = r.requestedReviewer?.login ?? r.requestedReviewer?.slug;
|
|
26339
26388
|
return name ? [name] : [];
|
|
26340
26389
|
}),
|
|
26341
|
-
|
|
26342
|
-
|
|
26343
|
-
|
|
26344
|
-
|
|
26345
|
-
|
|
26346
|
-
|
|
26347
|
-
files
|
|
26348
|
-
|
|
26349
|
-
|
|
26350
|
-
|
|
26390
|
+
...node2.commits ? { ci: node2.commits.nodes[0]?.commit.statusCheckRollup?.state ?? null } : {},
|
|
26391
|
+
...threads ? { threads } : {},
|
|
26392
|
+
...node2.additions !== void 0 ? { additions: node2.additions, deletions: node2.deletions ?? 0 } : {},
|
|
26393
|
+
...myReview !== void 0 ? {
|
|
26394
|
+
myReview: myReview && { state: myReview.state, upToDate: myReview.commit?.oid === node2.headRefOid }
|
|
26395
|
+
} : {},
|
|
26396
|
+
...node2.files ? {
|
|
26397
|
+
files: {
|
|
26398
|
+
viewed: node2.files.nodes.filter((f) => f.viewerViewedState === "VIEWED").length,
|
|
26399
|
+
total: node2.files.totalCount
|
|
26400
|
+
}
|
|
26401
|
+
} : {},
|
|
26351
26402
|
lastVisitAt: visit2?.visitedAt ?? null,
|
|
26352
26403
|
unread: !visit2 || visit2.headOid !== node2.headRefOid || lastOtherActivity > visit2.visitedAt
|
|
26353
26404
|
};
|
|
26354
26405
|
}
|
|
26355
|
-
function
|
|
26356
|
-
|
|
26406
|
+
function stageOf(pr) {
|
|
26407
|
+
if (pr.mergedAt !== null) return "merged";
|
|
26408
|
+
if (pr.inMergeQueue) return "queued";
|
|
26409
|
+
if (pr.isDraft) return "draft";
|
|
26410
|
+
if (isApproved(
|
|
26411
|
+
pr.reviewDecision,
|
|
26412
|
+
pr.reviews.map((r) => r.state)
|
|
26413
|
+
)) {
|
|
26414
|
+
const green = pr.ci === null || pr.ci === "SUCCESS";
|
|
26415
|
+
return green && (pr.threads?.open ?? 0) === 0 ? "ready" : "approved";
|
|
26416
|
+
}
|
|
26417
|
+
const reviewed = pr.reviewDecision === "CHANGES_REQUESTED" || pr.reviewCount > 0 || pr.reviews.length > 0 || (pr.threads?.total ?? 0) > 0;
|
|
26418
|
+
return reviewed ? "review" : "waiting";
|
|
26419
|
+
}
|
|
26420
|
+
function buildBoard(sources, me, visits, staleBefore) {
|
|
26421
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
26422
|
+
for (const node2 of [...sources.open, ...sources.merged]) nodes.set(node2.id, node2);
|
|
26423
|
+
const prs = [...nodes.values()].map((node2) => {
|
|
26357
26424
|
const [owner = "", repo = ""] = node2.repository.nameWithOwner.split("/");
|
|
26358
|
-
|
|
26359
|
-
|
|
26360
|
-
|
|
26361
|
-
|
|
26362
|
-
|
|
26363
|
-
|
|
26364
|
-
|
|
26365
|
-
|
|
26366
|
-
|
|
26367
|
-
|
|
26368
|
-
|
|
26369
|
-
|
|
26370
|
-
|
|
26371
|
-
|
|
26372
|
-
|
|
26373
|
-
|
|
26374
|
-
|
|
26375
|
-
|
|
26376
|
-
|
|
26377
|
-
|
|
26378
|
-
|
|
26379
|
-
|
|
26380
|
-
|
|
26425
|
+
const pr = toInboxPr(node2, me, visits.get(prKey(owner, repo, node2.number)));
|
|
26426
|
+
const stage = stageOf(pr);
|
|
26427
|
+
const mine = pr.author?.login === me;
|
|
26428
|
+
const tags = mine ? ["mine"] : [];
|
|
26429
|
+
if (stage === "merged") return { ...pr, stage, tags };
|
|
26430
|
+
if (mine) {
|
|
26431
|
+
const feedback = (pr.threads?.awaitingMyReply ?? 0) > 0 || pr.reviewDecision === "CHANGES_REQUESTED";
|
|
26432
|
+
if (!pr.isDraft && feedback) tags.push("todo");
|
|
26433
|
+
} else {
|
|
26434
|
+
if (sources.requested.has(node2.id)) tags.push("requested");
|
|
26435
|
+
if (pr.myReview && !pr.myReview.upToDate) tags.push("rereview");
|
|
26436
|
+
if (tags.length === 0 && (sources.involved.has(node2.id) || pr.myReview)) tags.push("involved");
|
|
26437
|
+
}
|
|
26438
|
+
if (Date.parse(pr.updatedAt) < staleBefore) tags.push("stale");
|
|
26439
|
+
if (stage === "waiting" && pr.requested.length === 0) tags.push("unreviewed");
|
|
26440
|
+
return { ...pr, stage, tags };
|
|
26441
|
+
});
|
|
26442
|
+
return prs.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
26443
|
+
}
|
|
26444
|
+
var MAX_SEARCH_PAGES = 10;
|
|
26445
|
+
var BATCH2 = 25;
|
|
26446
|
+
var PARALLEL = 12;
|
|
26447
|
+
async function retryOnTimeout(run2) {
|
|
26448
|
+
try {
|
|
26449
|
+
return await run2();
|
|
26450
|
+
} catch (error62) {
|
|
26451
|
+
if (error62 instanceof GitHubError && (error62.status === 502 || error62.status === 504)) return run2();
|
|
26452
|
+
throw error62;
|
|
26453
|
+
}
|
|
26454
|
+
}
|
|
26455
|
+
async function pool(tasks) {
|
|
26456
|
+
const results = new Array(tasks.length);
|
|
26457
|
+
let next = 0;
|
|
26458
|
+
const worker = async () => {
|
|
26459
|
+
while (next < tasks.length) {
|
|
26460
|
+
const i = next++;
|
|
26461
|
+
results[i] = await tasks[i]();
|
|
26462
|
+
}
|
|
26463
|
+
};
|
|
26464
|
+
await Promise.all(Array.from({ length: Math.min(PARALLEL, tasks.length) }, worker));
|
|
26465
|
+
return results;
|
|
26466
|
+
}
|
|
26467
|
+
async function fetchNodes(gh, query, ids) {
|
|
26468
|
+
const batches = [];
|
|
26469
|
+
for (let i = 0; i < ids.length; i += BATCH2) batches.push(ids.slice(i, i + BATCH2));
|
|
26470
|
+
const results = await pool(
|
|
26471
|
+
batches.map((batch) => () => retryOnTimeout(() => gh.graphql(query, { ids: batch })))
|
|
26381
26472
|
);
|
|
26382
|
-
|
|
26383
|
-
const involved = take(results.involved);
|
|
26384
|
-
const stale = results.stale.map(make);
|
|
26385
|
-
const unreviewed = results.unreviewed.map(make).filter((pr) => pr.requested.length === 0);
|
|
26386
|
-
const byUpdated = (a, b) => b.updatedAt.localeCompare(a.updatedAt);
|
|
26387
|
-
const sections = [
|
|
26388
|
-
{ id: "requested", prs: requested },
|
|
26389
|
-
{ id: "rereview", prs: rereview },
|
|
26390
|
-
{ id: "mine-todo", prs: mineTodo },
|
|
26391
|
-
{ id: "mine-waiting", prs: mineWaiting },
|
|
26392
|
-
{ id: "mine-ready", prs: mineReady },
|
|
26393
|
-
{ id: "mine-draft", prs: mineDraft },
|
|
26394
|
-
{ id: "involved", prs: involved },
|
|
26395
|
-
{ id: "stale", prs: stale.sort((a, b) => a.updatedAt.localeCompare(b.updatedAt)) },
|
|
26396
|
-
{ id: "unreviewed", prs: unreviewed }
|
|
26397
|
-
];
|
|
26398
|
-
for (const s of sections) if (s.id !== "stale") s.prs.sort(byUpdated);
|
|
26399
|
-
return sections;
|
|
26473
|
+
return results.flatMap((r) => r.nodes.filter((n) => n !== null));
|
|
26400
26474
|
}
|
|
26401
|
-
async function
|
|
26402
|
-
const
|
|
26475
|
+
async function searchIds(gh, q, pages) {
|
|
26476
|
+
const ids = [];
|
|
26477
|
+
let after = null;
|
|
26403
26478
|
let viewer2 = null;
|
|
26404
|
-
|
|
26405
|
-
|
|
26406
|
-
|
|
26407
|
-
searchQueries(scope, config2.staleDays, now)
|
|
26408
|
-
);
|
|
26479
|
+
let truncated = false;
|
|
26480
|
+
for (let page = 0; page < pages; page++) {
|
|
26481
|
+
const data = await gh.graphql(SEARCH_IDS_QUERY, { q, after });
|
|
26409
26482
|
viewer2 = data.viewer;
|
|
26410
|
-
for (const
|
|
26411
|
-
|
|
26412
|
-
|
|
26413
|
-
|
|
26414
|
-
}
|
|
26415
|
-
}
|
|
26416
|
-
const unique = [...new Set(INBOX_SECTION_IDS.flatMap((s) => idsBySection[s]))];
|
|
26417
|
-
const byId = /* @__PURE__ */ new Map();
|
|
26418
|
-
for (let i = 0; i < unique.length; i += 100) {
|
|
26419
|
-
const data = await gh.graphql(PR_SUMMARIES_QUERY, { ids: unique.slice(i, i + 100) });
|
|
26420
|
-
for (const node2 of data.nodes) if (node2) byId.set(node2.id, node2);
|
|
26483
|
+
for (const node2 of data.search.nodes) if (node2.id) ids.push(node2.id);
|
|
26484
|
+
if (!data.search.pageInfo.hasNextPage) break;
|
|
26485
|
+
after = data.search.pageInfo.endCursor;
|
|
26486
|
+
truncated = page === pages - 1;
|
|
26421
26487
|
}
|
|
26422
|
-
|
|
26423
|
-
|
|
26488
|
+
return { viewer: viewer2, ids, truncated };
|
|
26489
|
+
}
|
|
26490
|
+
var SIDE_SEARCHES = ["requested", "involved", "reviewed", "merged"];
|
|
26491
|
+
async function loadSources(gh, config2, now) {
|
|
26492
|
+
const open2 = scopeTerms(config2).map(
|
|
26493
|
+
(term) => () => searchIds(gh, searchQueries(term, 0).open, MAX_SEARCH_PAGES)
|
|
26424
26494
|
);
|
|
26425
|
-
|
|
26495
|
+
const side = scopeChunks(config2).flatMap((chunk) => {
|
|
26496
|
+
const queries = searchQueries(chunk, now - MERGED_WINDOW_MS);
|
|
26497
|
+
return SIDE_SEARCHES.map((name) => async () => ({ name, ...await searchIds(gh, queries[name], 1) }));
|
|
26498
|
+
});
|
|
26499
|
+
const [openResults, sideResults] = await Promise.all([pool(open2), pool(side)]);
|
|
26500
|
+
const viewer2 = openResults[0]?.viewer ?? sideResults[0]?.viewer ?? null;
|
|
26501
|
+
const sideIds = (name) => new Set(sideResults.filter((r) => r.name === name).flatMap((r) => r.ids));
|
|
26502
|
+
const requested = sideIds("requested");
|
|
26503
|
+
const involved = sideIds("involved");
|
|
26504
|
+
const reviewed = sideIds("reviewed");
|
|
26505
|
+
const mergedIds = [...sideIds("merged")];
|
|
26506
|
+
const openIds = [...new Set(openResults.flatMap((r) => r.ids))];
|
|
26507
|
+
const board = await fetchNodes(gh, BOARD_QUERY, [.../* @__PURE__ */ new Set([...openIds, ...mergedIds])]);
|
|
26508
|
+
const byId = new Map(board.map((node2) => [node2.id, node2]));
|
|
26509
|
+
const me = viewer2?.login;
|
|
26510
|
+
const personal = [];
|
|
26511
|
+
const approved = [];
|
|
26512
|
+
for (const node2 of board) {
|
|
26513
|
+
if (node2.mergedAt !== null) continue;
|
|
26514
|
+
const concernsMe = requested.has(node2.id) || involved.has(node2.id) || reviewed.has(node2.id) || node2.author?.login === me;
|
|
26515
|
+
if (concernsMe) personal.push(node2.id);
|
|
26516
|
+
else if (isApproved(
|
|
26517
|
+
node2.reviewDecision,
|
|
26518
|
+
node2.latestOpinionatedReviews.nodes.map((r) => r.state)
|
|
26519
|
+
)) {
|
|
26520
|
+
approved.push(node2.id);
|
|
26521
|
+
}
|
|
26522
|
+
}
|
|
26523
|
+
const [details, checks] = await Promise.all([
|
|
26524
|
+
fetchNodes(gh, DETAILS_QUERY, personal),
|
|
26525
|
+
fetchNodes(gh, CHECKS_QUERY, approved)
|
|
26526
|
+
]);
|
|
26527
|
+
for (const extra of [...details, ...checks]) {
|
|
26528
|
+
const node2 = byId.get(extra.id);
|
|
26529
|
+
if (node2) byId.set(extra.id, { ...node2, ...extra });
|
|
26530
|
+
}
|
|
26531
|
+
const nodesOf = (list) => list.flatMap((id) => byId.get(id) ?? []);
|
|
26532
|
+
return {
|
|
26533
|
+
viewer: viewer2,
|
|
26534
|
+
truncated: openResults.some((r) => r.truncated),
|
|
26535
|
+
sources: { open: nodesOf(openIds), merged: nodesOf(mergedIds), requested, involved }
|
|
26536
|
+
};
|
|
26426
26537
|
}
|
|
26427
26538
|
async function loadInbox(gh, config2, viewerFallback, lastVisits) {
|
|
26428
26539
|
const now = Date.now();
|
|
26429
|
-
const { viewer: viewer2,
|
|
26540
|
+
const { viewer: viewer2, truncated, sources } = await loadSources(gh, config2, now);
|
|
26430
26541
|
const me = viewer2 ?? await viewerFallback();
|
|
26431
|
-
const keys =
|
|
26432
|
-
|
|
26433
|
-
|
|
26434
|
-
|
|
26435
|
-
})
|
|
26436
|
-
);
|
|
26542
|
+
const keys = [...sources.open, ...sources.merged].map((n) => {
|
|
26543
|
+
const [owner = "", repo = ""] = n.repository.nameWithOwner.split("/");
|
|
26544
|
+
return prKey(owner, repo, n.number);
|
|
26545
|
+
});
|
|
26437
26546
|
return {
|
|
26438
26547
|
viewer: me,
|
|
26439
26548
|
configured: config2.repos.length + config2.orgs.length > 0,
|
|
26440
|
-
|
|
26549
|
+
prs: buildBoard(sources, me.login, lastVisits([...new Set(keys)]), now - config2.staleDays * 864e5),
|
|
26550
|
+
truncated,
|
|
26441
26551
|
fetchedAt: now
|
|
26442
26552
|
};
|
|
26443
26553
|
}
|
|
26444
26554
|
async function inboxFingerprint(gh, config2, signal) {
|
|
26445
26555
|
const parts = [];
|
|
26446
26556
|
for (const scope of scopeChunks(config2)) {
|
|
26447
|
-
const data = await gh.graphql(
|
|
26557
|
+
const data = await gh.graphql(
|
|
26558
|
+
INBOX_FINGERPRINT_QUERY,
|
|
26559
|
+
{ q: `is:pr is:open archived:false ${scope} sort:updated-desc` },
|
|
26560
|
+
signal
|
|
26561
|
+
);
|
|
26448
26562
|
parts.push(String(data.search.issueCount));
|
|
26449
|
-
for (const n of data.search.nodes)
|
|
26563
|
+
for (const n of data.search.nodes) {
|
|
26564
|
+
const ci = n.commits?.nodes[0]?.commit.statusCheckRollup?.state ?? "";
|
|
26565
|
+
parts.push(`${n.id}:${n.updatedAt}:${n.headRefOid}:${n.reviewDecision}:${n.isInMergeQueue}:${ci}`);
|
|
26566
|
+
}
|
|
26450
26567
|
}
|
|
26451
26568
|
return parts.join("|");
|
|
26452
26569
|
}
|
|
@@ -26497,7 +26614,6 @@ async function loadPr(gh, store, ref) {
|
|
|
26497
26614
|
reviewers.set(rr.login, { login: rr.login, avatarUrl: rr.avatarUrl, state: "REQUESTED" });
|
|
26498
26615
|
else if (rr?.__typename === "Team") requestedTeams.push(rr.slug);
|
|
26499
26616
|
}
|
|
26500
|
-
const rollup = pr.lastCommit.nodes[0]?.commit.statusCheckRollup ?? null;
|
|
26501
26617
|
const timeline = [
|
|
26502
26618
|
...pr.comments.nodes.map((c) => ({
|
|
26503
26619
|
kind: "comment",
|
|
@@ -26505,6 +26621,7 @@ async function loadPr(gh, store, ref) {
|
|
|
26505
26621
|
url: c.url,
|
|
26506
26622
|
body: c.body,
|
|
26507
26623
|
bodyHTML: c.bodyHTML,
|
|
26624
|
+
reactions: toReactions(c.reactionGroups),
|
|
26508
26625
|
createdAt: c.createdAt,
|
|
26509
26626
|
author: c.author,
|
|
26510
26627
|
unread: c.author?.login !== me && Date.parse(c.createdAt) > lastVisitAt
|
|
@@ -26516,6 +26633,7 @@ async function loadPr(gh, store, ref) {
|
|
|
26516
26633
|
state: r.state,
|
|
26517
26634
|
body: r.body,
|
|
26518
26635
|
bodyHTML: r.bodyHTML,
|
|
26636
|
+
reactions: toReactions(r.reactionGroups),
|
|
26519
26637
|
createdAt: r.submittedAt ?? r.createdAt,
|
|
26520
26638
|
author: r.author,
|
|
26521
26639
|
unread: r.author?.login !== me && Date.parse(r.submittedAt ?? r.createdAt) > lastVisitAt
|
|
@@ -26537,6 +26655,7 @@ async function loadPr(gh, store, ref) {
|
|
|
26537
26655
|
updatedAt: pr.updatedAt,
|
|
26538
26656
|
body: pr.body,
|
|
26539
26657
|
bodyHTML: pr.bodyHTML,
|
|
26658
|
+
reactions: toReactions(pr.reactionGroups),
|
|
26540
26659
|
baseRefName: pr.baseRefName,
|
|
26541
26660
|
headRefName: pr.headRefName,
|
|
26542
26661
|
baseRefOid: pr.baseRefOid,
|
|
@@ -26549,12 +26668,6 @@ async function loadPr(gh, store, ref) {
|
|
|
26549
26668
|
author: pr.author,
|
|
26550
26669
|
sameRepo: pr.headRepository?.nameWithOwner.toLowerCase() === `${ref.owner}/${ref.repo}`.toLowerCase()
|
|
26551
26670
|
},
|
|
26552
|
-
checks: rollup ? {
|
|
26553
|
-
state: rollup.state,
|
|
26554
|
-
contexts: rollup.contexts.nodes.map(
|
|
26555
|
-
(c) => c.__typename === "CheckRun" ? { name: c.name, state: c.conclusion ?? c.status, url: c.detailsUrl } : { name: c.context, state: c.state, url: c.targetUrl }
|
|
26556
|
-
)
|
|
26557
|
-
} : null,
|
|
26558
26671
|
reviewers: [...reviewers.values()],
|
|
26559
26672
|
requestedTeams,
|
|
26560
26673
|
myReview: pr.viewerLatestReview ? {
|
|
@@ -26586,6 +26699,9 @@ async function loadPr(gh, store, ref) {
|
|
|
26586
26699
|
seenHunks: store.seenHunks(key)
|
|
26587
26700
|
};
|
|
26588
26701
|
}
|
|
26702
|
+
function toReactions(groups) {
|
|
26703
|
+
return (groups ?? []).filter((g) => g.reactors.totalCount > 0).map((g) => ({ content: g.content, count: g.reactors.totalCount, mine: g.viewerHasReacted }));
|
|
26704
|
+
}
|
|
26589
26705
|
function toComment(c) {
|
|
26590
26706
|
return {
|
|
26591
26707
|
id: c.id,
|
|
@@ -26593,6 +26709,7 @@ function toComment(c) {
|
|
|
26593
26709
|
url: c.url,
|
|
26594
26710
|
body: c.body,
|
|
26595
26711
|
bodyHTML: c.bodyHTML,
|
|
26712
|
+
reactions: toReactions(c.reactionGroups),
|
|
26596
26713
|
createdAt: c.createdAt,
|
|
26597
26714
|
author: c.author,
|
|
26598
26715
|
pending: c.state === "PENDING",
|
|
@@ -26720,6 +26837,17 @@ async function setFileViewed(gh, prId, path, viewed) {
|
|
|
26720
26837
|
{ id: prId, path }
|
|
26721
26838
|
);
|
|
26722
26839
|
}
|
|
26840
|
+
async function setReaction(gh, subjectId, content, on2) {
|
|
26841
|
+
const mutation = on2 ? "addReaction" : "removeReaction";
|
|
26842
|
+
const data = await gh.graphql(
|
|
26843
|
+
`mutation($id: ID!, $content: ReactionContent!) {
|
|
26844
|
+
${mutation}(input: { subjectId: $id, content: $content }) { subject { ...ReactionFields } }
|
|
26845
|
+
}
|
|
26846
|
+
${REACTION_FIELDS}`,
|
|
26847
|
+
{ id: subjectId, content }
|
|
26848
|
+
);
|
|
26849
|
+
return toReactions(data[mutation].subject.reactionGroups);
|
|
26850
|
+
}
|
|
26723
26851
|
async function replyToThread(gh, threadId, body, pendingReviewId) {
|
|
26724
26852
|
const data = await gh.graphql(
|
|
26725
26853
|
`mutation($thread: ID!, $body: String!, $review: ID) {
|
|
@@ -26816,7 +26944,7 @@ async function addIssueComment(gh, subjectId, body) {
|
|
|
26816
26944
|
}`,
|
|
26817
26945
|
{ id: subjectId, body }
|
|
26818
26946
|
);
|
|
26819
|
-
return { kind: "comment", ...data.addComment.commentEdge.node, unread: false };
|
|
26947
|
+
return { kind: "comment", ...data.addComment.commentEdge.node, reactions: [], unread: false };
|
|
26820
26948
|
}
|
|
26821
26949
|
async function deleteReviewComment(gh, commentId) {
|
|
26822
26950
|
await gh.graphql(
|
|
@@ -26873,6 +27001,102 @@ async function applySuggestion(gh, ref, input2) {
|
|
|
26873
27001
|
return res.commit.sha;
|
|
26874
27002
|
}
|
|
26875
27003
|
|
|
27004
|
+
// ../server/src/checks.ts
|
|
27005
|
+
var PR_CHECKS_QUERY = (
|
|
27006
|
+
/* GraphQL */
|
|
27007
|
+
`
|
|
27008
|
+
query PrChecks($owner: String!, $repo: String!, $number: Int!) {
|
|
27009
|
+
repository(owner: $owner, name: $repo) {
|
|
27010
|
+
pullRequest(number: $number) {
|
|
27011
|
+
commits(last: 1) {
|
|
27012
|
+
nodes {
|
|
27013
|
+
commit {
|
|
27014
|
+
statusCheckRollup {
|
|
27015
|
+
state
|
|
27016
|
+
contexts(first: 100) {
|
|
27017
|
+
nodes {
|
|
27018
|
+
__typename
|
|
27019
|
+
... on CheckRun {
|
|
27020
|
+
name
|
|
27021
|
+
conclusion
|
|
27022
|
+
status
|
|
27023
|
+
detailsUrl
|
|
27024
|
+
title
|
|
27025
|
+
checkSuite {
|
|
27026
|
+
workflowRun {
|
|
27027
|
+
workflow {
|
|
27028
|
+
name
|
|
27029
|
+
}
|
|
27030
|
+
}
|
|
27031
|
+
}
|
|
27032
|
+
}
|
|
27033
|
+
... on StatusContext {
|
|
27034
|
+
context
|
|
27035
|
+
state
|
|
27036
|
+
targetUrl
|
|
27037
|
+
description
|
|
27038
|
+
}
|
|
27039
|
+
}
|
|
27040
|
+
}
|
|
27041
|
+
}
|
|
27042
|
+
}
|
|
27043
|
+
}
|
|
27044
|
+
}
|
|
27045
|
+
}
|
|
27046
|
+
}
|
|
27047
|
+
}
|
|
27048
|
+
`
|
|
27049
|
+
);
|
|
27050
|
+
var FAILED = /* @__PURE__ */ new Set(["FAILURE", "TIMED_OUT", "STARTUP_FAILURE", "ACTION_REQUIRED", "CANCELLED", "ERROR"]);
|
|
27051
|
+
var SKIPPED = /* @__PURE__ */ new Set(["NEUTRAL", "SKIPPED", "STALE"]);
|
|
27052
|
+
var RANK = { failure: 0, pending: 1, success: 2, skipped: 3 };
|
|
27053
|
+
function outcomeOf(state) {
|
|
27054
|
+
if (FAILED.has(state)) return "failure";
|
|
27055
|
+
if (state === "SUCCESS") return "success";
|
|
27056
|
+
if (SKIPPED.has(state)) return "skipped";
|
|
27057
|
+
return "pending";
|
|
27058
|
+
}
|
|
27059
|
+
function toChecks(rollup) {
|
|
27060
|
+
if (!rollup) return null;
|
|
27061
|
+
const all = rollup.contexts.nodes.map((c) => {
|
|
27062
|
+
if (c.__typename === "StatusContext") {
|
|
27063
|
+
return {
|
|
27064
|
+
name: c.context,
|
|
27065
|
+
outcome: outcomeOf(c.state),
|
|
27066
|
+
state: c.state.toLowerCase(),
|
|
27067
|
+
url: c.targetUrl,
|
|
27068
|
+
summary: c.description || null
|
|
27069
|
+
};
|
|
27070
|
+
}
|
|
27071
|
+
const state = c.conclusion ?? c.status;
|
|
27072
|
+
const workflow = c.checkSuite?.workflowRun?.workflow.name;
|
|
27073
|
+
return {
|
|
27074
|
+
name: workflow ? `${workflow} / ${c.name}` : c.name,
|
|
27075
|
+
outcome: outcomeOf(state),
|
|
27076
|
+
state: state.toLowerCase(),
|
|
27077
|
+
url: c.detailsUrl,
|
|
27078
|
+
summary: c.title || null
|
|
27079
|
+
};
|
|
27080
|
+
});
|
|
27081
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27082
|
+
const checks = all.filter((c) => {
|
|
27083
|
+
const key = `${c.name}\0${c.outcome}`;
|
|
27084
|
+
if (seen.has(key)) return false;
|
|
27085
|
+
seen.add(key);
|
|
27086
|
+
return true;
|
|
27087
|
+
});
|
|
27088
|
+
checks.sort((a, b) => RANK[a.outcome] - RANK[b.outcome] || a.name.localeCompare(b.name));
|
|
27089
|
+
return { state: rollup.state, checks };
|
|
27090
|
+
}
|
|
27091
|
+
async function loadChecks(gh, ref) {
|
|
27092
|
+
const data = await gh.graphql(PR_CHECKS_QUERY, {
|
|
27093
|
+
owner: ref.owner,
|
|
27094
|
+
repo: ref.repo,
|
|
27095
|
+
number: ref.number
|
|
27096
|
+
});
|
|
27097
|
+
return toChecks(data.repository?.pullRequest?.commits.nodes[0]?.commit.statusCheckRollup ?? null);
|
|
27098
|
+
}
|
|
27099
|
+
|
|
26876
27100
|
// ../../packages/language/src/paths.ts
|
|
26877
27101
|
function normalizePath(path) {
|
|
26878
27102
|
const segments = [];
|
|
@@ -27857,6 +28081,58 @@ async function loadLinks(gh, store, ref, base, head, fullPr) {
|
|
|
27857
28081
|
return links;
|
|
27858
28082
|
}
|
|
27859
28083
|
|
|
28084
|
+
// ../server/src/poll.ts
|
|
28085
|
+
function sleep(ms, signal) {
|
|
28086
|
+
const { promise: promise2, resolve } = Promise.withResolvers();
|
|
28087
|
+
const timer = setTimeout(resolve, ms);
|
|
28088
|
+
signal?.addEventListener(
|
|
28089
|
+
"abort",
|
|
28090
|
+
() => {
|
|
28091
|
+
clearTimeout(timer);
|
|
28092
|
+
resolve();
|
|
28093
|
+
},
|
|
28094
|
+
{ once: true }
|
|
28095
|
+
);
|
|
28096
|
+
return promise2;
|
|
28097
|
+
}
|
|
28098
|
+
async function* pollChanges(intervalMs, signal, fingerprint, extraTrigger) {
|
|
28099
|
+
let last = null;
|
|
28100
|
+
try {
|
|
28101
|
+
last = await fingerprint();
|
|
28102
|
+
} catch (error62) {
|
|
28103
|
+
console.warn("[poll]", error62 instanceof Error ? error62.message : error62);
|
|
28104
|
+
}
|
|
28105
|
+
const triggerIt = extraTrigger?.[Symbol.asyncIterator]();
|
|
28106
|
+
const nextTrigger = () => {
|
|
28107
|
+
const promise2 = triggerIt?.next();
|
|
28108
|
+
promise2?.catch(() => void 0);
|
|
28109
|
+
return promise2;
|
|
28110
|
+
};
|
|
28111
|
+
let pendingTrigger = signal?.aborted ? void 0 : nextTrigger();
|
|
28112
|
+
try {
|
|
28113
|
+
while (!signal?.aborted) {
|
|
28114
|
+
const tick = sleep(intervalMs, signal).then(() => "tick");
|
|
28115
|
+
const winner = pendingTrigger ? await Promise.race([tick, pendingTrigger.then(() => "trigger")]) : await tick;
|
|
28116
|
+
if (signal?.aborted) return;
|
|
28117
|
+
if (winner === "trigger") {
|
|
28118
|
+
pendingTrigger = nextTrigger();
|
|
28119
|
+
last = null;
|
|
28120
|
+
yield { at: Date.now() };
|
|
28121
|
+
continue;
|
|
28122
|
+
}
|
|
28123
|
+
try {
|
|
28124
|
+
const next = await fingerprint();
|
|
28125
|
+
if (last !== null && next !== last) yield { at: Date.now() };
|
|
28126
|
+
last = next;
|
|
28127
|
+
} catch (error62) {
|
|
28128
|
+
console.warn("[poll]", error62 instanceof Error ? error62.message : error62);
|
|
28129
|
+
}
|
|
28130
|
+
}
|
|
28131
|
+
} finally {
|
|
28132
|
+
await triggerIt?.return?.().catch(() => void 0);
|
|
28133
|
+
}
|
|
28134
|
+
}
|
|
28135
|
+
|
|
27860
28136
|
// ../../node_modules/.pnpm/@trpc+server@11.19.0_typescript@6.0.3/node_modules/@trpc/server/dist/initTRPC-B259os3T.mjs
|
|
27861
28137
|
var middlewareMarker = "middlewareMarker";
|
|
27862
28138
|
function createMiddlewareFactory() {
|
|
@@ -28202,51 +28478,10 @@ var procedure = t.procedure.use(githubErrors);
|
|
|
28202
28478
|
|
|
28203
28479
|
// ../server/src/router.ts
|
|
28204
28480
|
var PR_POLL_MS = 3e4;
|
|
28205
|
-
var INBOX_POLL_MS =
|
|
28481
|
+
var INBOX_POLL_MS = 6e4;
|
|
28206
28482
|
async function viewer(ctx) {
|
|
28207
28483
|
return (await ctx.gh.graphql("{ viewer { login avatarUrl } }")).viewer;
|
|
28208
28484
|
}
|
|
28209
|
-
function sleep(ms, signal) {
|
|
28210
|
-
const { promise: promise2, resolve } = Promise.withResolvers();
|
|
28211
|
-
const timer = setTimeout(resolve, ms);
|
|
28212
|
-
signal?.addEventListener(
|
|
28213
|
-
"abort",
|
|
28214
|
-
() => {
|
|
28215
|
-
clearTimeout(timer);
|
|
28216
|
-
resolve();
|
|
28217
|
-
},
|
|
28218
|
-
{ once: true }
|
|
28219
|
-
);
|
|
28220
|
-
return promise2;
|
|
28221
|
-
}
|
|
28222
|
-
async function* pollChanges(intervalMs, signal, fingerprint, extraTrigger) {
|
|
28223
|
-
let last = null;
|
|
28224
|
-
try {
|
|
28225
|
-
last = await fingerprint();
|
|
28226
|
-
} catch (error62) {
|
|
28227
|
-
console.warn("[poll]", error62 instanceof Error ? error62.message : error62);
|
|
28228
|
-
}
|
|
28229
|
-
const triggerIt = extraTrigger?.[Symbol.asyncIterator]();
|
|
28230
|
-
let pendingTrigger = triggerIt?.next();
|
|
28231
|
-
while (!signal?.aborted) {
|
|
28232
|
-
const tick = sleep(intervalMs, signal).then(() => "tick");
|
|
28233
|
-
const winner = pendingTrigger ? await Promise.race([tick, pendingTrigger.then(() => "trigger")]) : await tick;
|
|
28234
|
-
if (signal?.aborted) return;
|
|
28235
|
-
if (winner === "trigger") {
|
|
28236
|
-
pendingTrigger = triggerIt?.next();
|
|
28237
|
-
last = null;
|
|
28238
|
-
yield { at: Date.now() };
|
|
28239
|
-
continue;
|
|
28240
|
-
}
|
|
28241
|
-
try {
|
|
28242
|
-
const next = await fingerprint();
|
|
28243
|
-
if (last !== null && next !== last) yield { at: Date.now() };
|
|
28244
|
-
last = next;
|
|
28245
|
-
} catch (error62) {
|
|
28246
|
-
console.warn("[poll]", error62 instanceof Error ? error62.message : error62);
|
|
28247
|
-
}
|
|
28248
|
-
}
|
|
28249
|
-
}
|
|
28250
28485
|
var configRouter = router({
|
|
28251
28486
|
get: procedure.query(({ ctx }) => ctx.config.get()),
|
|
28252
28487
|
add: procedure.input(trackedEntrySchema).mutation(async ({ ctx, input: input2 }) => {
|
|
@@ -28276,6 +28511,8 @@ var inboxRouter = router({
|
|
|
28276
28511
|
});
|
|
28277
28512
|
var prRouter = router({
|
|
28278
28513
|
get: procedure.input(prRefSchema).query(({ ctx, input: input2 }) => loadPr(ctx.gh, ctx.store, input2)),
|
|
28514
|
+
/** Polled by the PR page while checks run. */
|
|
28515
|
+
checks: procedure.input(prRefSchema).query(({ ctx, input: input2 }) => loadChecks(ctx.gh, input2)),
|
|
28279
28516
|
diff: procedure.input(external_exports.object({ ref: prRefSchema, base: shaSchema, head: shaSchema, fullPr: external_exports.boolean() })).query(({ ctx, input: input2 }) => loadDiff(ctx.gh, ctx.store, input2.ref, input2.base, input2.head, input2.fullPr)),
|
|
28280
28517
|
links: procedure.input(external_exports.object({ ref: prRefSchema, base: shaSchema, head: shaSchema, fullPr: external_exports.boolean() })).query(({ ctx, input: input2 }) => loadLinks(ctx.gh, ctx.store, input2.ref, input2.base, input2.head, input2.fullPr)),
|
|
28281
28518
|
blobs: procedure.input(external_exports.object({ ref: prRefSchema, oids: external_exports.array(shaSchema).min(1).max(2) })).query(({ ctx, input: input2 }) => loadBlobs(ctx.gh, ctx.store, input2.ref, input2.oids)),
|
|
@@ -28316,6 +28553,7 @@ var prRouter = router({
|
|
|
28316
28553
|
({ ctx, input: input2 }) => replyToThread(ctx.gh, input2.threadId, input2.body, input2.pendingReviewId)
|
|
28317
28554
|
),
|
|
28318
28555
|
setResolved: procedure.input(external_exports.object({ threadId: external_exports.string(), resolved: external_exports.boolean() })).mutation(({ ctx, input: input2 }) => setThreadResolved(ctx.gh, input2.threadId, input2.resolved)),
|
|
28556
|
+
react: procedure.input(external_exports.object({ subjectId: external_exports.string(), content: reactionContentSchema, on: external_exports.boolean() })).mutation(({ ctx, input: input2 }) => setReaction(ctx.gh, input2.subjectId, input2.content, input2.on)),
|
|
28319
28557
|
addThread: procedure.input(
|
|
28320
28558
|
external_exports.object({
|
|
28321
28559
|
prId: external_exports.string(),
|