github-issue-tower-defence-management 1.35.1 → 1.36.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/bin/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.js +1 -27
  3. package/bin/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.js.map +1 -1
  4. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +1 -27
  5. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  6. package/bin/adapter/repositories/BaseGitHubRepository.js +7 -9
  7. package/bin/adapter/repositories/BaseGitHubRepository.js.map +1 -1
  8. package/bin/adapter/repositories/CheerioProjectRepository.js +11 -11
  9. package/bin/adapter/repositories/CheerioProjectRepository.js.map +1 -1
  10. package/bin/adapter/repositories/FetchWebhookRepository.js +5 -1
  11. package/bin/adapter/repositories/FetchWebhookRepository.js.map +1 -1
  12. package/bin/adapter/repositories/GraphqlProjectRepository.js +14 -16
  13. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
  14. package/bin/adapter/repositories/KySlackRepository.js +212 -0
  15. package/bin/adapter/repositories/KySlackRepository.js.map +1 -0
  16. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js +11 -13
  17. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js.map +1 -1
  18. package/bin/adapter/repositories/issue/CheerioIssueRepository.js +2 -3
  19. package/bin/adapter/repositories/issue/CheerioIssueRepository.js.map +1 -1
  20. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +47 -63
  21. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -1
  22. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js +12 -8
  23. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js.map +1 -1
  24. package/bin/adapter/repositories/issue/RestIssueRepository.js +36 -69
  25. package/bin/adapter/repositories/issue/RestIssueRepository.js.map +1 -1
  26. package/jest.config.js +2 -1
  27. package/package.json +2 -3
  28. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.test.ts +0 -78
  29. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.ts +1 -33
  30. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +0 -78
  31. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +1 -33
  32. package/src/adapter/repositories/BaseGitHubRepository.test.ts +141 -0
  33. package/src/adapter/repositories/BaseGitHubRepository.ts +10 -10
  34. package/src/adapter/repositories/CheerioProjectRepository.ts +19 -23
  35. package/src/adapter/repositories/FetchWebhookRepository.ts +2 -1
  36. package/src/adapter/repositories/GraphqlProjectRepository.ts +63 -69
  37. package/src/adapter/repositories/{AxiosSlackRepository.test.ts → KySlackRepository.test.ts} +4 -4
  38. package/src/adapter/repositories/KySlackRepository.ts +297 -0
  39. package/src/adapter/repositories/issue/ApiV3IssueRepository.ts +31 -33
  40. package/src/adapter/repositories/issue/CheerioIssueRepository.test.ts +3 -3
  41. package/src/adapter/repositories/issue/CheerioIssueRepository.ts +2 -3
  42. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +30 -22
  43. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +178 -191
  44. package/src/adapter/repositories/issue/InternalGraphqlIssueRepository.ts +12 -8
  45. package/src/adapter/repositories/issue/RestIssueRepository.ts +51 -91
  46. package/types/adapter/entry-points/function/getStoryObjectMap.d.ts +1 -1
  47. package/types/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.d.ts +1 -1
  48. package/types/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.d.ts.map +1 -1
  49. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts +1 -1
  50. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  51. package/types/adapter/repositories/BaseGitHubRepository.d.ts +1 -1
  52. package/types/adapter/repositories/BaseGitHubRepository.d.ts.map +1 -1
  53. package/types/adapter/repositories/CheerioProjectRepository.d.ts.map +1 -1
  54. package/types/adapter/repositories/FetchWebhookRepository.d.ts.map +1 -1
  55. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
  56. package/types/adapter/repositories/{AxiosSlackRepository.d.ts → KySlackRepository.d.ts} +3 -2
  57. package/types/adapter/repositories/KySlackRepository.d.ts.map +1 -0
  58. package/types/adapter/repositories/issue/ApiV3IssueRepository.d.ts.map +1 -1
  59. package/types/adapter/repositories/issue/CheerioIssueRepository.d.ts.map +1 -1
  60. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -1
  61. package/types/adapter/repositories/issue/InternalGraphqlIssueRepository.d.ts.map +1 -1
  62. package/types/adapter/repositories/issue/RestIssueRepository.d.ts.map +1 -1
  63. package/types/index.d.ts +1 -1
  64. package/bin/adapter/repositories/AxiosSlackRepository.js +0 -188
  65. package/bin/adapter/repositories/AxiosSlackRepository.js.map +0 -1
  66. package/src/adapter/repositories/AxiosSlackRepository.ts +0 -218
  67. package/types/adapter/repositories/AxiosSlackRepository.d.ts.map +0 -1
@@ -1,24 +1,32 @@
1
- import axios, { AxiosHeaders, AxiosResponse } from 'axios';
1
+ const mockPost = jest.fn();
2
+
3
+ jest.mock('ky', () => ({
4
+ default: {
5
+ post: mockPost,
6
+ get: jest.fn(),
7
+ put: jest.fn(),
8
+ patch: jest.fn(),
9
+ delete: jest.fn(),
10
+ extend: jest.fn(),
11
+ create: jest.fn(),
12
+ stop: jest.fn(),
13
+ },
14
+ __esModule: true,
15
+ }));
16
+
2
17
  import {
3
18
  GraphqlProjectItemRepository,
4
19
  PAGINATION_DELAY_MS,
5
20
  } from './GraphqlProjectItemRepository';
6
21
  import { LocalStorageRepository } from '../LocalStorageRepository';
7
22
 
8
- jest.mock('axios');
9
- const mockAxios = jest.mocked(axios);
10
-
11
- const toAxiosResponse = <T>(data: T): AxiosResponse<T> => ({
12
- data,
13
- status: 200,
14
- statusText: 'OK',
15
- headers: {},
16
- config: { headers: new AxiosHeaders() },
23
+ const mockJsonResponse = <T>(data: T) => ({
24
+ json: jest.fn().mockResolvedValue(data),
17
25
  });
18
26
 
19
27
  describe('GraphqlProjectItemRepository', () => {
20
28
  const makePageResponse = (hasNextPage: boolean, endCursor: string) =>
21
- toAxiosResponse({
29
+ mockJsonResponse({
22
30
  data: {
23
31
  node: {
24
32
  items: {
@@ -64,7 +72,7 @@ describe('GraphqlProjectItemRepository', () => {
64
72
 
65
73
  afterEach(() => {
66
74
  jest.useRealTimers();
67
- mockAxios.mockClear();
75
+ mockPost.mockClear();
68
76
  });
69
77
 
70
78
  it('should sleep between paginated requests to avoid 403', async () => {
@@ -76,15 +84,15 @@ describe('GraphqlProjectItemRepository', () => {
76
84
  );
77
85
 
78
86
  const setTimeoutSpy = jest.spyOn(global, 'setTimeout');
79
- mockAxios
80
- .mockResolvedValueOnce(makePageResponse(true, 'cursor-1'))
81
- .mockResolvedValueOnce(makePageResponse(false, 'cursor-2'));
87
+ mockPost
88
+ .mockReturnValueOnce(makePageResponse(true, 'cursor-1'))
89
+ .mockReturnValueOnce(makePageResponse(false, 'cursor-2'));
82
90
 
83
91
  const resultPromise = repository.fetchProjectItems('test-project-id');
84
92
  await jest.advanceTimersByTimeAsync(PAGINATION_DELAY_MS);
85
93
  const result = await resultPromise;
86
94
 
87
- expect(mockAxios).toHaveBeenCalledTimes(2);
95
+ expect(mockPost).toHaveBeenCalledTimes(2);
88
96
  expect(result).toHaveLength(2);
89
97
  expect(setTimeoutSpy).toHaveBeenCalledWith(
90
98
  expect.any(Function),
@@ -102,11 +110,11 @@ describe('GraphqlProjectItemRepository', () => {
102
110
  );
103
111
 
104
112
  const setTimeoutSpy = jest.spyOn(global, 'setTimeout');
105
- mockAxios.mockResolvedValueOnce(makePageResponse(false, 'cursor-1'));
113
+ mockPost.mockReturnValueOnce(makePageResponse(false, 'cursor-1'));
106
114
 
107
115
  const result = await repository.fetchProjectItems('test-project-id');
108
116
 
109
- expect(mockAxios).toHaveBeenCalledTimes(1);
117
+ expect(mockPost).toHaveBeenCalledTimes(1);
110
118
  expect(result).toHaveLength(1);
111
119
  expect(setTimeoutSpy).not.toHaveBeenCalledWith(
112
120
  expect.any(Function),
@@ -118,7 +126,7 @@ describe('GraphqlProjectItemRepository', () => {
118
126
 
119
127
  describe('getProjectItemFields', () => {
120
128
  afterEach(() => {
121
- mockAxios.mockClear();
129
+ mockPost.mockClear();
122
130
  });
123
131
 
124
132
  it('should return project item fields', async () => {
@@ -129,8 +137,8 @@ describe('GraphqlProjectItemRepository', () => {
129
137
  'dummy-token',
130
138
  );
131
139
 
132
- mockAxios.mockResolvedValueOnce(
133
- toAxiosResponse({
140
+ mockPost.mockReturnValueOnce(
141
+ mockJsonResponse({
134
142
  data: {
135
143
  repository: {
136
144
  issue: {
@@ -163,7 +171,7 @@ describe('GraphqlProjectItemRepository', () => {
163
171
 
164
172
  const result = await repository.getProjectItemFields('owner', 'repo', 1);
165
173
 
166
- expect(mockAxios).toHaveBeenCalledTimes(1);
174
+ expect(mockPost).toHaveBeenCalledTimes(1);
167
175
  expect(result).toEqual([
168
176
  {
169
177
  fieldName: 'NextActionDate',
@@ -1,4 +1,4 @@
1
- import axios from 'axios';
1
+ import ky from 'ky';
2
2
  import { BaseGitHubRepository } from '../BaseGitHubRepository';
3
3
  import { Project } from '../../../domain/entities/Project';
4
4
  import { Issue } from '../../../domain/entities/Issue';
@@ -50,33 +50,32 @@ export class GraphqlProjectItemRepository extends BaseGitHubRepository {
50
50
  };
51
51
 
52
52
  try {
53
- const response = await axios<{
54
- data: {
55
- repository: {
56
- issue: {
57
- projectItems: {
58
- nodes: {
59
- id: string;
60
- project: { id: string };
61
- }[];
53
+ const response = await ky
54
+ .post('https://api.github.com/graphql', {
55
+ json: graphqlQuery,
56
+ headers: {
57
+ Authorization: `Bearer ${this.ghToken}`,
58
+ },
59
+ })
60
+ .json<{
61
+ data: {
62
+ repository: {
63
+ issue: {
64
+ projectItems: {
65
+ nodes: {
66
+ id: string;
67
+ project: { id: string };
68
+ }[];
69
+ };
62
70
  };
63
71
  };
64
72
  };
65
- };
66
- }>({
67
- url: 'https://api.github.com/graphql',
68
- method: 'post',
69
- headers: {
70
- Authorization: `Bearer ${this.ghToken}`,
71
- 'Content-Type': 'application/json',
72
- },
73
- data: JSON.stringify(graphqlQuery),
74
- });
73
+ }>();
75
74
 
76
75
  const projectItems: {
77
76
  id: string;
78
77
  project: { id: string };
79
- }[] = response.data.data.repository.issue.projectItems.nodes;
78
+ }[] = response.data.repository.issue.projectItems.nodes;
80
79
  const projectItemId = projectItems.find(
81
80
  (item) => item.project.id === projectId,
82
81
  )?.id;
@@ -240,56 +239,55 @@ query GetProjectItems($projectId: ID!, $after: String) {
240
239
  after: after,
241
240
  },
242
241
  };
243
- const response = await axios<{
244
- data: {
245
- node: {
246
- items: {
247
- totalCount: number;
248
- pageInfo: {
249
- endCursor: string;
250
- startCursor: string;
251
- hasNextPage: boolean;
252
- };
253
- nodes: {
254
- id: string;
255
- fieldValues: {
256
- nodes: {
257
- text: string;
258
- number: number;
259
- date: string;
260
- field: {
261
- name: string;
262
- };
263
- }[];
264
- };
265
- content: {
266
- repository: { nameWithOwner: string };
267
- number: number;
268
- title: string;
269
- state: string;
270
- url: string;
271
- body: string;
272
- createdAt: string;
273
- labels: { nodes: { name: string }[] };
274
- assignees: { nodes: { login: string }[] };
242
+ const response = await ky
243
+ .post('https://api.github.com/graphql', {
244
+ json: graphqlQuery,
245
+ headers: {
246
+ Authorization: `Bearer ${this.ghToken}`,
247
+ },
248
+ })
249
+ .json<{
250
+ data: {
251
+ node: {
252
+ items: {
253
+ totalCount: number;
254
+ pageInfo: {
255
+ endCursor: string;
256
+ startCursor: string;
257
+ hasNextPage: boolean;
275
258
  };
276
- }[];
259
+ nodes: {
260
+ id: string;
261
+ fieldValues: {
262
+ nodes: {
263
+ text: string;
264
+ number: number;
265
+ date: string;
266
+ field: {
267
+ name: string;
268
+ };
269
+ }[];
270
+ };
271
+ content: {
272
+ repository: { nameWithOwner: string };
273
+ number: number;
274
+ title: string;
275
+ state: string;
276
+ url: string;
277
+ body: string;
278
+ createdAt: string;
279
+ labels: { nodes: { name: string }[] };
280
+ assignees: { nodes: { login: string }[] };
281
+ };
282
+ }[];
283
+ };
277
284
  };
278
285
  };
279
- };
280
- }>({
281
- url: 'https://api.github.com/graphql',
282
- method: 'post',
283
- headers: {
284
- Authorization: `Bearer ${this.ghToken}`,
285
- 'Content-Type': 'application/json',
286
- },
287
- data: JSON.stringify(graphqlQuery),
288
- });
289
- if (!response.data.data) {
286
+ }>();
287
+ if (!response.data) {
290
288
  throw new Error('No data returned from GitHub API');
291
289
  }
292
- return response.data.data;
290
+ return response.data;
293
291
  };
294
292
  const issues: ProjectItem[] = [];
295
293
  let after: string | null = null;
@@ -458,40 +456,39 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
458
456
  issueNumber: issueNumber,
459
457
  },
460
458
  };
461
- const response = await axios<{
462
- data: {
463
- repository: {
464
- issue: {
465
- projectItems: {
466
- nodes: {
467
- id: string;
468
- fieldValues: {
469
- nodes: {
470
- __typename: string;
471
- field: { name: string };
472
- date: string;
473
- name: string;
474
- text: string;
475
- repository: { name: string };
476
- user: { login: string };
477
- }[];
478
- };
479
- }[];
459
+ const response = await ky
460
+ .post('https://api.github.com/graphql', {
461
+ json: graphqlQuery,
462
+ headers: {
463
+ Authorization: `Bearer ${this.ghToken}`,
464
+ },
465
+ })
466
+ .json<{
467
+ data: {
468
+ repository: {
469
+ issue: {
470
+ projectItems: {
471
+ nodes: {
472
+ id: string;
473
+ fieldValues: {
474
+ nodes: {
475
+ __typename: string;
476
+ field: { name: string };
477
+ date: string;
478
+ name: string;
479
+ text: string;
480
+ repository: { name: string };
481
+ user: { login: string };
482
+ }[];
483
+ };
484
+ }[];
485
+ };
480
486
  };
481
487
  };
482
488
  };
483
- };
484
- }>({
485
- url: 'https://api.github.com/graphql',
486
- method: 'post',
487
- headers: {
488
- Authorization: `Bearer ${this.ghToken}`,
489
- 'Content-Type': 'application/json',
490
- },
491
- data: JSON.stringify(graphqlQuery),
492
- });
489
+ }>();
493
490
 
494
- const data = response.data.data;
491
+ const data = response.data;
495
492
  const issueFields: {
496
493
  fieldName: string;
497
494
  fieldValue: string;
@@ -615,48 +612,47 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
615
612
  number: issueNumber,
616
613
  },
617
614
  };
618
- const response = await axios<{
619
- data: {
620
- repository: {
621
- issue: {
622
- number: number;
623
- title: string;
624
- state: string;
625
- url: string;
626
- body: string;
627
- createdAt: string;
628
- labels: { nodes: { name: string }[] };
629
- assignees: { nodes: { login: string }[] };
630
- repository: { nameWithOwner: string };
631
- projectItems: {
632
- nodes: {
633
- id: string;
634
- fieldValues: {
635
- nodes: {
636
- text: string;
637
- number: number;
638
- date: string;
639
- name: string;
640
- field: {
615
+ const response = await ky
616
+ .post('https://api.github.com/graphql', {
617
+ json: graphqlQuery,
618
+ headers: {
619
+ Authorization: `Bearer ${this.ghToken}`,
620
+ },
621
+ })
622
+ .json<{
623
+ data: {
624
+ repository: {
625
+ issue: {
626
+ number: number;
627
+ title: string;
628
+ state: string;
629
+ url: string;
630
+ body: string;
631
+ createdAt: string;
632
+ labels: { nodes: { name: string }[] };
633
+ assignees: { nodes: { login: string }[] };
634
+ repository: { nameWithOwner: string };
635
+ projectItems: {
636
+ nodes: {
637
+ id: string;
638
+ fieldValues: {
639
+ nodes: {
640
+ text: string;
641
+ number: number;
642
+ date: string;
641
643
  name: string;
642
- };
643
- }[];
644
- };
645
- }[];
644
+ field: {
645
+ name: string;
646
+ };
647
+ }[];
648
+ };
649
+ }[];
650
+ };
646
651
  };
647
652
  };
648
653
  };
649
- };
650
- }>({
651
- url: 'https://api.github.com/graphql',
652
- method: 'post',
653
- headers: {
654
- Authorization: `Bearer ${this.ghToken}`,
655
- 'Content-Type': 'application/json',
656
- },
657
- data: JSON.stringify(graphqlQuery),
658
- });
659
- const data = response.data.data;
654
+ }>();
655
+ const data = response.data;
660
656
  if (!data.repository.issue) {
661
657
  return null;
662
658
  }
@@ -738,26 +734,23 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
738
734
  }`,
739
735
  };
740
736
 
741
- const res = await axios<{
742
- data: {
743
- updateProjectV2ItemFieldValue: {
744
- clientMutationId: string;
737
+ const res = await ky
738
+ .post('https://api.github.com/graphql', {
739
+ json: graphqlQuery,
740
+ headers: {
741
+ Authorization: `Bearer ${this.ghToken}`,
742
+ },
743
+ })
744
+ .json<{
745
+ data: {
746
+ updateProjectV2ItemFieldValue: {
747
+ clientMutationId: string;
748
+ };
745
749
  };
746
- };
747
- errors: { message: string }[];
748
- }>({
749
- url: 'https://api.github.com/graphql',
750
- method: 'post',
751
- headers: {
752
- Authorization: `Bearer ${this.ghToken}`,
753
- 'Content-Type': 'application/json',
754
- },
755
- data: JSON.stringify(graphqlQuery),
756
- });
757
- if (res.status !== 200) {
758
- throw new Error('Failed to update project field');
759
- } else if (res.data.errors) {
760
- throw new Error(res.data.errors.map((e) => e.message).join('\n'));
750
+ errors: { message: string }[];
751
+ }>();
752
+ if (res.errors) {
753
+ throw new Error(res.errors.map((e) => e.message).join('\n'));
761
754
  }
762
755
  };
763
756
 
@@ -778,26 +771,23 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
778
771
  }`,
779
772
  };
780
773
 
781
- const res = await axios<{
782
- data: {
783
- clearProjectV2ItemFieldValue: {
784
- clientMutationId: string;
774
+ const res = await ky
775
+ .post('https://api.github.com/graphql', {
776
+ json: graphqlQuery,
777
+ headers: {
778
+ Authorization: `Bearer ${this.ghToken}`,
779
+ },
780
+ })
781
+ .json<{
782
+ data: {
783
+ clearProjectV2ItemFieldValue: {
784
+ clientMutationId: string;
785
+ };
785
786
  };
786
- };
787
- errors: { message: string }[];
788
- }>({
789
- url: 'https://api.github.com/graphql',
790
- method: 'post',
791
- headers: {
792
- Authorization: `Bearer ${this.ghToken}`,
793
- 'Content-Type': 'application/json',
794
- },
795
- data: JSON.stringify(graphqlQuery),
796
- });
797
- if (res.status !== 200) {
798
- throw new Error('Failed to clear project field');
799
- } else if (res.data.errors) {
800
- throw new Error(res.data.errors.map((e) => e.message).join('\n'));
787
+ errors: { message: string }[];
788
+ }>();
789
+ if (res.errors) {
790
+ throw new Error(res.errors.map((e) => e.message).join('\n'));
801
791
  }
802
792
  };
803
793
  updateProjectTextField = async (
@@ -825,27 +815,24 @@ query GetProjectFields($owner: String!, $repository: String!, $issueNumber: Int!
825
815
  },
826
816
  };
827
817
 
828
- const res = await axios<{
829
- data: {
830
- deleteProjectV2Item: {
831
- clientMutationId: string;
818
+ const res = await ky
819
+ .post('https://api.github.com/graphql', {
820
+ json: graphqlQuery,
821
+ headers: {
822
+ Authorization: `Bearer ${this.ghToken}`,
823
+ },
824
+ })
825
+ .json<{
826
+ data: {
827
+ deleteProjectV2Item: {
828
+ clientMutationId: string;
829
+ };
832
830
  };
833
- };
834
- errors?: { message: string }[];
835
- }>({
836
- url: 'https://api.github.com/graphql',
837
- method: 'post',
838
- headers: {
839
- Authorization: `Bearer ${this.ghToken}`,
840
- 'Content-Type': 'application/json',
841
- },
842
- data: JSON.stringify(graphqlQuery),
843
- });
831
+ errors?: { message: string }[];
832
+ }>();
844
833
 
845
- if (res.status !== 200) {
846
- throw new Error('Failed to remove item from project');
847
- } else if (res.data.errors) {
848
- throw new Error(res.data.errors.map((e) => e.message).join('\n'));
834
+ if (res.errors) {
835
+ throw new Error(res.errors.map((e) => e.message).join('\n'));
849
836
  }
850
837
  };
851
838
 
@@ -1,4 +1,4 @@
1
- import axios from 'axios';
1
+ import ky from 'ky';
2
2
  import { BaseGitHubRepository } from '../BaseGitHubRepository';
3
3
  import typia from 'typia';
4
4
  import { Issue, IssueStatusTimeline } from './CheerioIssueRepository';
@@ -419,23 +419,27 @@ export class InternalGraphqlIssueRepository extends BaseGitHubRepository {
419
419
  for (let i = 0; i < maxRetries; i++) {
420
420
  try {
421
421
  console.log(url);
422
- const response = await axios.get<GraphqlResponse>(url, {
422
+ const kyResponse = await ky.get(url, {
423
423
  headers: headers,
424
- withCredentials: true,
424
+ throwHttpErrors: false,
425
425
  });
426
- if (!response.data?.data?.node?.frontTimelineItems) {
426
+ if (!kyResponse.ok) {
427
+ throw new Error(`HTTP error ${kyResponse.status}`);
428
+ }
429
+ const rawResponse = await kyResponse.json<GraphqlResponse>();
430
+ if (!rawResponse?.data?.node?.frontTimelineItems) {
427
431
  throw new Error(
428
432
  `No frontTimelineItems found. URL: ${issueUrl}, Response: ${JSON.stringify(
429
- response.data,
433
+ rawResponse,
430
434
  )}`,
431
435
  );
432
436
  }
433
437
  await new Promise((resolve) => setTimeout(resolve, 2000));
434
- return response.data.data.node.frontTimelineItems;
438
+ return rawResponse.data.node.frontTimelineItems;
435
439
  } catch (e) {
436
440
  const statusCode =
437
- axios.isAxiosError(e) && e.response?.status !== undefined
438
- ? e.response.status
441
+ e instanceof Error && e.message.startsWith('HTTP error ')
442
+ ? parseInt(e.message.replace('HTTP error ', ''), 10)
439
443
  : null;
440
444
  const isRetryableError =
441
445
  statusCode !== null && [500, 502, 503, 504].includes(statusCode);