github-issue-tower-defence-management 1.1.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 (221) hide show
  1. package/.env.example +6 -0
  2. package/.eslintrc.cjs +55 -0
  3. package/.github/CODEOWNERS +2 -0
  4. package/.github/workflows/assign-all-cards-to-owner.yml +14 -0
  5. package/.github/workflows/commit-lint.yml +54 -0
  6. package/.github/workflows/configs/commitlint.config.js +27 -0
  7. package/.github/workflows/create-pr.yml +64 -0
  8. package/.github/workflows/format.yml +25 -0
  9. package/.github/workflows/publish.yml +47 -0
  10. package/.github/workflows/test.yml +45 -0
  11. package/.github/workflows/umino-project.yml +181 -0
  12. package/.prettierignore +22 -0
  13. package/.prettierrc +5 -0
  14. package/CHANGELOG.md +49 -0
  15. package/CONTRIBUTING.md +107 -0
  16. package/README.md +108 -0
  17. package/bin/adapter/entry-points/cli/index.js +26 -0
  18. package/bin/adapter/entry-points/cli/index.js.map +1 -0
  19. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +142 -0
  20. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -0
  21. package/bin/adapter/repositories/AxiosSlackRepository.js +124 -0
  22. package/bin/adapter/repositories/AxiosSlackRepository.js.map +1 -0
  23. package/bin/adapter/repositories/BaseGitHubRepository.js +136 -0
  24. package/bin/adapter/repositories/BaseGitHubRepository.js.map +1 -0
  25. package/bin/adapter/repositories/GoogleSpreadsheetRepository.js +123 -0
  26. package/bin/adapter/repositories/GoogleSpreadsheetRepository.js.map +1 -0
  27. package/bin/adapter/repositories/GraphqlProjectRepository.js +167 -0
  28. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -0
  29. package/bin/adapter/repositories/LocalStorageCacheRepository.js +46 -0
  30. package/bin/adapter/repositories/LocalStorageCacheRepository.js.map +1 -0
  31. package/bin/adapter/repositories/LocalStorageRepository.js +30 -0
  32. package/bin/adapter/repositories/LocalStorageRepository.js.map +1 -0
  33. package/bin/adapter/repositories/SystemDateRepository.js +23 -0
  34. package/bin/adapter/repositories/SystemDateRepository.js.map +1 -0
  35. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +148 -0
  36. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -0
  37. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js +48 -0
  38. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js.map +1 -0
  39. package/bin/adapter/repositories/issue/CheerioIssueRepository.js +120 -0
  40. package/bin/adapter/repositories/issue/CheerioIssueRepository.js.map +1 -0
  41. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +485 -0
  42. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -0
  43. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js +114 -0
  44. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js.map +1 -0
  45. package/bin/adapter/repositories/issue/RestIssueRepository.js +79 -0
  46. package/bin/adapter/repositories/issue/RestIssueRepository.js.map +1 -0
  47. package/bin/adapter/repositories/issue/issueTimelineUtils.js +38 -0
  48. package/bin/adapter/repositories/issue/issueTimelineUtils.js.map +1 -0
  49. package/bin/adapter/repositories/utils.js +45 -0
  50. package/bin/adapter/repositories/utils.js.map +1 -0
  51. package/bin/domain/entities/Issue.js +3 -0
  52. package/bin/domain/entities/Issue.js.map +1 -0
  53. package/bin/domain/entities/Member.js +3 -0
  54. package/bin/domain/entities/Member.js.map +1 -0
  55. package/bin/domain/entities/Project.js +3 -0
  56. package/bin/domain/entities/Project.js.map +1 -0
  57. package/bin/domain/entities/ProjectField.js +3 -0
  58. package/bin/domain/entities/ProjectField.js.map +1 -0
  59. package/bin/domain/entities/ProjectFieldSingleSelect.js +3 -0
  60. package/bin/domain/entities/ProjectFieldSingleSelect.js.map +1 -0
  61. package/bin/domain/entities/ProjectFieldSingleSelectOption.js +3 -0
  62. package/bin/domain/entities/ProjectFieldSingleSelectOption.js.map +1 -0
  63. package/bin/domain/entities/WorkingTime.js +3 -0
  64. package/bin/domain/entities/WorkingTime.js.map +1 -0
  65. package/bin/domain/usecases/ActionAnnouncementUseCase.js +46 -0
  66. package/bin/domain/usecases/ActionAnnouncementUseCase.js.map +1 -0
  67. package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js +116 -0
  68. package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js.map +1 -0
  69. package/bin/domain/usecases/ClearNextActionHourUseCase.js +38 -0
  70. package/bin/domain/usecases/ClearNextActionHourUseCase.js.map +1 -0
  71. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js +180 -0
  72. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js.map +1 -0
  73. package/bin/domain/usecases/HandleScheduledEventUseCase.js +122 -0
  74. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -0
  75. package/bin/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.js +35 -0
  76. package/bin/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.js.map +1 -0
  77. package/bin/domain/usecases/adapter-interfaces/DateRepository.js +3 -0
  78. package/bin/domain/usecases/adapter-interfaces/DateRepository.js.map +1 -0
  79. package/bin/domain/usecases/adapter-interfaces/IssueRepository.js +3 -0
  80. package/bin/domain/usecases/adapter-interfaces/IssueRepository.js.map +1 -0
  81. package/bin/domain/usecases/adapter-interfaces/ProjectRepository.js +3 -0
  82. package/bin/domain/usecases/adapter-interfaces/ProjectRepository.js.map +1 -0
  83. package/bin/domain/usecases/adapter-interfaces/SlackRepository.js +3 -0
  84. package/bin/domain/usecases/adapter-interfaces/SlackRepository.js.map +1 -0
  85. package/bin/domain/usecases/adapter-interfaces/SpreadsheetRepository.js +3 -0
  86. package/bin/domain/usecases/adapter-interfaces/SpreadsheetRepository.js.map +1 -0
  87. package/bin/index.js +13 -0
  88. package/bin/index.js.map +1 -0
  89. package/commitlint.config.js +6 -0
  90. package/jest.config.js +19 -0
  91. package/package.json +80 -0
  92. package/renovate.json +37 -0
  93. package/src/adapter/entry-points/cli/index.test.ts +20 -0
  94. package/src/adapter/entry-points/cli/index.ts +36 -0
  95. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +95 -0
  96. package/src/adapter/repositories/AxiosSlackRepository.test.ts +119 -0
  97. package/src/adapter/repositories/AxiosSlackRepository.ts +184 -0
  98. package/src/adapter/repositories/BaseGitHubRepository.test.ts +95 -0
  99. package/src/adapter/repositories/BaseGitHubRepository.ts +172 -0
  100. package/src/adapter/repositories/GoogleSpreadsheetRepository.test.ts +124 -0
  101. package/src/adapter/repositories/GoogleSpreadsheetRepository.ts +151 -0
  102. package/src/adapter/repositories/GraphqlProjectRepository.test.ts +46 -0
  103. package/src/adapter/repositories/GraphqlProjectRepository.ts +236 -0
  104. package/src/adapter/repositories/LocalStorageCacheRepository.test.ts +146 -0
  105. package/src/adapter/repositories/LocalStorageCacheRepository.ts +53 -0
  106. package/src/adapter/repositories/LocalStorageRepository.integration.test.ts +142 -0
  107. package/src/adapter/repositories/LocalStorageRepository.test.ts +161 -0
  108. package/src/adapter/repositories/LocalStorageRepository.ts +21 -0
  109. package/src/adapter/repositories/SystemDateRepository.ts +20 -0
  110. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +158 -0
  111. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +274 -0
  112. package/src/adapter/repositories/issue/ApiV3IssueRepository.test.ts +26 -0
  113. package/src/adapter/repositories/issue/ApiV3IssueRepository.ts +59 -0
  114. package/src/adapter/repositories/issue/CheerioIssueRepository.test.ts +6610 -0
  115. package/src/adapter/repositories/issue/CheerioIssueRepository.ts +127 -0
  116. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +49 -0
  117. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +745 -0
  118. package/src/adapter/repositories/issue/InternalGraphqlIssueRepository.test.ts +71 -0
  119. package/src/adapter/repositories/issue/InternalGraphqlIssueRepository.ts +263 -0
  120. package/src/adapter/repositories/issue/RestIssueRepository.test.ts +29 -0
  121. package/src/adapter/repositories/issue/RestIssueRepository.ts +105 -0
  122. package/src/adapter/repositories/issue/issueTimelineUtils.test.ts +79 -0
  123. package/src/adapter/repositories/issue/issueTimelineUtils.ts +52 -0
  124. package/src/adapter/repositories/utils.test.ts +40 -0
  125. package/src/adapter/repositories/utils.ts +50 -0
  126. package/src/domain/entities/Issue.ts +23 -0
  127. package/src/domain/entities/Member.ts +3 -0
  128. package/src/domain/entities/Project.ts +29 -0
  129. package/src/domain/entities/ProjectField.ts +3 -0
  130. package/src/domain/entities/ProjectFieldSingleSelect.ts +8 -0
  131. package/src/domain/entities/ProjectFieldSingleSelectOption.ts +8 -0
  132. package/src/domain/entities/WorkingTime.ts +8 -0
  133. package/src/domain/usecases/ActionAnnouncementUseCase.ts +76 -0
  134. package/src/domain/usecases/AnalyzeProblemByIssueUseCase.ts +209 -0
  135. package/src/domain/usecases/ClearNextActionHourUseCase.ts +51 -0
  136. package/src/domain/usecases/GenerateWorkingTimeReportUseCase.test.ts +382 -0
  137. package/src/domain/usecases/GenerateWorkingTimeReportUseCase.ts +284 -0
  138. package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +58 -0
  139. package/src/domain/usecases/HandleScheduledEventUseCase.ts +209 -0
  140. package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.ts +46 -0
  141. package/src/domain/usecases/adapter-interfaces/DateRepository.ts +5 -0
  142. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +44 -0
  143. package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +6 -0
  144. package/src/domain/usecases/adapter-interfaces/SlackRepository.ts +20 -0
  145. package/src/domain/usecases/adapter-interfaces/SpreadsheetRepository.ts +18 -0
  146. package/src/index.test.ts +8 -0
  147. package/src/index.ts +7 -0
  148. package/tsconfig.build.json +11 -0
  149. package/tsconfig.json +22 -0
  150. package/types/adapter/entry-points/cli/index.d.ts +3 -0
  151. package/types/adapter/entry-points/cli/index.d.ts.map +1 -0
  152. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts +11 -0
  153. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -0
  154. package/types/adapter/repositories/AxiosSlackRepository.d.ts +13 -0
  155. package/types/adapter/repositories/AxiosSlackRepository.d.ts.map +1 -0
  156. package/types/adapter/repositories/BaseGitHubRepository.d.ts +32 -0
  157. package/types/adapter/repositories/BaseGitHubRepository.d.ts.map +1 -0
  158. package/types/adapter/repositories/GoogleSpreadsheetRepository.d.ts +13 -0
  159. package/types/adapter/repositories/GoogleSpreadsheetRepository.d.ts.map +1 -0
  160. package/types/adapter/repositories/GraphqlProjectRepository.d.ts +13 -0
  161. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -0
  162. package/types/adapter/repositories/LocalStorageCacheRepository.d.ts +12 -0
  163. package/types/adapter/repositories/LocalStorageCacheRepository.d.ts.map +1 -0
  164. package/types/adapter/repositories/LocalStorageRepository.d.ts +7 -0
  165. package/types/adapter/repositories/LocalStorageRepository.d.ts.map +1 -0
  166. package/types/adapter/repositories/SystemDateRepository.d.ts +7 -0
  167. package/types/adapter/repositories/SystemDateRepository.d.ts.map +1 -0
  168. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +38 -0
  169. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -0
  170. package/types/adapter/repositories/issue/ApiV3IssueRepository.d.ts +17 -0
  171. package/types/adapter/repositories/issue/ApiV3IssueRepository.d.ts.map +1 -0
  172. package/types/adapter/repositories/issue/CheerioIssueRepository.d.ts +31 -0
  173. package/types/adapter/repositories/issue/CheerioIssueRepository.d.ts.map +1 -0
  174. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts +39 -0
  175. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -0
  176. package/types/adapter/repositories/issue/InternalGraphqlIssueRepository.d.ts +83 -0
  177. package/types/adapter/repositories/issue/InternalGraphqlIssueRepository.d.ts.map +1 -0
  178. package/types/adapter/repositories/issue/RestIssueRepository.d.ts +16 -0
  179. package/types/adapter/repositories/issue/RestIssueRepository.d.ts.map +1 -0
  180. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts +12 -0
  181. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts.map +1 -0
  182. package/types/adapter/repositories/utils.d.ts +4 -0
  183. package/types/adapter/repositories/utils.d.ts.map +1 -0
  184. package/types/domain/entities/Issue.d.ts +24 -0
  185. package/types/domain/entities/Issue.d.ts.map +1 -0
  186. package/types/domain/entities/Member.d.ts +4 -0
  187. package/types/domain/entities/Member.d.ts.map +1 -0
  188. package/types/domain/entities/Project.d.ts +29 -0
  189. package/types/domain/entities/Project.d.ts.map +1 -0
  190. package/types/domain/entities/ProjectField.d.ts +3 -0
  191. package/types/domain/entities/ProjectField.d.ts.map +1 -0
  192. package/types/domain/entities/ProjectFieldSingleSelect.d.ts +8 -0
  193. package/types/domain/entities/ProjectFieldSingleSelect.d.ts.map +1 -0
  194. package/types/domain/entities/ProjectFieldSingleSelectOption.d.ts +8 -0
  195. package/types/domain/entities/ProjectFieldSingleSelectOption.d.ts.map +1 -0
  196. package/types/domain/entities/WorkingTime.d.ts +8 -0
  197. package/types/domain/entities/WorkingTime.d.ts.map +1 -0
  198. package/types/domain/usecases/ActionAnnouncementUseCase.d.ts +17 -0
  199. package/types/domain/usecases/ActionAnnouncementUseCase.d.ts.map +1 -0
  200. package/types/domain/usecases/AnalyzeProblemByIssueUseCase.d.ts +26 -0
  201. package/types/domain/usecases/AnalyzeProblemByIssueUseCase.d.ts.map +1 -0
  202. package/types/domain/usecases/ClearNextActionHourUseCase.d.ts +14 -0
  203. package/types/domain/usecases/ClearNextActionHourUseCase.d.ts.map +1 -0
  204. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts +50 -0
  205. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts.map +1 -0
  206. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +63 -0
  207. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -0
  208. package/types/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.d.ts +14 -0
  209. package/types/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.d.ts.map +1 -0
  210. package/types/domain/usecases/adapter-interfaces/DateRepository.d.ts +6 -0
  211. package/types/domain/usecases/adapter-interfaces/DateRepository.d.ts.map +1 -0
  212. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +23 -0
  213. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -0
  214. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts +6 -0
  215. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts.map +1 -0
  216. package/types/domain/usecases/adapter-interfaces/SlackRepository.d.ts +9 -0
  217. package/types/domain/usecases/adapter-interfaces/SlackRepository.d.ts.map +1 -0
  218. package/types/domain/usecases/adapter-interfaces/SpreadsheetRepository.d.ts +6 -0
  219. package/types/domain/usecases/adapter-interfaces/SpreadsheetRepository.d.ts.map +1 -0
  220. package/types/index.d.ts +10 -0
  221. package/types/index.d.ts.map +1 -0
@@ -0,0 +1,58 @@
1
+ import { HandleScheduledEventUseCase } from './HandleScheduledEventUseCase';
2
+
3
+ describe('HandleScheduledEventUseCase', () => {
4
+ describe('createTargetDateTimes', () => {
5
+ const testCases: {
6
+ lastExecutionDateTime: Date;
7
+ now: Date;
8
+ expected: Date[];
9
+ }[] = [
10
+ {
11
+ lastExecutionDateTime: new Date('2021-01-01T00:00:00Z'),
12
+ now: new Date('2021-01-01T00:00:00Z'),
13
+ expected: [],
14
+ },
15
+ {
16
+ lastExecutionDateTime: new Date('2021-01-01T00:00:00Z'),
17
+ now: new Date('2021-01-01T00:00:01Z'),
18
+ expected: [],
19
+ },
20
+ {
21
+ lastExecutionDateTime: new Date('2021-01-01T00:00:00Z'),
22
+ now: new Date('2020-01-01T00:00:02Z'),
23
+ expected: [new Date('2020-01-01T00:00:00Z')],
24
+ },
25
+ {
26
+ lastExecutionDateTime: new Date('2021-01-01T00:00:00Z'),
27
+ now: new Date('2021-01-01T00:05:00Z'),
28
+ expected: [
29
+ new Date('2021-01-01T00:01:00Z'),
30
+ new Date('2021-01-01T00:02:00Z'),
31
+ new Date('2021-01-01T00:03:00Z'),
32
+ new Date('2021-01-01T00:04:00Z'),
33
+ new Date('2021-01-01T00:05:00Z'),
34
+ ],
35
+ },
36
+ {
37
+ lastExecutionDateTime: new Date('2021-01-01T00:00:00Z'),
38
+ now: new Date('2022-01-01T00:00:00Z'),
39
+ expected: Array(30)
40
+ .fill(0)
41
+ .map((_, i) => {
42
+ const d = new Date('2021-01-01T00:00:00Z');
43
+ d.setTime(d.getTime() + (i + 1) * 60 * 1000);
44
+ return d;
45
+ }),
46
+ },
47
+ ];
48
+ testCases.forEach((testCase) => {
49
+ it(`should return ${testCase.expected.map((d) => d.toISOString()).join(',')} when lastExecutionDateTime is ${testCase.lastExecutionDateTime.toISOString()} and now is ${testCase.now.toISOString()}`, () => {
50
+ const result = HandleScheduledEventUseCase.createTargetDateTimes(
51
+ testCase.lastExecutionDateTime,
52
+ testCase.now,
53
+ );
54
+ expect(result).toEqual(testCase.expected);
55
+ });
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,209 @@
1
+ import { Issue, Label } from '../entities/Issue';
2
+ import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
+ import { Project } from '../entities/Project';
4
+ import { ProjectRepository } from './adapter-interfaces/ProjectRepository';
5
+ import { GenerateWorkingTimeReportUseCase } from './GenerateWorkingTimeReportUseCase';
6
+ import { Member } from '../entities/Member';
7
+ import { DateRepository } from './adapter-interfaces/DateRepository';
8
+ import { SpreadsheetRepository } from './adapter-interfaces/SpreadsheetRepository';
9
+ import { ActionAnnouncementUseCase } from './ActionAnnouncementUseCase';
10
+ import { SetWorkflowManagementIssueToStoryUseCase } from './SetWorkflowManagementIssueToStoryUseCase';
11
+ import { ClearNextActionHourUseCase } from './ClearNextActionHourUseCase';
12
+ import { AnalyzeProblemByIssueUseCase } from './AnalyzeProblemByIssueUseCase';
13
+
14
+ export class ProjectNotFoundError extends Error {
15
+ constructor(message: string) {
16
+ super(message);
17
+ this.name = 'ProjectNotFoundError';
18
+ }
19
+ }
20
+
21
+ export class HandleScheduledEventUseCase {
22
+ constructor(
23
+ readonly generateWorkingTimeReportUseCase: GenerateWorkingTimeReportUseCase,
24
+ readonly actionAnnouncementUseCase: ActionAnnouncementUseCase,
25
+ readonly setWorkflowManagementIssueToStoryUseCase: SetWorkflowManagementIssueToStoryUseCase,
26
+ readonly clearNextActionHourUseCase: ClearNextActionHourUseCase,
27
+ readonly analyzeProblemByIssueUseCase: AnalyzeProblemByIssueUseCase,
28
+ readonly dateRepository: DateRepository,
29
+ readonly spreadsheetRepository: SpreadsheetRepository,
30
+ readonly projectRepository: ProjectRepository,
31
+ readonly issueRepository: IssueRepository,
32
+ ) {}
33
+
34
+ run = async (input: {
35
+ org: string;
36
+ projectUrl: string;
37
+ manager: Member['name'];
38
+ workingReport: {
39
+ repo: string;
40
+ members: Member['name'][];
41
+ warningThresholdHour?: number;
42
+ spreadsheetUrl: string;
43
+ reportIssueTemplate?: string;
44
+ reportIssueLabels: Label[];
45
+ };
46
+ }): Promise<{
47
+ project: Project;
48
+ issues: Issue[];
49
+ cacheUsed: boolean;
50
+ targetDateTimes: Date[];
51
+ }> => {
52
+ const projectId = await this.projectRepository.findProjectIdByUrl(
53
+ input.projectUrl,
54
+ );
55
+ if (!projectId) {
56
+ throw new ProjectNotFoundError(
57
+ `Project not found. projectUrl: ${input.projectUrl}`,
58
+ );
59
+ }
60
+ const project = await this.projectRepository.getProject(projectId);
61
+ if (!project) {
62
+ throw new ProjectNotFoundError(
63
+ `Project not found. projectId: ${
64
+ projectId
65
+ } projectUrl: ${input.projectUrl}`,
66
+ );
67
+ }
68
+ const now: Date = await this.dateRepository.now();
69
+ const allowIssueCacheMinutes = 60;
70
+ const { issues, cacheUsed }: { issues: Issue[]; cacheUsed: boolean } =
71
+ await this.issueRepository.getAllIssues(
72
+ projectId,
73
+ allowIssueCacheMinutes,
74
+ );
75
+
76
+ const targetDateTimes: Date[] =
77
+ await this.findTargetDateAndUpdateLastExecutionDateTime(
78
+ input.workingReport.spreadsheetUrl,
79
+ now,
80
+ );
81
+
82
+ for (const targetDateTime of targetDateTimes) {
83
+ await this.runForTargetDateTime({
84
+ org: input.org,
85
+ manager: input.manager,
86
+ workingReport: input.workingReport,
87
+ projectId,
88
+ issues,
89
+ targetDateTime,
90
+ });
91
+ }
92
+ await this.analyzeProblemByIssueUseCase.run({
93
+ targetDates: targetDateTimes,
94
+ project,
95
+ issues,
96
+ cacheUsed,
97
+ manager: input.manager,
98
+ org: input.org,
99
+ repo: input.workingReport.repo,
100
+ });
101
+ await this.actionAnnouncementUseCase.run({
102
+ targetDates: targetDateTimes,
103
+ project,
104
+ issues,
105
+ cacheUsed,
106
+ members: input.workingReport.members,
107
+ manager: input.manager,
108
+ });
109
+ await this.setWorkflowManagementIssueToStoryUseCase.run({
110
+ targetDates: targetDateTimes,
111
+ project,
112
+ issues,
113
+ cacheUsed,
114
+ });
115
+ await this.clearNextActionHourUseCase.run({
116
+ targetDates: targetDateTimes,
117
+ project,
118
+ issues,
119
+ cacheUsed,
120
+ });
121
+ return { project, issues, cacheUsed, targetDateTimes };
122
+ };
123
+ runForTargetDateTime = async (input: {
124
+ org: string;
125
+ manager: Member['name'];
126
+ workingReport: {
127
+ repo: string;
128
+ members: Member['name'][];
129
+ warningThresholdHour?: number;
130
+ spreadsheetUrl: string;
131
+ reportIssueTemplate?: string;
132
+ reportIssueLabels: Label[];
133
+ };
134
+ projectId: Project['id'];
135
+ issues: Issue[];
136
+ targetDateTime: Date;
137
+ }): Promise<void> => {
138
+ const targetHour = input.targetDateTime.getHours();
139
+ const targetMinute = input.targetDateTime.getMinutes();
140
+ if (targetHour === 0 && targetMinute === 0) {
141
+ const yesterday = new Date(
142
+ input.targetDateTime.getTime() - 24 * 60 * 60 * 1000,
143
+ );
144
+
145
+ await this.generateWorkingTimeReportUseCase.run({
146
+ ...input,
147
+ ...input.workingReport,
148
+ targetDate: yesterday,
149
+ });
150
+ }
151
+ };
152
+ static createTargetDateTimes = (from: Date, to: Date): Date[] => {
153
+ const targetDateTimes: Date[] = [];
154
+ if (from.getTime() > to.getTime()) {
155
+ const targetDate = new Date(to);
156
+ targetDate.setSeconds(0);
157
+ targetDate.setMilliseconds(0);
158
+ return [targetDate];
159
+ }
160
+ const targetDate = new Date(from);
161
+ targetDate.setTime(targetDate.getTime() + 60 * 1000);
162
+ targetDate.setSeconds(0);
163
+ targetDate.setMilliseconds(0);
164
+ while (
165
+ targetDate.getTime() <= to.getTime() &&
166
+ targetDateTimes.length < 30
167
+ ) {
168
+ targetDateTimes.push(new Date(targetDate));
169
+ targetDate.setMinutes(targetDate.getMinutes() + 1);
170
+ }
171
+ return targetDateTimes;
172
+ };
173
+ findTargetDateAndUpdateLastExecutionDateTime = async (
174
+ spreadsheetUrl: string,
175
+ now: Date,
176
+ ): Promise<Date[]> => {
177
+ const sheetValues = await this.spreadsheetRepository.getSheet(
178
+ spreadsheetUrl,
179
+ 'HandleScheduledEvent',
180
+ );
181
+ if (!sheetValues) {
182
+ await this.spreadsheetRepository.updateCell(
183
+ spreadsheetUrl,
184
+ 'HandleScheduledEvent',
185
+ 1,
186
+ 1,
187
+ 'LastExecutionDateTime',
188
+ );
189
+ }
190
+ const lastExecutionDateTime =
191
+ sheetValues && sheetValues[1][2] ? new Date(sheetValues[1][2]) : null;
192
+
193
+ const targetDateTimes: Date[] = lastExecutionDateTime
194
+ ? HandleScheduledEventUseCase.createTargetDateTimes(
195
+ lastExecutionDateTime,
196
+ now,
197
+ )
198
+ : [now];
199
+
200
+ await this.spreadsheetRepository.updateCell(
201
+ spreadsheetUrl,
202
+ 'HandleScheduledEvent',
203
+ 1,
204
+ 2,
205
+ targetDateTimes[targetDateTimes.length - 1].toISOString(),
206
+ );
207
+ return targetDateTimes;
208
+ };
209
+ }
@@ -0,0 +1,46 @@
1
+ import { Issue } from '../entities/Issue';
2
+ import { IssueRepository } from './adapter-interfaces/IssueRepository';
3
+ import { Project } from '../entities/Project';
4
+
5
+ export class SetWorkflowManagementIssueToStoryUseCase {
6
+ constructor(readonly issueRepository: Pick<IssueRepository, 'updateStory'>) {}
7
+
8
+ run = async (input: {
9
+ targetDates: Date[];
10
+ project: Project;
11
+ issues: Issue[];
12
+ cacheUsed: boolean;
13
+ }): Promise<void> => {
14
+ const story = input.project.story;
15
+ if (
16
+ !story ||
17
+ input.cacheUsed ||
18
+ !input.targetDates.find((targetDate) => targetDate.getMinutes() === 0)
19
+ ) {
20
+ return;
21
+ }
22
+ const isTargetIssue = (issue: Issue): boolean => {
23
+ return (
24
+ (issue.labels.includes('story:workflow-management') ||
25
+ issue.labels.includes('daily-routine') ||
26
+ issue.isPr) &&
27
+ (issue.nextActionDate === null ||
28
+ issue.nextActionDate.getTime() <= input.targetDates[0].getTime()) &&
29
+ issue.nextActionHour === null &&
30
+ issue.state === 'OPEN' &&
31
+ issue.story === null
32
+ );
33
+ };
34
+ for (const issue of input.issues) {
35
+ if (!isTargetIssue(issue)) {
36
+ continue;
37
+ }
38
+ await this.issueRepository.updateStory(
39
+ { ...input.project, story },
40
+ issue,
41
+ story.workflowManagementStory.id,
42
+ );
43
+ await new Promise((resolve) => setTimeout(resolve, 5000));
44
+ }
45
+ };
46
+ }
@@ -0,0 +1,5 @@
1
+ export interface DateRepository {
2
+ now(): Promise<Date>;
3
+ formatDurationToHHMM(durationMinutes: number): string;
4
+ formatDateTimeWithDayOfWeek(date: Date): string;
5
+ }
@@ -0,0 +1,44 @@
1
+ import { Issue, Label } from '../../entities/Issue';
2
+ import { Project } from '../../entities/Project';
3
+ import { Member } from '../../entities/Member';
4
+
5
+ export interface IssueRepository {
6
+ getAllIssues: (
7
+ projectId: Project['id'],
8
+ allowCacheMinutes: number,
9
+ ) => Promise<{ issues: Issue[]; cacheUsed: boolean }>;
10
+ getIssueByUrl: (url: string) => Promise<Issue | null>;
11
+ createNewIssue: (
12
+ org: string,
13
+ repo: string,
14
+ title: string,
15
+ body: string,
16
+ assignees: Member['name'][],
17
+ labels: Label[],
18
+ ) => Promise<void>;
19
+ updateIssue: (issue: Issue) => Promise<void>;
20
+ updateNextActionDate: (
21
+ project: Project & {
22
+ nextActionDate: NonNullable<Project['nextActionDate']>;
23
+ },
24
+ issue: Issue,
25
+ date: Date,
26
+ ) => Promise<void>;
27
+ updateNextActionHour: (
28
+ project: Project & {
29
+ nextActionHour: NonNullable<Project['nextActionHour']>;
30
+ },
31
+ issue: Issue,
32
+ hour: number,
33
+ ) => Promise<void>;
34
+ updateStory: (
35
+ project: Project & { story: NonNullable<Project['story']> },
36
+ issue: Issue,
37
+ storyId: string,
38
+ ) => Promise<void>;
39
+ clearProjectField: (
40
+ project: Project,
41
+ fieldId: string,
42
+ issue: Issue,
43
+ ) => Promise<void>;
44
+ }
@@ -0,0 +1,6 @@
1
+ import { Project } from '../../entities/Project';
2
+
3
+ export interface ProjectRepository {
4
+ findProjectIdByUrl: (projectUrl: string) => Promise<Project['id'] | null>;
5
+ getProject: (projectId: Project['id']) => Promise<Project | null>;
6
+ }
@@ -0,0 +1,20 @@
1
+ export interface SlackRepository {
2
+ postMessageToChannel: (
3
+ message: string,
4
+ channelName: string,
5
+ ) => Promise<{ threadTs: string }>;
6
+ postMessageToChannelThread: (
7
+ message: string,
8
+ channelName: string,
9
+ threadTs: string,
10
+ ) => Promise<void>;
11
+ postMessageToChannelWithImage: (
12
+ message: string,
13
+ channelName: string,
14
+ imageFilePath: string,
15
+ ) => Promise<void>;
16
+ postMessageToDirectMessage: (
17
+ message: string,
18
+ userName: string,
19
+ ) => Promise<void>;
20
+ }
@@ -0,0 +1,18 @@
1
+ export interface SpreadsheetRepository {
2
+ getSheet: (
3
+ spreadsheetUrl: string,
4
+ sheetName: string,
5
+ ) => Promise<string[][] | null>;
6
+ updateCell: (
7
+ spreadsheetUrl: string,
8
+ sheetName: string,
9
+ row: number,
10
+ column: number,
11
+ value: string,
12
+ ) => Promise<void>;
13
+ appendSheetValues: (
14
+ spreadsheetUrl: string,
15
+ sheetName: string,
16
+ values: string[][],
17
+ ) => Promise<void>;
18
+ }
@@ -0,0 +1,8 @@
1
+ import { hello } from './index';
2
+
3
+ describe('index', () => {
4
+ test('hello', async () => {
5
+ const res = hello('test');
6
+ expect(res).toEqual('hello test');
7
+ });
8
+ });
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ import dotenv from 'dotenv';
2
+ import { HandleScheduledEventUseCaseHandler } from './adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler';
3
+ dotenv.config();
4
+ export const hello = (name: string) => `hello ${name}`;
5
+ export { Project } from './domain/entities/Project';
6
+ export { Issue } from './domain/entities/Issue';
7
+ export const scheduledEvent = new HandleScheduledEventUseCaseHandler().handle;
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src"],
4
+ "exclude": ["node_modules", "**/__tests__/*", "**/*.test.ts"],
5
+ "compilerOptions": {
6
+ "outDir": "bin",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "declarationDir": "types"
10
+ }
11
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2020",
4
+ "module": "commonjs",
5
+ "moduleResolution": "Node",
6
+ "esModuleInterop": true,
7
+ "outDir": "./dist",
8
+ "sourceMap": true,
9
+ "strict": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "skipLibCheck": true,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "plugins": [
14
+ {
15
+ "transform": "typia/lib/transform"
16
+ }
17
+ ],
18
+ "strictNullChecks": true
19
+ },
20
+ "include": ["src"],
21
+ "exclude": ["node_modules", "**/__tests__/*"]
22
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { Issue } from '../../../domain/entities/Issue';
2
+ import { Project } from '../../../domain/entities/Project';
3
+ export declare class HandleScheduledEventUseCaseHandler {
4
+ handle: (configFilePath: string) => Promise<{
5
+ project: Project;
6
+ issues: Issue[];
7
+ cacheUsed: boolean;
8
+ targetDateTimes: Date[];
9
+ }>;
10
+ }
11
+ //# sourceMappingURL=HandleScheduledEventUseCaseHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D,qBAAa,kCAAkC;IAC7C,MAAM,mBACY,MAAM,KACrB,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,CAAC,CA8DA;CACH"}
@@ -0,0 +1,13 @@
1
+ import { SlackRepository } from '../../domain/usecases/adapter-interfaces/SlackRepository';
2
+ export declare class AxiosSlackRepository implements SlackRepository {
3
+ private readonly client;
4
+ private readonly baseUrl;
5
+ constructor(userToken: string);
6
+ postMessageToChannel(message: string, channelName: string): Promise<{
7
+ threadTs: string;
8
+ }>;
9
+ postMessageToChannelThread(message: string, channelName: string, threadTs: string): Promise<void>;
10
+ postMessageToDirectMessage(message: string, userName: string): Promise<void>;
11
+ postMessageToChannelWithImage(message: string, channelName: string, imageFilePath: string): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=AxiosSlackRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AxiosSlackRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/AxiosSlackRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAE3F,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;gBAEvC,SAAS,EAAE,MAAM;IAYvB,oBAAoB,CACxB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IAwBI,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmBV,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAiBV,6BAA6B,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC;CAuFjB"}
@@ -0,0 +1,32 @@
1
+ interface Cookie {
2
+ name: string;
3
+ value: string;
4
+ domain?: string;
5
+ path?: string;
6
+ expires?: number;
7
+ httpOnly?: boolean;
8
+ secure?: boolean;
9
+ sameSite?: 'lax' | 'strict' | 'none';
10
+ }
11
+ export declare class BaseGitHubRepository {
12
+ readonly jsonFilePath: string;
13
+ readonly ghToken: string;
14
+ readonly ghUserName: string | undefined;
15
+ readonly ghUserPassword: string | undefined;
16
+ readonly ghAuthenticatorKey: string | undefined;
17
+ cookie: string | null;
18
+ constructor(jsonFilePath?: string, ghToken?: string, ghUserName?: string | undefined, ghUserPassword?: string | undefined, ghAuthenticatorKey?: string | undefined);
19
+ protected extractIssueFromUrl: (issueUrl: string) => {
20
+ owner: string;
21
+ repo: string;
22
+ issueNumber: number;
23
+ isIssue: boolean;
24
+ };
25
+ getCookie: () => Promise<string>;
26
+ createHeader: () => Promise<object>;
27
+ protected createCookieStringFromFile: () => Promise<string>;
28
+ protected isCookie: (cookie: object) => cookie is Cookie;
29
+ protected generateCookieHeaderFromJson: (cookieData: unknown) => Promise<string>;
30
+ }
31
+ export {};
32
+ //# sourceMappingURL=BaseGitHubRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseGitHubRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/BaseGitHubRepository.ts"],"names":[],"mappings":"AAgBA,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,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;IANjD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;gBAEX,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,aACjB,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,CAwBtC;IACF,SAAS,CAAC,0BAA0B,QAAa,OAAO,CAAC,MAAM,CAAC,CAqB9D;IACF,SAAS,CAAC,QAAQ,WAAY,MAAM,KAAG,MAAM,IAAI,MAAM,CAoBrD;IAEF,SAAS,CAAC,4BAA4B,eACxB,OAAO,KAClB,OAAO,CAAC,MAAM,CAAC,CAmChB;CACH"}
@@ -0,0 +1,13 @@
1
+ import { SpreadsheetRepository } from '../../domain/usecases/adapter-interfaces/SpreadsheetRepository';
2
+ import { LocalStorageRepository } from './LocalStorageRepository';
3
+ export declare class GoogleSpreadsheetRepository implements SpreadsheetRepository {
4
+ readonly localStorageRepository: LocalStorageRepository;
5
+ keyFile: string;
6
+ constructor(localStorageRepository: LocalStorageRepository, serviceAccountKey?: string);
7
+ getSpreadsheetId: (spreadsheetUrl: string) => string;
8
+ getSheet: (spreadsheetUrl: string, sheetName: string) => Promise<string[][] | null>;
9
+ updateCell: (spreadsheetUrl: string, sheetName: string, row: number, column: number, value: string) => Promise<void>;
10
+ createNewSheetIfNotExists: (spreadsheetUrl: string, sheetName: string) => Promise<void>;
11
+ appendSheetValues: (spreadsheetUrl: string, sheetName: string, values: string[][]) => Promise<void>;
12
+ }
13
+ //# sourceMappingURL=GoogleSpreadsheetRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleSpreadsheetRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/GoogleSpreadsheetRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;AAEvG,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,qBAAa,2BAA4B,YAAW,qBAAqB;IAIrE,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB;IAHzD,OAAO,SAAoC;gBAGhC,sBAAsB,EAAE,sBAAsB,EACvD,iBAAiB,GAAE,MACV;IAKX,gBAAgB,mBAAoB,MAAM,KAAG,MAAM,CAGjD;IACF,QAAQ,mBACU,MAAM,aACX,MAAM,KAChB,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,CAkC3B;IACF,UAAU,mBACQ,MAAM,aACX,MAAM,OACZ,MAAM,UACH,MAAM,SACP,MAAM,KACZ,OAAO,CAAC,IAAI,CAAC,CAqBd;IACF,yBAAyB,mBACP,MAAM,aACX,MAAM,KAChB,OAAO,CAAC,IAAI,CAAC,CA8Bd;IAEF,iBAAiB,mBACC,MAAM,aACX,MAAM,UACT,MAAM,EAAE,EAAE,KACjB,OAAO,CAAC,IAAI,CAAC,CAuBd;CACH"}
@@ -0,0 +1,13 @@
1
+ import { BaseGitHubRepository } from './BaseGitHubRepository';
2
+ import { ProjectRepository } from '../../domain/usecases/adapter-interfaces/ProjectRepository';
3
+ import { Project } from '../../domain/entities/Project';
4
+ export declare class GraphqlProjectRepository extends BaseGitHubRepository implements ProjectRepository {
5
+ extractProjectFromUrl: (projectUrl: string) => {
6
+ owner: string;
7
+ projectNumber: number;
8
+ };
9
+ fetchProjectId: (login: string, projectNumber: number) => Promise<string>;
10
+ findProjectIdByUrl: (projectUrl: string) => Promise<Project["id"] | null>;
11
+ getProject: (projectId: Project["id"]) => Promise<Project | null>;
12
+ }
13
+ //# sourceMappingURL=GraphqlProjectRepository.d.ts.map
@@ -0,0 +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;AAGxD,qBAAa,wBACX,SAAQ,oBACR,YAAW,iBAAiB;IAE5B,qBAAqB,eACP,MAAM,KACjB;QACD,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;KACvB,CAMC;IACF,cAAc,UACL,MAAM,iBACE,MAAM,KACpB,OAAO,CAAC,MAAM,CAAC,CAkDhB;IACF,kBAAkB,eACJ,MAAM,KACjB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAG9B;IACF,UAAU,cAAqB,OAAO,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAwJpE;CACH"}
@@ -0,0 +1,12 @@
1
+ import { LocalStorageRepository } from './LocalStorageRepository';
2
+ export declare class LocalStorageCacheRepository {
3
+ readonly localStorageRepository: LocalStorageRepository;
4
+ readonly cachePath: string;
5
+ constructor(localStorageRepository: LocalStorageRepository, cachePath?: string);
6
+ getLatest: (key: string) => Promise<{
7
+ value: object;
8
+ timestamp: Date;
9
+ } | null>;
10
+ set: <T>(key: string, value: T) => Promise<void>;
11
+ }
12
+ //# sourceMappingURL=LocalStorageCacheRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalStorageCacheRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/LocalStorageCacheRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,qBAAa,2BAA2B;IAEpC,QAAQ,CAAC,sBAAsB,EAAE,sBAAsB;IACvD,QAAQ,CAAC,SAAS;gBADT,sBAAsB,EAAE,sBAAsB,EAC9C,SAAS,SAAgB;IAGpC,SAAS,QACF,MAAM,KACV,OAAO,CAAC;QACT,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,IAAI,CAAC;KACjB,GAAG,IAAI,CAAC,CA6BP;IACF,GAAG,GAAU,CAAC,OAAO,MAAM,SAAS,CAAC,KAAG,OAAO,CAAC,IAAI,CAAC,CAQnD;CACH"}
@@ -0,0 +1,7 @@
1
+ export declare class LocalStorageRepository {
2
+ write: (path: string, value: string) => void;
3
+ read: (path: string) => string | null;
4
+ listFiles: (dirPath: string) => string[];
5
+ mkdir: (dirPath: string) => void;
6
+ }
7
+ //# sourceMappingURL=LocalStorageRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalStorageRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/LocalStorageRepository.ts"],"names":[],"mappings":"AAEA,qBAAa,sBAAsB;IACjC,KAAK,SAAU,MAAM,SAAS,MAAM,UAIlC;IACF,IAAI,SAAU,MAAM,KAAG,MAAM,GAAG,IAAI,CAElC;IACF,SAAS,YAAa,MAAM,KAAG,MAAM,EAAE,CAKrC;IACF,KAAK,YAAa,MAAM,UAEtB;CACH"}
@@ -0,0 +1,7 @@
1
+ import { DateRepository } from '../../domain/usecases/adapter-interfaces/DateRepository';
2
+ export declare class SystemDateRepository implements DateRepository {
3
+ now: () => Promise<Date>;
4
+ formatDurationToHHMM: (durationMinutes: number) => string;
5
+ formatDateTimeWithDayOfWeek: (date: Date) => string;
6
+ }
7
+ //# sourceMappingURL=SystemDateRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SystemDateRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/SystemDateRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAEzF,qBAAa,oBAAqB,YAAW,cAAc;IACzD,GAAG,sBAA0B;IAC7B,oBAAoB,oBAAqB,MAAM,KAAG,MAAM,CAItD;IACF,2BAA2B,SAAU,IAAI,KAAG,MAAM,CAShD;CACH"}