github-issue-tower-defence-management 1.45.0 → 1.47.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 (42) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +64 -0
  3. package/bin/adapter/entry-points/cli/index.js +0 -52
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.js +0 -2
  6. package/bin/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.js.map +1 -1
  7. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +20 -15
  8. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  9. package/bin/adapter/entry-points/handlers/situationFileWriter.js +98 -0
  10. package/bin/adapter/entry-points/handlers/situationFileWriter.js.map +1 -0
  11. package/bin/adapter/repositories/BaseGitHubRepository.js +5 -22
  12. package/bin/adapter/repositories/BaseGitHubRepository.js.map +1 -1
  13. package/bin/adapter/repositories/GraphqlProjectRepository.js +40 -0
  14. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -1
  15. package/package.json +1 -2
  16. package/src/adapter/entry-points/cli/index.test.ts +0 -49
  17. package/src/adapter/entry-points/cli/index.ts +2 -21
  18. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.test.ts +0 -6
  19. package/src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.ts +0 -2
  20. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +23 -51
  21. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +27 -18
  22. package/src/adapter/entry-points/handlers/situationFileWriter.test.ts +417 -0
  23. package/src/adapter/entry-points/handlers/situationFileWriter.ts +168 -0
  24. package/src/adapter/repositories/BaseGitHubRepository.test.ts +3 -48
  25. package/src/adapter/repositories/BaseGitHubRepository.ts +5 -33
  26. package/src/adapter/repositories/GraphqlProjectRepository.test.ts +72 -0
  27. package/src/adapter/repositories/GraphqlProjectRepository.ts +57 -1
  28. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  29. package/types/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.d.ts.map +1 -1
  30. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  31. package/types/adapter/entry-points/handlers/situationFileWriter.d.ts +30 -0
  32. package/types/adapter/entry-points/handlers/situationFileWriter.d.ts.map +1 -0
  33. package/types/adapter/repositories/BaseGitHubRepository.d.ts +0 -1
  34. package/types/adapter/repositories/BaseGitHubRepository.d.ts.map +1 -1
  35. package/types/adapter/repositories/GraphqlProjectRepository.d.ts +5 -2
  36. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -1
  37. package/bin/adapter/repositories/CheerioProjectRepository.js +0 -45
  38. package/bin/adapter/repositories/CheerioProjectRepository.js.map +0 -1
  39. package/src/adapter/repositories/CheerioProjectRepository.test.ts +0 -122
  40. package/src/adapter/repositories/CheerioProjectRepository.ts +0 -65
  41. package/types/adapter/repositories/CheerioProjectRepository.d.ts +0 -17
  42. package/types/adapter/repositories/CheerioProjectRepository.d.ts.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import { promises as fsPromises } from 'fs';
2
2
  import { serialize } from 'cookie';
3
- import { getCookieContent } from 'gh-cookie';
4
3
  import fs from 'fs';
5
4
  import { LocalStorageRepository } from './LocalStorageRepository';
6
5
  import ky from 'ky';
@@ -18,7 +17,6 @@ interface Cookie {
18
17
 
19
18
  export class BaseGitHubRepository {
20
19
  cookie: string | null;
21
- protected cookieRefreshRetryDelayMs = 3000;
22
20
  constructor(
23
21
  readonly localStorageRepository: LocalStorageRepository,
24
22
  readonly jsonFilePath: string = './tmp/github.com.cookies.json',
@@ -82,19 +80,7 @@ export class BaseGitHubRepository {
82
80
  };
83
81
  protected createCookieStringFromFile = async (): Promise<string> => {
84
82
  if (!fs.existsSync(this.jsonFilePath)) {
85
- if (
86
- !this.ghUserName ||
87
- !this.ghUserPassword ||
88
- !this.ghAuthenticatorKey
89
- ) {
90
- throw new Error('No cookie file and no credentials provided');
91
- }
92
- const cookie = await getCookieContent(
93
- this.ghUserName,
94
- this.ghUserPassword,
95
- this.ghAuthenticatorKey,
96
- );
97
- this.localStorageRepository.write(this.jsonFilePath, cookie);
83
+ throw new Error('No cookie file found');
98
84
  }
99
85
  const data = await fsPromises.readFile(this.jsonFilePath, {
100
86
  encoding: 'utf-8',
@@ -169,24 +155,10 @@ export class BaseGitHubRepository {
169
155
  );
170
156
  }
171
157
  const profileUrl = `https://github.com/${this.ghUserName}`;
172
- const maxAttempts = 3;
173
-
174
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
175
- if (attempt > 0) {
176
- await new Promise<void>((resolve) =>
177
- setTimeout(resolve, this.cookieRefreshRetryDelayMs),
178
- );
179
- this.localStorageRepository.remove(this.jsonFilePath);
180
- this.cookie = null;
181
- }
182
- const headers = await this.createHeader();
183
- const html = await ky.get(profileUrl, { headers }).text();
184
- if (
185
- html.includes(`meta name="user-login" content="${this.ghUserName}"`)
186
- ) {
187
- return;
188
- }
158
+ const headers = await this.createHeader();
159
+ const html = await ky.get(profileUrl, { headers }).text();
160
+ if (!html.includes(`meta name="user-login" content="${this.ghUserName}"`)) {
161
+ throw new Error('Failed to refresh cookie');
189
162
  }
190
- throw new Error('Failed to refresh cookie');
191
163
  };
192
164
  }
@@ -1,5 +1,6 @@
1
1
  import { GraphqlProjectRepository } from './GraphqlProjectRepository';
2
2
  import { LocalStorageRepository } from './LocalStorageRepository';
3
+ import { FieldOption, Project } from '../../domain/entities/Project';
3
4
 
4
5
  describe('GraphqlProjectRepository', () => {
5
6
  const localStorageRepository = new LocalStorageRepository();
@@ -29,6 +30,77 @@ describe('GraphqlProjectRepository', () => {
29
30
  });
30
31
  });
31
32
 
33
+ describe('updateStoryList', () => {
34
+ const storyFieldId = 'PVTSSF_lAHOAGJHa84AFhgFzg1oBms';
35
+ const existingStories: FieldOption[] = [
36
+ { id: 'af410dae', name: 'story1', color: 'GRAY', description: '' },
37
+ {
38
+ id: '696ccdef',
39
+ name: 'Workflow Management',
40
+ color: 'GRAY',
41
+ description: '',
42
+ },
43
+ { id: '4fa21881', name: 'test', color: 'GRAY', description: '' },
44
+ ];
45
+ const testProject: Project = {
46
+ id: projectId,
47
+ url: projectUrl,
48
+ databaseId: 1447941,
49
+ name: 'V2 project on owner for testing',
50
+ completionDate50PercentConfidence: null,
51
+ dependedIssueUrlSeparatedByComma: null,
52
+ nextActionDate: {
53
+ fieldId: 'PVTF_lAHOAGJHa84AFhgFzgVlnK4',
54
+ name: 'NextActionDate',
55
+ },
56
+ nextActionHour: null,
57
+ remainingEstimationMinutes: null,
58
+ status: {
59
+ fieldId: 'PVTSSF_lAHOAGJHa84AFhgFzgDLt0c',
60
+ name: 'Status',
61
+ statuses: [],
62
+ },
63
+ story: {
64
+ fieldId: storyFieldId,
65
+ databaseId: 224921195,
66
+ name: 'Story',
67
+ stories: existingStories,
68
+ workflowManagementStory: {
69
+ id: '696ccdef',
70
+ name: 'Workflow Management',
71
+ },
72
+ },
73
+ };
74
+
75
+ it('should add a new option while preserving all existing options', async () => {
76
+ const newOption: Omit<FieldOption, 'id'> & { id: null } = {
77
+ id: null,
78
+ name: 'test-story-from-graphql-unit-test',
79
+ color: 'BLUE',
80
+ description: 'created by graphql unit test',
81
+ };
82
+ const inputList: Parameters<typeof repository.updateStoryList>['1'] = [
83
+ ...existingStories,
84
+ newOption,
85
+ ];
86
+
87
+ const result = await repository.updateStoryList(testProject, inputList);
88
+
89
+ expect(result).toHaveLength(existingStories.length + 1);
90
+ existingStories.forEach((existing) => {
91
+ const found = result.find((r) => r.id === existing.id);
92
+ expect(found).toEqual(existing);
93
+ });
94
+ const added = result.find((r) => r.name === newOption.name);
95
+ expect(added).toBeDefined();
96
+ expect(added?.color).toEqual(newOption.color);
97
+ expect(added?.description).toEqual(newOption.description);
98
+ expect(added?.id).toBeDefined();
99
+
100
+ await repository.updateStoryList(testProject, existingStories);
101
+ });
102
+ });
103
+
32
104
  describe('getProject', () => {
33
105
  it('should retrieve project details', async () => {
34
106
  const project = await repository.getProject(projectId);
@@ -7,7 +7,10 @@ import { normalizeFieldName } from './utils';
7
7
  export class GraphqlProjectRepository
8
8
  extends BaseGitHubRepository
9
9
  implements
10
- Pick<ProjectRepository, 'getProject' | 'findProjectIdByUrl' | 'getByUrl'>
10
+ Pick<
11
+ ProjectRepository,
12
+ 'getProject' | 'findProjectIdByUrl' | 'getByUrl' | 'updateStoryList'
13
+ >
11
14
  {
12
15
  extractProjectFromUrl = (
13
16
  projectUrl: string,
@@ -306,4 +309,57 @@ export class GraphqlProjectRepository
306
309
  }
307
310
  return project;
308
311
  };
312
+ updateStoryList = async (
313
+ project: Project,
314
+ newStoryList: (Omit<FieldOption, 'id'> & {
315
+ id: FieldOption['id'] | null;
316
+ })[],
317
+ ): Promise<FieldOption[]> => {
318
+ if (!project.story) {
319
+ throw new Error('Project has no story field');
320
+ }
321
+ const mutation = `mutation UpdateStoryOptions($fieldId: ID!, $options: [ProjectV2SingleSelectFieldOptionInput!]!) {
322
+ updateProjectV2Field(input: {
323
+ fieldId: $fieldId
324
+ singleSelectOptions: $options
325
+ }) {
326
+ projectV2Field {
327
+ ... on ProjectV2SingleSelectField {
328
+ options {
329
+ id
330
+ name
331
+ color
332
+ description
333
+ }
334
+ }
335
+ }
336
+ }
337
+ }`;
338
+ const variables = {
339
+ fieldId: project.story.fieldId,
340
+ options: newStoryList.map(({ id, name, color, description }) => ({
341
+ ...(id !== null ? { id } : {}),
342
+ name,
343
+ color,
344
+ description,
345
+ })),
346
+ };
347
+ const response = await ky
348
+ .post('https://api.github.com/graphql', {
349
+ json: { query: mutation, variables },
350
+ headers: {
351
+ Authorization: `Bearer ${this.ghToken}`,
352
+ },
353
+ })
354
+ .json<{
355
+ data: {
356
+ updateProjectV2Field: {
357
+ projectV2Field: {
358
+ options: FieldOption[];
359
+ };
360
+ };
361
+ };
362
+ }>();
363
+ return response.data.updateProjectV2Field.projectV2Field.options;
364
+ };
309
365
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAwEzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAuEzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"GetStoryObjectMapUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAI3D,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,qBAAa,+BAA+B;IAC1C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,EACjB,oBAAoB,MAAM,KACzB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;KAChC,CAAC,CAsEA;CACH"}
1
+ {"version":3,"file":"GetStoryObjectMapUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/GetStoryObjectMapUseCaseHandler.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAEzE,qBAAa,+BAA+B;IAC1C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,EACjB,oBAAoB,MAAM,KACzB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,cAAc,EAAE,cAAc,CAAC;KAChC,CAAC,CAqEA;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAqB3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,KAChB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CAqQP;CACH"}
1
+ {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAoB3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,KAChB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CA8QP;CACH"}
@@ -0,0 +1,30 @@
1
+ import type { Issue } from '../../../domain/entities/Issue';
2
+ import type { LocalCommandRunner } from '../../../domain/usecases/adapter-interfaces/LocalCommandRunner';
3
+ export type SituationFileParams = {
4
+ cachePath: string;
5
+ projectId: string;
6
+ issues: Issue[];
7
+ statusNames: {
8
+ awaitingQualityCheckStatus: string | null;
9
+ preparationStatus: string | null;
10
+ awaitingWorkspaceStatus: string | null;
11
+ };
12
+ config: {
13
+ maximumPreparingIssuesCount: number | null;
14
+ utilizationPercentageThreshold: number;
15
+ allowIssueCacheMinutes: number;
16
+ thresholdForAutoReject: number;
17
+ };
18
+ preparationProcessCheckCommand?: string | null;
19
+ localCommandRunner?: LocalCommandRunner;
20
+ };
21
+ type MeminfoValues = {
22
+ memTotalKb: number;
23
+ memAvailableKb: number;
24
+ swapTotalKb: number;
25
+ swapFreeKb: number;
26
+ };
27
+ export declare const parseMeminfo: (meminfo: string) => MeminfoValues;
28
+ export declare const writeSituationFile: (params: SituationFileParams) => Promise<void>;
29
+ export {};
30
+ //# sourceMappingURL=situationFileWriter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"situationFileWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/situationFileWriter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gEAAgE,CAAC;AAEzG,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,WAAW,EAAE;QACX,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1C,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;QACjC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;KACxC,CAAC;IACF,MAAM,EAAE;QACN,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3C,8BAA8B,EAAE,MAAM,CAAC;QACvC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,sBAAsB,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,aAW9C,CAAC;AAiCF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,mBAAmB,KAC1B,OAAO,CAAC,IAAI,CA2Fd,CAAC"}
@@ -17,7 +17,6 @@ export declare class BaseGitHubRepository {
17
17
  readonly ghUserPassword: string | undefined;
18
18
  readonly ghAuthenticatorKey: string | undefined;
19
19
  cookie: string | null;
20
- protected cookieRefreshRetryDelayMs: number;
21
20
  constructor(localStorageRepository: LocalStorageRepository, jsonFilePath?: string, ghToken?: string, ghUserName?: string | undefined, ghUserPassword?: string | undefined, ghAuthenticatorKey?: string | undefined);
22
21
  protected extractIssueFromUrl: (issueUrl: string) => {
23
22
  owner: string;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseGitHubRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/BaseGitHubRepository.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC;AAED,qBAAa,oBAAoB;IAI7B,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS;IARjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,yBAAyB,SAAQ;gBAEhC,sBAAsB,EAAE,sBAAsB,EAC9C,YAAY,GAAE,MAAwC,EACtD,OAAO,GAAE,MAAwC,EACjD,UAAU,GAAE,MAAM,GAAG,SAAoC,EACzD,cAAc,GAAE,MAAM,GAAG,SAAwC,EACjE,kBAAkB,GAAE,MAAM,GAAG,SACf;IAIzB,SAAS,CAAC,mBAAmB,GAC3B,UAAU,MAAM,KACf;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAevE;IAEF,SAAS,QAAa,OAAO,CAAC,MAAM,CAAC,CAKnC;IACF,YAAY,QAAa,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwBtD;IACF,SAAS,CAAC,0BAA0B,QAAa,OAAO,CAAC,MAAM,CAAC,CAqB9D;IACF,SAAS,CAAC,QAAQ,GAAI,QAAQ,MAAM,KAAG,MAAM,IAAI,MAAM,CAoBrD;IAEF,SAAS,CAAC,4BAA4B,GACpC,YAAY,OAAO,KAClB,OAAO,CAAC,MAAM,CAAC,CAmChB;IACF,aAAa,QAAa,OAAO,CAAC,IAAI,CAAC,CA0BrC;CACH"}
1
+ {"version":3,"file":"BaseGitHubRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/BaseGitHubRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC;AAED,qBAAa,oBAAoB;IAG7B,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS;IAPjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEX,sBAAsB,EAAE,sBAAsB,EAC9C,YAAY,GAAE,MAAwC,EACtD,OAAO,GAAE,MAAwC,EACjD,UAAU,GAAE,MAAM,GAAG,SAAoC,EACzD,cAAc,GAAE,MAAM,GAAG,SAAwC,EACjE,kBAAkB,GAAE,MAAM,GAAG,SACf;IAIzB,SAAS,CAAC,mBAAmB,GAC3B,UAAU,MAAM,KACf;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAevE;IAEF,SAAS,QAAa,OAAO,CAAC,MAAM,CAAC,CAKnC;IACF,YAAY,QAAa,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwBtD;IACF,SAAS,CAAC,0BAA0B,QAAa,OAAO,CAAC,MAAM,CAAC,CAS9D;IACF,SAAS,CAAC,QAAQ,GAAI,QAAQ,MAAM,KAAG,MAAM,IAAI,MAAM,CAoBrD;IAEF,SAAS,CAAC,4BAA4B,GACpC,YAAY,OAAO,KAClB,OAAO,CAAC,MAAM,CAAC,CAmChB;IACF,aAAa,QAAa,OAAO,CAAC,IAAI,CAAC,CAYrC;CACH"}
@@ -1,7 +1,7 @@
1
1
  import { BaseGitHubRepository } from './BaseGitHubRepository';
2
2
  import { ProjectRepository } from '../../domain/usecases/adapter-interfaces/ProjectRepository';
3
- import { Project } from '../../domain/entities/Project';
4
- export declare class GraphqlProjectRepository extends BaseGitHubRepository implements Pick<ProjectRepository, 'getProject' | 'findProjectIdByUrl' | 'getByUrl'> {
3
+ import { FieldOption, Project } from '../../domain/entities/Project';
4
+ export declare class GraphqlProjectRepository extends BaseGitHubRepository implements Pick<ProjectRepository, 'getProject' | 'findProjectIdByUrl' | 'getByUrl' | 'updateStoryList'> {
5
5
  extractProjectFromUrl: (projectUrl: string) => {
6
6
  owner: string;
7
7
  projectNumber: number;
@@ -10,5 +10,8 @@ export declare class GraphqlProjectRepository extends BaseGitHubRepository imple
10
10
  findProjectIdByUrl: (projectUrl: string) => Promise<Project["id"] | null>;
11
11
  getProject: (projectId: Project["id"]) => Promise<Project | null>;
12
12
  getByUrl: (url: string) => Promise<Project>;
13
+ updateStoryList: (project: Project, newStoryList: (Omit<FieldOption, "id"> & {
14
+ id: FieldOption["id"] | null;
15
+ })[]) => Promise<FieldOption[]>;
13
16
  }
14
17
  //# sourceMappingURL=GraphqlProjectRepository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GraphqlProjectRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GraphqlProjectRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4DAA4D,CAAC;AAC/F,OAAO,EAAe,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAGrE,qBAAa,wBACX,SAAQ,oBACR,YACE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,oBAAoB,GAAG,UAAU,CAAC;IAE3E,qBAAqB,GACnB,YAAY,MAAM,KACjB;QACD,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;KACvB,CAMC;IACF,cAAc,GACZ,OAAO,MAAM,EACb,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,CAAC,CAqDhB;IACF,kBAAkB,GAChB,YAAY,MAAM,KACjB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAG9B;IACF,UAAU,GAAU,WAAW,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAkNpE;IACF,QAAQ,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CAU9C;CACH"}
1
+ {"version":3,"file":"GraphqlProjectRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GraphqlProjectRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4DAA4D,CAAC;AAC/F,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAGrE,qBAAa,wBACX,SAAQ,oBACR,YACE,IAAI,CACF,iBAAiB,EACjB,YAAY,GAAG,oBAAoB,GAAG,UAAU,GAAG,iBAAiB,CACrE;IAEH,qBAAqB,GACnB,YAAY,MAAM,KACjB;QACD,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;KACvB,CAMC;IACF,cAAc,GACZ,OAAO,MAAM,EACb,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,CAAC,CAqDhB;IACF,kBAAkB,GAChB,YAAY,MAAM,KACjB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAG9B;IACF,UAAU,GAAU,WAAW,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAkNpE;IACF,QAAQ,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CAU9C;IACF,eAAe,GACb,SAAS,OAAO,EAChB,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;QACvC,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAC9B,CAAC,EAAE,KACH,OAAO,CAAC,WAAW,EAAE,CAAC,CA+CvB;CACH"}
@@ -1,45 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CheerioProjectRepository = void 0;
7
- const ky_1 = __importDefault(require("ky"));
8
- const BaseGitHubRepository_1 = require("./BaseGitHubRepository");
9
- class CheerioProjectRepository extends BaseGitHubRepository_1.BaseGitHubRepository {
10
- constructor(localStorageRepository, jsonFilePath = './tmp/github.com.cookies.json', ghToken = process.env.GH_TOKEN || 'dummy', ghUserName = process.env.GH_USER_NAME, ghUserPassword = process.env.GH_USER_PASSWORD, ghAuthenticatorKey = process.env
11
- .GH_AUTHENTICATOR_KEY) {
12
- super(localStorageRepository, jsonFilePath, ghToken, ghUserName, ghUserPassword, ghAuthenticatorKey);
13
- this.localStorageRepository = localStorageRepository;
14
- this.jsonFilePath = jsonFilePath;
15
- this.ghToken = ghToken;
16
- this.ghUserName = ghUserName;
17
- this.ghUserPassword = ghUserPassword;
18
- this.ghAuthenticatorKey = ghAuthenticatorKey;
19
- this.updateStoryList = async (project, newStoryList) => {
20
- const browserHeaders = await this.createHeader();
21
- const raw = await ky_1.default
22
- .put(`https://github.com/memexes/${project.databaseId}/columns`, {
23
- json: {
24
- memexProjectColumnId: project.story?.databaseId,
25
- settings: { width: 200, options: newStoryList },
26
- },
27
- headers: {
28
- 'github-verified-fetch': 'true',
29
- origin: 'https://github.com',
30
- 'x-requested-with': 'XMLHttpRequest',
31
- ...browserHeaders,
32
- },
33
- })
34
- .json();
35
- return raw.memexProjectColumn.settings.options.map((v) => ({
36
- id: v.id,
37
- name: v.name,
38
- color: v.color,
39
- description: v.description,
40
- }));
41
- };
42
- }
43
- }
44
- exports.CheerioProjectRepository = CheerioProjectRepository;
45
- //# sourceMappingURL=CheerioProjectRepository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CheerioProjectRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/CheerioProjectRepository.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,iEAA8D;AAK9D,MAAa,wBACX,SAAQ,2CAAoB;IAG5B,YACW,sBAA8C,EAC9C,eAAuB,+BAA+B,EACtD,UAAkB,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,EACjD,aAAiC,OAAO,CAAC,GAAG,CAAC,YAAY,EACzD,iBAAqC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EACjE,qBAAyC,OAAO,CAAC,GAAG;SAC1D,oBAAoB;QAEvB,KAAK,CACH,sBAAsB,EACtB,YAAY,EACZ,OAAO,EACP,UAAU,EACV,cAAc,EACd,kBAAkB,CACnB,CAAC;QAfO,2BAAsB,GAAtB,sBAAsB,CAAwB;QAC9C,iBAAY,GAAZ,YAAY,CAA0C;QACtD,YAAO,GAAP,OAAO,CAA0C;QACjD,eAAU,GAAV,UAAU,CAA+C;QACzD,mBAAc,GAAd,cAAc,CAAmD;QACjE,uBAAkB,GAAlB,kBAAkB,CACJ;QAWzB,oBAAe,GAAG,KAAK,EACrB,OAAgB,EAChB,YAEI,EACoB,EAAE;YAC1B,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YACjD,MAAM,GAAG,GAAG,MAAM,YAAE;iBACjB,GAAG,CAAC,8BAA8B,OAAO,CAAC,UAAU,UAAU,EAAE;gBAC/D,IAAI,EAAE;oBACJ,oBAAoB,EAAE,OAAO,CAAC,KAAK,EAAE,UAAU;oBAC/C,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE;iBAChD;gBACD,OAAO,EAAE;oBACP,uBAAuB,EAAE,MAAM;oBAC/B,MAAM,EAAE,oBAAoB;oBAC5B,kBAAkB,EAAE,gBAAgB;oBACpC,GAAG,cAAc;iBAClB;aACF,CAAC;iBACD,IAAI,EAQD,CAAC;YACP,OAAO,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACzD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,WAAW,EAAE,CAAC,CAAC,WAAW;aAC3B,CAAC,CAAC,CAAC;QACN,CAAC,CAAC;IApCF,CAAC;CAqCF;AA1DD,4DA0DC"}
@@ -1,122 +0,0 @@
1
- import { CheerioProjectRepository } from './CheerioProjectRepository';
2
- import dotenv from 'dotenv';
3
- import { LocalStorageRepository } from './LocalStorageRepository';
4
- import { FieldOption, Project } from '../../domain/entities/Project';
5
-
6
- dotenv.config();
7
-
8
- describe('CheerioProjectRepository', () => {
9
- jest.setTimeout(60 * 1000);
10
- const localStorageRepository = new LocalStorageRepository();
11
-
12
- const repository = new CheerioProjectRepository(
13
- localStorageRepository,
14
- './tmp/github.com.cookies.json',
15
- process.env.GH_TOKEN,
16
- );
17
- beforeAll(async () => {
18
- await repository.refreshCookie();
19
- });
20
- beforeEach(async () => {
21
- await new Promise((resolve) => setTimeout(resolve, 2000));
22
- });
23
-
24
- describe('updateStoryList', () => {
25
- it('success', async () => {
26
- const project: Project = {
27
- completionDate50PercentConfidence: null,
28
- dependedIssueUrlSeparatedByComma: null,
29
- id: 'PVT_kwHOAGJHa84AFhgF',
30
- url: 'https://github.com/users/HiromiShikata/projects/49',
31
- databaseId: 1447941,
32
- name: 'V2 project on owner for testing',
33
- nextActionDate: {
34
- fieldId: 'PVTF_lAHOAGJHa84AFhgFzgVlnK4',
35
- name: 'NextActionDate',
36
- },
37
- nextActionHour: null,
38
- remainingEstimationMinutes: null,
39
- status: {
40
- fieldId: 'PVTSSF_lAHOAGJHa84AFhgFzgDLt0c',
41
- name: 'Status',
42
- statuses: [
43
- {
44
- color: 'GRAY',
45
- description: '',
46
- id: 'f75ad846',
47
- name: 'Todo',
48
- },
49
- {
50
- color: 'GRAY',
51
- description: '',
52
- id: '47fc9ee4',
53
- name: 'In Progress',
54
- },
55
- {
56
- color: 'GRAY',
57
- description: '',
58
- id: '98236657',
59
- name: 'Done',
60
- },
61
- ],
62
- },
63
- story: {
64
- fieldId: 'PVTSSF_lAHOAGJHa84AFhgFzg1oBms',
65
- databaseId: 224921195,
66
- name: 'Story',
67
- stories: [
68
- {
69
- color: 'GRAY',
70
- description: '',
71
- id: 'af410dae',
72
- name: 'story1',
73
- },
74
- {
75
- color: 'GRAY',
76
- description: '',
77
- id: '696ccdef',
78
- name: 'Workflow Management',
79
- },
80
- {
81
- color: 'GRAY',
82
- description: '',
83
- id: '4fa21881',
84
- name: 'test',
85
- },
86
- ],
87
- workflowManagementStory: {
88
- id: '696ccdef',
89
- name: 'Workflow Management',
90
- },
91
- },
92
- };
93
-
94
- const storyOption: Omit<FieldOption, 'id'> & { id: null } = {
95
- id: null,
96
- name: 'test-story-from-unit-test',
97
- color: 'BLUE',
98
- description: 'created by unit test',
99
- };
100
- const story = project.story;
101
- if (!story) {
102
- throw new Error('story is null');
103
- }
104
- const newStoryList: Parameters<typeof repository.updateStoryList>['1'] =
105
- [];
106
- newStoryList.push(...story.stories.slice(0, 2), storyOption);
107
-
108
- const res = await repository.updateStoryList(project, newStoryList);
109
- expect(res[0]).toEqual(newStoryList[0]);
110
- expect(res[1]).toEqual(newStoryList[1]);
111
- expect(res[1].id).toBeDefined();
112
- expect(res[2].name).toEqual(newStoryList[2].name);
113
- expect(res[2].color).toEqual(newStoryList[2].color);
114
- expect(res[2].description).toEqual(newStoryList[2].description);
115
- const resRemoved = await repository.updateStoryList(
116
- project,
117
- story.stories,
118
- );
119
- expect(resRemoved).toEqual(story.stories);
120
- });
121
- });
122
- });
@@ -1,65 +0,0 @@
1
- import ky from 'ky';
2
- import { BaseGitHubRepository } from './BaseGitHubRepository';
3
- import { LocalStorageRepository } from './LocalStorageRepository';
4
- import { FieldOption, Project } from '../../domain/entities/Project';
5
- import { ProjectRepository } from '../../domain/usecases/adapter-interfaces/ProjectRepository';
6
-
7
- export class CheerioProjectRepository
8
- extends BaseGitHubRepository
9
- implements Pick<ProjectRepository, 'updateStoryList'>
10
- {
11
- constructor(
12
- readonly localStorageRepository: LocalStorageRepository,
13
- readonly jsonFilePath: string = './tmp/github.com.cookies.json',
14
- readonly ghToken: string = process.env.GH_TOKEN || 'dummy',
15
- readonly ghUserName: string | undefined = process.env.GH_USER_NAME,
16
- readonly ghUserPassword: string | undefined = process.env.GH_USER_PASSWORD,
17
- readonly ghAuthenticatorKey: string | undefined = process.env
18
- .GH_AUTHENTICATOR_KEY,
19
- ) {
20
- super(
21
- localStorageRepository,
22
- jsonFilePath,
23
- ghToken,
24
- ghUserName,
25
- ghUserPassword,
26
- ghAuthenticatorKey,
27
- );
28
- }
29
- updateStoryList = async (
30
- project: Project,
31
- newStoryList: (Omit<FieldOption, 'id'> & {
32
- id: FieldOption['id'] | null;
33
- })[],
34
- ): Promise<FieldOption[]> => {
35
- const browserHeaders = await this.createHeader();
36
- const raw = await ky
37
- .put(`https://github.com/memexes/${project.databaseId}/columns`, {
38
- json: {
39
- memexProjectColumnId: project.story?.databaseId,
40
- settings: { width: 200, options: newStoryList },
41
- },
42
- headers: {
43
- 'github-verified-fetch': 'true',
44
- origin: 'https://github.com',
45
- 'x-requested-with': 'XMLHttpRequest',
46
- ...browserHeaders,
47
- },
48
- })
49
- .json<{
50
- memexProjectColumn: {
51
- id: string;
52
- settings: {
53
- width: number;
54
- options: FieldOption[];
55
- };
56
- };
57
- }>();
58
- return raw.memexProjectColumn.settings.options.map((v) => ({
59
- id: v.id,
60
- name: v.name,
61
- color: v.color,
62
- description: v.description,
63
- }));
64
- };
65
- }
@@ -1,17 +0,0 @@
1
- import { BaseGitHubRepository } from './BaseGitHubRepository';
2
- import { LocalStorageRepository } from './LocalStorageRepository';
3
- import { FieldOption, Project } from '../../domain/entities/Project';
4
- import { ProjectRepository } from '../../domain/usecases/adapter-interfaces/ProjectRepository';
5
- export declare class CheerioProjectRepository extends BaseGitHubRepository implements Pick<ProjectRepository, 'updateStoryList'> {
6
- readonly localStorageRepository: LocalStorageRepository;
7
- readonly jsonFilePath: string;
8
- readonly ghToken: string;
9
- readonly ghUserName: string | undefined;
10
- readonly ghUserPassword: string | undefined;
11
- readonly ghAuthenticatorKey: string | undefined;
12
- constructor(localStorageRepository: LocalStorageRepository, jsonFilePath?: string, ghToken?: string, ghUserName?: string | undefined, ghUserPassword?: string | undefined, ghAuthenticatorKey?: string | undefined);
13
- updateStoryList: (project: Project, newStoryList: (Omit<FieldOption, "id"> & {
14
- id: FieldOption["id"] | null;
15
- })[]) => Promise<FieldOption[]>;
16
- }
17
- //# sourceMappingURL=CheerioProjectRepository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"CheerioProjectRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/CheerioProjectRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4DAA4D,CAAC;AAE/F,qBAAa,wBACX,SAAQ,oBACR,YAAW,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAGnD,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS;IAC3C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,SAAS;gBALtC,sBAAsB,EAAE,sBAAsB,EAC9C,YAAY,GAAE,MAAwC,EACtD,OAAO,GAAE,MAAwC,EACjD,UAAU,GAAE,MAAM,GAAG,SAAoC,EACzD,cAAc,GAAE,MAAM,GAAG,SAAwC,EACjE,kBAAkB,GAAE,MAAM,GAAG,SACf;IAWzB,eAAe,GACb,SAAS,OAAO,EAChB,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;QACvC,EAAE,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAC9B,CAAC,EAAE,KACH,OAAO,CAAC,WAAW,EAAE,CAAC,CA8BvB;CACH"}