Skip to content

Commit 4dc1785

Browse files
committed
feat(api): merge query
Signed-off-by: Adam Setch <[email protected]>
1 parent 6bccaa9 commit 4dc1785

File tree

13 files changed

+435
-149
lines changed

13 files changed

+435
-149
lines changed

src/renderer/utils/api/client.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,9 @@ export async function fetchIssueByNumber(
207207
notification.account.token,
208208
FetchIssueByNumberDocument,
209209
{
210-
owner: notification.repository.owner.login,
211-
name: notification.repository.name,
212-
number: number,
210+
ownerINDEX: notification.repository.owner.login,
211+
nameINDEX: notification.repository.name,
212+
numberINDEX: number,
213213
firstLabels: 100,
214214
lastComments: 1,
215215
},
@@ -230,11 +230,11 @@ export async function fetchPullByNumber(
230230
notification.account.token,
231231
FetchPullRequestByNumberDocument,
232232
{
233-
owner: notification.repository.owner.login,
234-
name: notification.repository.name,
235-
number: number,
236-
firstLabels: 100,
233+
ownerINDEX: notification.repository.owner.login,
234+
nameINDEX: notification.repository.name,
235+
numberINDEX: number,
237236
firstClosingIssues: 100,
237+
firstLabels: 100,
238238
lastComments: 1,
239239
lastReviews: 100,
240240
},
@@ -255,12 +255,12 @@ export async function fetchDiscussionByNumber(
255255
notification.account.token,
256256
FetchDiscussionByNumberDocument,
257257
{
258-
owner: notification.repository.owner.login,
259-
name: notification.repository.name,
260-
number: number,
258+
ownerINDEX: notification.repository.owner.login,
259+
nameINDEX: notification.repository.name,
260+
numberINDEX: number,
261+
firstLabels: 100,
261262
lastComments: 10,
262263
lastReplies: 10,
263-
firstLabels: 100,
264264
includeIsAnswered: isAnsweredDiscussionFeatureSupported(
265265
notification.account,
266266
),

src/renderer/utils/api/graphql/discussion.graphql

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
query FetchDiscussionByNumber(
2-
$owner: String!
3-
$name: String!
4-
$number: Int!
2+
$ownerINDEX: String!
3+
$nameINDEX: String!
4+
$numberINDEX: Int!
55
$lastComments: Int
66
$lastReplies: Int
77
$firstLabels: Int
88
$includeIsAnswered: Boolean!
99
) {
10-
repository(owner: $owner, name: $name) {
11-
discussion(number: $number) {
10+
...DiscussionMergeQuery
11+
}
12+
13+
fragment DiscussionMergeQuery on Query {
14+
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
15+
discussion(number: $numberINDEX) {
1216
...DiscussionDetails
1317
}
1418
}

src/renderer/utils/api/graphql/generated/gql.ts

Lines changed: 9 additions & 9 deletions
Large diffs are not rendered by default.

src/renderer/utils/api/graphql/generated/graphql.ts

Lines changed: 256 additions & 29 deletions
Large diffs are not rendered by default.

src/renderer/utils/api/graphql/issue.graphql

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
query FetchIssueByNumber(
2-
$owner: String!
3-
$name: String!
4-
$number: Int!
2+
$ownerINDEX: String!
3+
$nameINDEX: String!
4+
$numberINDEX: Int!
55
$lastComments: Int
66
$firstLabels: Int
77
) {
8-
repository(owner: $owner, name: $name) {
9-
issue(number: $number) {
8+
...IssueMergeQuery
9+
}
10+
fragment IssueMergeQuery on Query {
11+
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
12+
issue(number: $numberINDEX) {
1013
...IssueDetails
1114
}
1215
}

src/renderer/utils/api/graphql/pull.graphql

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
query FetchPullRequestByNumber(
2-
$owner: String!
3-
$name: String!
4-
$number: Int!
2+
$ownerINDEX: String!
3+
$nameINDEX: String!
4+
$numberINDEX: Int!
55
$firstLabels: Int
66
$lastComments: Int
77
$lastReviews: Int
88
$firstClosingIssues: Int
99
) {
10-
repository(owner: $owner, name: $name) {
11-
pullRequest(number: $number) {
10+
...PullRequestMergeQuery
11+
}
12+
13+
fragment PullRequestMergeQuery on Query {
14+
nodeINDEX: repository(owner: $ownerINDEX, name: $nameINDEX) {
15+
pullRequest(number: $numberINDEX) {
1216
...PullRequestDetails
1317
}
1418
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export function getQueryFragmentBody(doc: string): string | null {
2+
// Find fragment on Query pattern
3+
const fragmentMatch = doc.match(/fragment\s+\w+\s+on\s+Query\s+\{/);
4+
if (!fragmentMatch) {
5+
return null;
6+
}
7+
8+
const start = fragmentMatch.index + fragmentMatch[0].length - 1; // Position of opening brace
9+
let depth = 0;
10+
11+
for (let i = start; i < doc.length; i++) {
12+
if (doc[i] === '{') {
13+
depth++;
14+
} else if (doc[i] === '}') {
15+
depth--;
16+
if (depth === 0) {
17+
return doc.slice(start + 1, i).trim();
18+
}
19+
}
20+
}
21+
return null;
22+
}

src/renderer/utils/notifications/handlers/default.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import { formatForDisplay } from './utils';
1212
export class DefaultHandler implements NotificationTypeHandler {
1313
type?: SubjectType;
1414

15+
mergeQueryConfig() {
16+
return undefined;
17+
}
18+
1519
query(_notification: Notification) {
1620
return null;
1721
}

src/renderer/utils/notifications/handlers/discussion.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,51 @@ import {
1919
} from '../../../types';
2020
import type { Notification, Subject } from '../../../typesGitHub';
2121
import { fetchDiscussionByNumber } from '../../api/client';
22-
import type {
23-
CommentFieldsFragment,
24-
DiscussionCommentFieldsFragment,
25-
DiscussionDetailsFragment,
22+
import {
23+
type CommentFieldsFragment,
24+
type DiscussionCommentFieldsFragment,
25+
type DiscussionDetailsFragment,
26+
DiscussionDetailsFragmentDoc,
27+
DiscussionMergeQueryFragmentDoc,
2628
} from '../../api/graphql/generated/graphql';
29+
import { getQueryFragmentBody } from '../../api/graphql/utils';
2730
import { DefaultHandler, defaultHandler } from './default';
31+
import type { GraphQLMergedQueryConfig } from './types';
2832
import { getNotificationAuthor } from './utils';
2933

3034
class DiscussionHandler extends DefaultHandler {
3135
readonly type = 'Discussion';
3236

37+
mergeQueryConfig() {
38+
return {
39+
queryFragment: getQueryFragmentBody(
40+
DiscussionMergeQueryFragmentDoc.toString(),
41+
),
42+
responseFragment: DiscussionDetailsFragmentDoc.toString(),
43+
extras: [
44+
{ name: 'lastComments', type: 'Int', defaultValue: 100 },
45+
{ name: 'lastReplies', type: 'Int', defaultValue: 100 },
46+
{ name: 'firstLabels', type: 'Int', defaultValue: 100 },
47+
{ name: 'includeIsAnswered', type: 'Boolean!', defaultValue: true },
48+
],
49+
selection: (
50+
index: number,
51+
) => `node${index}: repository(owner: $owner${index}, name: $name${index}) {
52+
discussion(number: $number${index}) {
53+
...DiscussionDetails
54+
}
55+
}`,
56+
} as GraphQLMergedQueryConfig;
57+
}
58+
3359
async enrich(
3460
notification: Notification,
3561
_settings: SettingsState,
3662
fetchedData?: DiscussionDetailsFragment,
3763
): Promise<GitifySubject> {
3864
const discussion =
3965
fetchedData ??
40-
(await fetchDiscussionByNumber(notification)).data.repository?.discussion;
66+
(await fetchDiscussionByNumber(notification)).data.nodeINDEX?.discussion;
4167

4268
let discussionState: GitifyDiscussionState = 'OPEN';
4369

src/renderer/utils/notifications/handlers/issue.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,40 @@ import type {
1616
} from '../../../types';
1717
import { IconColor } from '../../../types';
1818
import type { Notification, Subject } from '../../../typesGitHub';
19-
import type { IssueDetailsFragment } from '../../api/graphql/generated/graphql';
19+
import {
20+
type IssueDetailsFragment,
21+
IssueDetailsFragmentDoc,
22+
IssueMergeQueryFragmentDoc,
23+
} from '../../api/graphql/generated/graphql';
24+
import { getQueryFragmentBody } from '../../api/graphql/utils';
2025
import { DefaultHandler, defaultHandler } from './default';
26+
import type { GraphQLMergedQueryConfig } from './types';
2127
import { getNotificationAuthor } from './utils';
2228

2329
class IssueHandler extends DefaultHandler {
2430
readonly type = 'Issue';
2531

32+
mergeQueryConfig() {
33+
return {
34+
queryFragment: getQueryFragmentBody(
35+
IssueMergeQueryFragmentDoc.toString(),
36+
),
37+
38+
responseFragment: IssueDetailsFragmentDoc.toString(),
39+
extras: [
40+
{ name: 'lastComments', type: 'Int', defaultValue: 100 },
41+
{ name: 'firstLabels', type: 'Int', defaultValue: 100 },
42+
],
43+
selection: (
44+
index: number,
45+
) => `node${index}: repository(owner: $owner${index}, name: $name${index}) {
46+
issue(number: $number${index}) {
47+
...IssueDetails
48+
}
49+
}`,
50+
} as GraphQLMergedQueryConfig;
51+
}
52+
2653
async enrich(
2754
_notification: Notification,
2855
_settings: SettingsState,

0 commit comments

Comments
 (0)