Skip to content

Commit 239b6a4

Browse files
committed
refactor: use octokit client
Signed-off-by: Adam Setch <adam.setch@outlook.com>
1 parent ff20dc2 commit 239b6a4

14 files changed

Lines changed: 192 additions & 239 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,4 @@
151151
"*": "biome check --no-errors-on-unmatched",
152152
"*.{js,ts,tsx}": "pnpm test --findRelatedTests --passWithNoTests --updateSnapshot"
153153
}
154-
}
154+
}

src/renderer/utils/api/client.ts

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
import { MergeQueryBuilder } from './graphql/MergeQueryBuilder';
3737
import { createOctokitClient } from './octokit';
3838
import { performGraphQLRequest, performGraphQLRequestString } from './request';
39-
import { getNumberFromUrl } from './utils';
39+
import { getNumberFromUrl } from './utils';
4040

4141
/**
4242
* Perform a HEAD operation, used to validate that connectivity is established.
@@ -64,34 +64,33 @@ export async function listNotificationsForAuthenticatedUser(
6464
): Promise<ListNotificationsForAuthenticatedUserResponse> {
6565
const octokit = await createOctokitClient(account);
6666

67-
if (settings.fetchAllNotifications) {
68-
// Fetch all pages using Octokit's pagination
69-
return await octokit.paginate(
70-
octokit.rest.activity.listNotificationsForAuthenticatedUser,
71-
{
72-
participating: settings.participating,
73-
all: settings.fetchReadNotifications,
74-
per_page: 100,
75-
headers: {
76-
'Cache-Control': 'no-cache', // Prevent caching
77-
},
78-
},
79-
);
80-
}
81-
82-
// Single page request
83-
const response =
84-
await octokit.rest.activity.listNotificationsForAuthenticatedUser({
67+
if (settings.fetchAllNotifications) {
68+
// Fetch all pages using Octokit's pagination
69+
return await octokit.paginate(
70+
octokit.rest.activity.listNotificationsForAuthenticatedUser,
71+
{
8572
participating: settings.participating,
8673
all: settings.fetchReadNotifications,
8774
per_page: 100,
8875
headers: {
8976
'Cache-Control': 'no-cache', // Prevent caching
9077
},
91-
});
78+
},
79+
);
80+
}
9281

93-
return response.data;
94-
82+
// Single page request
83+
const response =
84+
await octokit.rest.activity.listNotificationsForAuthenticatedUser({
85+
participating: settings.participating,
86+
all: settings.fetchReadNotifications,
87+
per_page: 100,
88+
headers: {
89+
'Cache-Control': 'no-cache', // Prevent caching
90+
},
91+
});
92+
93+
return response.data;
9594
}
9695

9796
/**
@@ -106,12 +105,11 @@ export async function markNotificationThreadAsRead(
106105
): Promise<MarkNotificationThreadAsReadResponse> {
107106
const octokit = await createOctokitClient(account);
108107

109-
const response = await octokit.rest.activity.markThreadAsRead({
110-
thread_id: Number(threadId),
111-
});
108+
const response = await octokit.rest.activity.markThreadAsRead({
109+
thread_id: Number(threadId),
110+
});
112111

113-
return response.data;
114-
112+
return response.data;
115113
}
116114

117115
/**
@@ -128,12 +126,11 @@ export async function markNotificationThreadAsDone(
128126
): Promise<MarkNotificationThreadAsDoneResponse> {
129127
const octokit = await createOctokitClient(account);
130128

131-
const response = await octokit.rest.activity.markThreadAsDone({
132-
thread_id: Number(threadId),
133-
});
129+
const response = await octokit.rest.activity.markThreadAsDone({
130+
thread_id: Number(threadId),
131+
});
134132

135-
return response.data;
136-
133+
return response.data;
137134
}
138135

139136
/**
@@ -147,13 +144,12 @@ export async function ignoreNotificationThreadSubscription(
147144
): Promise<IgnoreNotificationThreadSubscriptionResponse> {
148145
const octokit = await createOctokitClient(account);
149146

150-
const response = await octokit.rest.activity.setThreadSubscription({
151-
thread_id: Number(threadId),
152-
ignored: true,
153-
});
147+
const response = await octokit.rest.activity.setThreadSubscription({
148+
thread_id: Number(threadId),
149+
ignored: true,
150+
});
154151

155-
return response.data;
156-
152+
return response.data;
157153
}
158154

159155
/**
@@ -165,8 +161,7 @@ export async function getCommit(
165161
account: Account,
166162
url: Link,
167163
): Promise<GetCommitResponse> {
168-
return followUrl<GetCommitResponse>(account, url)
169-
164+
return followUrl<GetCommitResponse>(account, url);
170165
}
171166

172167
/**
@@ -178,8 +173,7 @@ export async function getCommitComment(
178173
account: Account,
179174
url: Link,
180175
): Promise<GetCommitCommentResponse> {
181-
return followUrl<GetCommitCommentResponse>(account, url)
182-
176+
return followUrl<GetCommitCommentResponse>(account, url);
183177
}
184178

185179
/**
@@ -191,8 +185,7 @@ export async function getRelease(
191185
account: Account,
192186
url: Link,
193187
): Promise<GetReleaseResponse> {
194-
return followUrl<GetReleaseResponse>(account, url)
195-
188+
return followUrl<GetReleaseResponse>(account, url);
196189
}
197190

198191
/**
@@ -202,7 +195,7 @@ export async function getHtmlUrl(
202195
account: Account,
203196
url: Link,
204197
): Promise<GitHubHtmlUrlResponse> {
205-
return followUrl<GitHubHtmlUrlResponse>(account, url)
198+
return followUrl<GitHubHtmlUrlResponse>(account, url);
206199
}
207200

208201
/**
@@ -214,13 +207,12 @@ async function followUrl<TResult>(
214207
): Promise<TResult> {
215208
const octokit = await createOctokitClient(account);
216209

217-
// Perform a generic GET request using Octokit's request method
218-
const response = await octokit.request('GET {+url}', {
219-
url: url,
220-
});
210+
// Perform a generic GET request using Octokit's request method
211+
const response = await octokit.request('GET {+url}', {
212+
url: url,
213+
});
221214

222-
return response.data as TResult;
223-
215+
return response.data as TResult;
224216
}
225217

226218
/**
@@ -231,10 +223,9 @@ export async function fetchAuthenticatedUserDetails(
231223
): Promise<OctokitResponse<GetAuthenticatedUserResponse>> {
232224
const octokit = await createOctokitClient(account);
233225

234-
const response = await octokit.rest.users.getAuthenticated();
226+
const response = await octokit.rest.users.getAuthenticated();
235227

236-
return response;
237-
228+
return response;
238229
}
239230

240231
/**

src/renderer/utils/api/errors.test.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,23 @@ describe('renderer/utils/api/errors.ts', () => {
1717
// const mockError: Partial<RequestError> = {
1818
// code: AxiosError.ERR_NETWORK,
1919
// };
20-
2120
// const result = determineFailureType(
2221
// mockError as AxiosError<GitHubRESTError>,
2322
// );
24-
2523
// expect(result).toBe(Errors.NETWORK);
2624
// });
27-
2825
// describe('bad request errors', () => {
2926
// it('bad credentials', async () => {
3027
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
3128
// code: AxiosError.ERR_BAD_REQUEST,
3229
// status: 401,
3330
// response: createMockResponse(401, 'Bad credentials'),
3431
// };
35-
3632
// const result = determineFailureType(
3733
// mockError as AxiosError<GitHubRESTError>,
3834
// );
39-
4035
// expect(result).toBe(Errors.BAD_CREDENTIALS);
4136
// });
42-
4337
// it('missing scopes', async () => {
4438
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
4539
// code: AxiosError.ERR_BAD_REQUEST,
@@ -49,28 +43,22 @@ describe('renderer/utils/api/errors.ts', () => {
4943
// "Missing the 'notifications' scope",
5044
// ),
5145
// };
52-
5346
// const result = determineFailureType(
5447
// mockError as AxiosError<GitHubRESTError>,
5548
// );
56-
5749
// expect(result).toBe(Errors.MISSING_SCOPES);
5850
// });
59-
6051
// it('rate limited - primary', async () => {
6152
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
6253
// code: AxiosError.ERR_BAD_REQUEST,
6354
// status: 403,
6455
// response: createMockResponse(403, 'API rate limit exceeded'),
6556
// };
66-
6757
// const result = determineFailureType(
6858
// mockError as AxiosError<GitHubRESTError>,
6959
// );
70-
7160
// expect(result).toBe(Errors.RATE_LIMITED);
7261
// });
73-
7462
// it('rate limited - secondary', async () => {
7563
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
7664
// code: AxiosError.ERR_BAD_REQUEST,
@@ -80,50 +68,39 @@ describe('renderer/utils/api/errors.ts', () => {
8068
// 'You have exceeded a secondary rate limit',
8169
// ),
8270
// };
83-
8471
// const result = determineFailureType(
8572
// mockError as AxiosError<GitHubRESTError>,
8673
// );
87-
8874
// expect(result).toBe(Errors.RATE_LIMITED);
8975
// });
90-
9176
// it('unhandled bad request error', async () => {
9277
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
9378
// code: AxiosError.ERR_BAD_REQUEST,
9479
// status: 400,
9580
// response: createMockResponse(403, 'Oops! Something went wrong.'),
9681
// };
97-
9882
// const result = determineFailureType(
9983
// mockError as AxiosError<GitHubRESTError>,
10084
// );
101-
10285
// expect(result).toBe(Errors.UNKNOWN);
10386
// });
10487
// });
105-
10688
// it('bad credentials - safe storage', async () => {
10789
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
10890
// message: `Error invoking remote method '${EVENTS.SAFE_STORAGE_DECRYPT}': Error: Error while decrypting the ciphertext provided to safeStorage.decryptString. Ciphertext does not appear to be encrypted.`,
10991
// };
110-
11192
// const result = determineFailureType(
11293
// mockError as AxiosError<GitHubRESTError>,
11394
// );
114-
11595
// expect(result).toBe(Errors.BAD_CREDENTIALS);
11696
// });
117-
11897
// it('unknown error', async () => {
11998
// const mockError: Partial<AxiosError<GitHubRESTError>> = {
12099
// code: 'anything',
121100
// };
122-
123101
// const result = determineFailureType(
124102
// mockError as AxiosError<GitHubRESTError>,
125103
// );
126-
127104
// expect(result).toBe(Errors.UNKNOWN);
128105
// });
129106
// });

src/renderer/utils/api/errors.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ import { rendererLogError } from '../logger';
1313
* @param err The error
1414
* @returns The Gitify error type
1515
*/
16-
export function determineFailureType(
17-
err: RequestError,
18-
): GitifyError {
16+
export function determineFailureType(err: RequestError): GitifyError {
1917
// Handle Octokit RequestError
2018
if (err instanceof RequestError) {
2119
const status = err.status;
@@ -44,7 +42,6 @@ export function determineFailureType(
4442
}
4543
}
4644

47-
4845
return Errors.UNKNOWN;
4946
}
5047

src/renderer/utils/api/octokit.test.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { mockGitHubAppAccount, mockGitHubCloudAccount, mockGitHubEnterpriseServerAccount } from '../../__mocks__/account-mocks';
1+
import {
2+
mockGitHubAppAccount,
3+
mockGitHubCloudAccount,
4+
mockGitHubEnterpriseServerAccount,
5+
} from '../../__mocks__/account-mocks';
26
import { mockToken } from '../../__mocks__/state-mocks';
37

4-
58
import * as comms from '../comms';
69
import { clearOctokitClientCache, createOctokitClient } from './octokit';
710
import * as utils from './utils';
@@ -27,8 +30,7 @@ describe('renderer/utils/api/octokit.ts', () => {
2730
new URL('https://api.github.com/'),
2831
);
2932

30-
const octokit = await createOctokitClient(mockGitHubCloudAccount
31-
);
33+
const octokit = await createOctokitClient(mockGitHubCloudAccount);
3234

3335
expect(getGitHubAPIBaseUrlSpy).toHaveBeenCalledWith('github.com');
3436
expect(octokit).toBeDefined();
@@ -41,7 +43,8 @@ describe('renderer/utils/api/octokit.ts', () => {
4143
new URL('https://github.gitify.io/api/v3/'),
4244
);
4345

44-
const octokit = await createOctokitClient(mockGitHubEnterpriseServerAccount
46+
const octokit = await createOctokitClient(
47+
mockGitHubEnterpriseServerAccount,
4548
);
4649

4750
expect(getGitHubAPIBaseUrlSpy).toHaveBeenCalledWith('github.gitify.io');
@@ -55,11 +58,9 @@ describe('renderer/utils/api/octokit.ts', () => {
5558
new URL('https://api.github.com/'),
5659
);
5760

58-
const octokit1 = await createOctokitClient(mockGitHubCloudAccount
59-
);
61+
const octokit1 = await createOctokitClient(mockGitHubCloudAccount);
6062

61-
const octokit2 = await createOctokitClient(mockGitHubCloudAccount
62-
);
63+
const octokit2 = await createOctokitClient(mockGitHubCloudAccount);
6364

6465
// Should return the same instance
6566
expect(octokit1).toBe(octokit2);
@@ -77,11 +78,9 @@ describe('renderer/utils/api/octokit.ts', () => {
7778
new URL('https://api.github.com/'),
7879
);
7980

80-
const octokit1 = await createOctokitClient(mockGitHubAppAccount
81-
);
81+
const octokit1 = await createOctokitClient(mockGitHubAppAccount);
8282

83-
const octokit2 = await createOctokitClient(mockGitHubCloudAccount
84-
);
83+
const octokit2 = await createOctokitClient(mockGitHubCloudAccount);
8584

8685
// Should be different instances for different tokens
8786
expect(octokit1).not.toBe(octokit2);

0 commit comments

Comments
 (0)