github-issue-tower-defence-management 1.121.0 → 1.122.1

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 (31) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +6 -2
  3. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +7 -2
  4. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  5. package/bin/adapter/entry-points/handlers/inTmuxByHumanDataWriter.js +2 -1
  6. package/bin/adapter/entry-points/handlers/inTmuxByHumanDataWriter.js.map +1 -1
  7. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +14 -7
  8. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -1
  9. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +297 -137
  10. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -1
  11. package/bin/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.js +2 -2
  12. package/bin/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.js.map +1 -1
  13. package/package.json +1 -1
  14. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +2 -0
  15. package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.test.ts +11 -0
  16. package/src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.ts +3 -0
  17. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +175 -7
  18. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +22 -8
  19. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +294 -0
  20. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +400 -165
  21. package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.test.ts +11 -0
  22. package/src/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.ts +3 -1
  23. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  24. package/types/adapter/entry-points/handlers/inTmuxByHumanDataWriter.d.ts +1 -0
  25. package/types/adapter/entry-points/handlers/inTmuxByHumanDataWriter.d.ts.map +1 -1
  26. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +3 -2
  27. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -1
  28. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts +10 -0
  29. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -1
  30. package/types/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.d.ts +1 -0
  31. package/types/domain/usecases/intmux/GenerateInTmuxByHumanDataUseCase.d.ts.map +1 -1
@@ -21,8 +21,145 @@ export type ProjectItem = {
21
21
  value: string | null;
22
22
  }[];
23
23
  };
24
+ export type ProjectItemLight = {
25
+ id: string;
26
+ updatedAt: string;
27
+ url: string;
28
+ number: number;
29
+ };
30
+ type ProjectV2ItemFieldValueNode = {
31
+ text?: string;
32
+ number?: number;
33
+ date?: string;
34
+ name?: string;
35
+ field: {
36
+ name: string;
37
+ };
38
+ };
39
+ type ProjectV2ItemContentNode = {
40
+ repository: { nameWithOwner: string };
41
+ number: number;
42
+ title: string;
43
+ state: string;
44
+ url: string;
45
+ createdAt: string;
46
+ updatedAt: string;
47
+ author: { login: string } | null;
48
+ labels: { nodes: { name: string }[] };
49
+ assignees: { nodes: { login: string }[] };
50
+ closingIssuesReferences?: { nodes: { url: string }[] };
51
+ };
52
+ type ProjectV2ItemNode = {
53
+ id: string;
54
+ fieldValues: {
55
+ nodes: ProjectV2ItemFieldValueNode[];
56
+ };
57
+ content: ProjectV2ItemContentNode;
58
+ };
59
+ const PROJECT_V2_ITEM_FIELD_VALUES_AND_CONTENT_SELECTION = `
60
+ fieldValues(first: 10) {
61
+ nodes {
62
+ ... on ProjectV2ItemFieldTextValue {
63
+ text
64
+ field {
65
+ ... on ProjectV2Field{
66
+ name
67
+ }
68
+ }
69
+ }
70
+ ... on ProjectV2ItemFieldNumberValue {
71
+ number
72
+ id
73
+ field {
74
+ ... on ProjectV2Field{
75
+ name
76
+ }
77
+ }
78
+ }
79
+ ... on ProjectV2ItemFieldDateValue {
80
+ date
81
+ field {
82
+ ... on ProjectV2Field{
83
+ name
84
+ }
85
+ }
86
+ }
87
+ ... on ProjectV2ItemFieldSingleSelectValue {
88
+ name
89
+ field {
90
+ ... on ProjectV2SingleSelectField {
91
+ name
92
+ }
93
+ }
94
+ }
95
+ ... on ProjectV2ItemFieldIterationValue {
96
+ title
97
+ field {
98
+ ... on ProjectV2Field{
99
+ name
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ content {
106
+ ... on Issue {
107
+ number
108
+ title
109
+ state
110
+ url
111
+ createdAt
112
+ updatedAt
113
+ author {
114
+ login
115
+ }
116
+ labels(first: 100) {
117
+ nodes {
118
+ name
119
+ }
120
+ }
121
+ assignees(first: 20) {
122
+ nodes {
123
+ login
124
+ }
125
+ }
126
+ repository {
127
+ nameWithOwner
128
+ }
129
+ }
130
+ ... on PullRequest {
131
+ number
132
+ title
133
+ state
134
+ url
135
+ createdAt
136
+ updatedAt
137
+ author {
138
+ login
139
+ }
140
+ labels(first: 100) {
141
+ nodes {
142
+ name
143
+ }
144
+ }
145
+ assignees(first: 20) {
146
+ nodes {
147
+ login
148
+ }
149
+ }
150
+ repository {
151
+ nameWithOwner
152
+ }
153
+ closingIssuesReferences(first: 50) {
154
+ nodes {
155
+ url
156
+ }
157
+ }
158
+ }
159
+ }`;
24
160
  export const PAGINATION_DELAY_MS = 5000;
25
161
  export const FETCH_PROJECT_ITEMS_INITIAL_PAGE_SIZE = 100;
162
+ export const FETCH_PROJECT_ITEMS_BY_IDS_BATCH_SIZE = 100;
26
163
  export const FETCH_PROJECT_ITEMS_GRAPHQL_ERROR_PAYLOAD_MAX_LENGTH = 4000;
27
164
  export const RATE_LIMIT_MAX_RETRIES = 6;
28
165
  export const RATE_LIMIT_MIN_BACKOFF_MS = 1000;
@@ -212,107 +349,7 @@ query GetProjectItems($projectId: ID!, $after: String, $first: Int!, $query: Str
212
349
  hasNextPage
213
350
  }
214
351
  nodes {
215
- id
216
- fieldValues(first: 10) {
217
- nodes {
218
- ... on ProjectV2ItemFieldTextValue {
219
- text
220
- field {
221
- ... on ProjectV2Field{
222
- name
223
- }
224
- }
225
- }
226
- ... on ProjectV2ItemFieldNumberValue {
227
- number
228
- id
229
- field {
230
- ... on ProjectV2Field{
231
- name
232
- }
233
- }
234
- }
235
- ... on ProjectV2ItemFieldDateValue {
236
- date
237
- field {
238
- ... on ProjectV2Field{
239
- name
240
- }
241
- }
242
- }
243
- ... on ProjectV2ItemFieldSingleSelectValue {
244
- name
245
- field {
246
- ... on ProjectV2SingleSelectField {
247
- name
248
- }
249
- }
250
- }
251
- ... on ProjectV2ItemFieldIterationValue {
252
- title
253
- field {
254
- ... on ProjectV2Field{
255
- name
256
- }
257
- }
258
- }
259
- }
260
- }
261
- content {
262
- ... on Issue {
263
- number
264
- title
265
- state
266
- url
267
- createdAt
268
- updatedAt
269
- author {
270
- login
271
- }
272
- labels(first: 100) {
273
- nodes {
274
- name
275
- }
276
- }
277
- assignees(first: 20) {
278
- nodes {
279
- login
280
- }
281
- }
282
- repository {
283
- nameWithOwner
284
- }
285
- }
286
- ... on PullRequest {
287
- number
288
- title
289
- state
290
- url
291
- createdAt
292
- updatedAt
293
- author {
294
- login
295
- }
296
- labels(first: 100) {
297
- nodes {
298
- name
299
- }
300
- }
301
- assignees(first: 20) {
302
- nodes {
303
- login
304
- }
305
- }
306
- repository {
307
- nameWithOwner
308
- }
309
- closingIssuesReferences(first: 50) {
310
- nodes {
311
- url
312
- }
313
- }
314
- }
315
- }
352
+ id${PROJECT_V2_ITEM_FIELD_VALUES_AND_CONTENT_SELECTION}
316
353
  }
317
354
  }
318
355
  }
@@ -524,71 +561,12 @@ query GetProjectItems($projectId: ID!, $after: String, $first: Int!, $query: Str
524
561
  console.log(
525
562
  `fetchProjectItems: page ${pageIndex}, nodes: ${pageNodes.length}, cumulative: ${cumulativeRawNodes}/${totalCount}`,
526
563
  );
527
- const projectItems: {
528
- id: string;
529
- fieldValues: {
530
- nodes: {
531
- text?: string;
532
- number?: number;
533
- date?: string;
534
- name?: string;
535
- field: {
536
- name: string;
537
- };
538
- }[];
539
- };
540
- content: {
541
- repository: { nameWithOwner: string };
542
- number: number;
543
- title: string;
544
- state: string;
545
- url: string;
546
- createdAt: string;
547
- updatedAt: string;
548
- author: { login: string } | null;
549
- labels: { nodes: { name: string }[] };
550
- assignees: { nodes: { login: string }[] };
551
- closingIssuesReferences?: { nodes: { url: string }[] };
552
- };
553
- }[] = pageNodes;
554
- projectItems.forEach((item) => {
555
- if (!item || !item.content || !item.content.repository) {
556
- return;
564
+ const nodes: ProjectV2ItemNode[] = pageNodes;
565
+ nodes.forEach((item) => {
566
+ const projectItem = this.mapProjectV2ItemNodeToProjectItem(item);
567
+ if (projectItem) {
568
+ issues.push(projectItem);
557
569
  }
558
- issues.push({
559
- id: item.id,
560
- nameWithOwner: item.content.repository.nameWithOwner,
561
- number: item.content.number,
562
- title: item.content.title,
563
- state: this.convertStrToState(item.content.state),
564
- url: item.content.url,
565
- body: null,
566
- labels: item.content.labels?.nodes?.map((l) => l.name) || [],
567
- assignees: item.content.assignees?.nodes?.map((a) => a.login) || [],
568
- createdAt: item.content.createdAt || new Date().toISOString(),
569
- updatedAt:
570
- item.content.updatedAt ||
571
- item.content.createdAt ||
572
- new Date().toISOString(),
573
- author: item.content.author?.login || '',
574
- closingIssueReferenceUrls:
575
- item.content.closingIssuesReferences?.nodes
576
- ?.map((node) => node.url)
577
- .filter((url) => url.length > 0) || [],
578
- customFields: item.fieldValues.nodes
579
- .filter((field) => !!field.field)
580
- .map((field) => {
581
- return {
582
- name: field.field.name,
583
- value:
584
- field.name ??
585
- field.text ??
586
- field.number?.toString() ??
587
- field.date ??
588
- null,
589
- };
590
- }),
591
- });
592
570
  });
593
571
  if (
594
572
  pageNodes.length > 0 &&
@@ -612,6 +590,263 @@ query GetProjectItems($projectId: ID!, $after: String, $first: Int!, $query: Str
612
590
  }
613
591
  return issues;
614
592
  };
593
+ private mapProjectV2ItemNodeToProjectItem = (
594
+ item: ProjectV2ItemNode | null,
595
+ ): ProjectItem | null => {
596
+ if (!item || !item.content || !item.content.repository) {
597
+ return null;
598
+ }
599
+ return {
600
+ id: item.id,
601
+ nameWithOwner: item.content.repository.nameWithOwner,
602
+ number: item.content.number,
603
+ title: item.content.title,
604
+ state: this.convertStrToState(item.content.state),
605
+ url: item.content.url,
606
+ body: null,
607
+ labels: item.content.labels?.nodes?.map((l) => l.name) || [],
608
+ assignees: item.content.assignees?.nodes?.map((a) => a.login) || [],
609
+ createdAt: item.content.createdAt || new Date().toISOString(),
610
+ updatedAt:
611
+ item.content.updatedAt ||
612
+ item.content.createdAt ||
613
+ new Date().toISOString(),
614
+ author: item.content.author?.login || '',
615
+ closingIssueReferenceUrls:
616
+ item.content.closingIssuesReferences?.nodes
617
+ ?.map((node) => node.url)
618
+ .filter((url) => url.length > 0) || [],
619
+ customFields: item.fieldValues.nodes
620
+ .filter((field) => !!field.field)
621
+ .map((field) => {
622
+ return {
623
+ name: field.field.name,
624
+ value:
625
+ field.name ??
626
+ field.text ??
627
+ field.number?.toString() ??
628
+ field.date ??
629
+ null,
630
+ };
631
+ }),
632
+ };
633
+ };
634
+ fetchProjectItemsLight = async (
635
+ projectId: string,
636
+ query?: string,
637
+ ): Promise<ProjectItemLight[]> => {
638
+ const graphqlQueryString = `
639
+ query GetProjectItemsLight($projectId: ID!, $after: String, $first: Int!, $query: String) {
640
+ node(id: $projectId) {
641
+ ... on ProjectV2 {
642
+ items(first: $first, after: $after, query: $query) {
643
+ totalCount
644
+ pageInfo {
645
+ endCursor
646
+ hasNextPage
647
+ }
648
+ nodes {
649
+ id
650
+ updatedAt
651
+ content {
652
+ ... on Issue {
653
+ url
654
+ number
655
+ }
656
+ ... on PullRequest {
657
+ url
658
+ number
659
+ }
660
+ }
661
+ }
662
+ }
663
+ }
664
+ }
665
+ }
666
+ `;
667
+ const callGraphql = async (
668
+ after: string | null,
669
+ ): Promise<{
670
+ totalCount: number;
671
+ pageInfo: { endCursor: string; hasNextPage: boolean };
672
+ nodes: {
673
+ id: string;
674
+ updatedAt: string;
675
+ content: { url: string; number: number } | null;
676
+ }[];
677
+ }> => {
678
+ const response = await callWithRateLimitRetry(() =>
679
+ ky
680
+ .post('https://api.github.com/graphql', {
681
+ json: {
682
+ query: graphqlQueryString,
683
+ variables: {
684
+ projectId: projectId,
685
+ after: after,
686
+ first: FETCH_PROJECT_ITEMS_INITIAL_PAGE_SIZE,
687
+ query: query ?? null,
688
+ },
689
+ },
690
+ headers: {
691
+ Authorization: `Bearer ${this.ghToken}`,
692
+ },
693
+ })
694
+ .json<{
695
+ data: {
696
+ node: {
697
+ items: {
698
+ totalCount: number;
699
+ pageInfo: { endCursor: string; hasNextPage: boolean };
700
+ nodes: {
701
+ id: string;
702
+ updatedAt: string;
703
+ content: { url: string; number: number } | null;
704
+ }[];
705
+ };
706
+ } | null;
707
+ } | null;
708
+ errors?: { message: string }[];
709
+ }>(),
710
+ );
711
+ if (response.errors && response.errors.length > 0) {
712
+ throw new Error(
713
+ `GitHub GraphQL errors: ${stringifyGraphqlErrorsForLog(response.errors)}`,
714
+ );
715
+ }
716
+ const rawData = response.data;
717
+ if (!rawData || rawData.node === null) {
718
+ throw new Error('No data returned from GitHub API');
719
+ }
720
+ return rawData.node.items;
721
+ };
722
+ const lightItems: ProjectItemLight[] = [];
723
+ let after: string | null = null;
724
+ let hasNextPage = true;
725
+ let totalCount = 0;
726
+ let cumulativeRawNodes = 0;
727
+ let pageIndex = 0;
728
+ while (hasNextPage) {
729
+ if (after !== null) {
730
+ await new Promise((resolve) =>
731
+ setTimeout(resolve, PAGINATION_DELAY_MS),
732
+ );
733
+ }
734
+ const items = await callGraphql(after);
735
+ const pageNodes = items.nodes;
736
+ const pageInfo = items.pageInfo;
737
+ totalCount = items.totalCount;
738
+ cumulativeRawNodes += pageNodes.length;
739
+ pageIndex++;
740
+ console.log(
741
+ `fetchProjectItemsLight: page ${pageIndex}, nodes: ${pageNodes.length}, cumulative: ${cumulativeRawNodes}/${totalCount}`,
742
+ );
743
+ pageNodes.forEach((node) => {
744
+ if (!node || !node.content || !node.content.url) {
745
+ return;
746
+ }
747
+ lightItems.push({
748
+ id: node.id,
749
+ updatedAt: node.updatedAt,
750
+ url: node.content.url,
751
+ number: node.content.number,
752
+ });
753
+ });
754
+ if (
755
+ pageNodes.length > 0 &&
756
+ !pageInfo.hasNextPage &&
757
+ cumulativeRawNodes < totalCount
758
+ ) {
759
+ throw new Error(
760
+ `fetchProjectItemsLight: page ${pageIndex} has ${pageNodes.length} nodes with hasNextPage=false but only ${cumulativeRawNodes}/${totalCount} items accumulated`,
761
+ );
762
+ }
763
+ hasNextPage = pageInfo.hasNextPage;
764
+ after = pageInfo.endCursor;
765
+ }
766
+ console.log(
767
+ `fetchProjectItemsLight: completed, totalCount: ${totalCount}, cumulativeRawNodes: ${cumulativeRawNodes}, items: ${lightItems.length}`,
768
+ );
769
+ if (cumulativeRawNodes !== totalCount) {
770
+ throw new Error(
771
+ `fetchProjectItemsLight: expected ${totalCount} items but accumulated ${cumulativeRawNodes}`,
772
+ );
773
+ }
774
+ return lightItems;
775
+ };
776
+ fetchProjectItemsByIds = async (ids: string[]): Promise<ProjectItem[]> => {
777
+ if (ids.length === 0) {
778
+ return [];
779
+ }
780
+ const graphqlQueryString = `
781
+ query GetProjectItemsByIds($ids: [ID!]!) {
782
+ nodes(ids: $ids) {
783
+ ... on ProjectV2Item {
784
+ id${PROJECT_V2_ITEM_FIELD_VALUES_AND_CONTENT_SELECTION}
785
+ }
786
+ }
787
+ }
788
+ `;
789
+ const callGraphql = async (
790
+ batchIds: string[],
791
+ ): Promise<(ProjectV2ItemNode | null)[]> => {
792
+ const response = await callWithRateLimitRetry(() =>
793
+ ky
794
+ .post('https://api.github.com/graphql', {
795
+ json: {
796
+ query: graphqlQueryString,
797
+ variables: {
798
+ ids: batchIds,
799
+ },
800
+ },
801
+ headers: {
802
+ Authorization: `Bearer ${this.ghToken}`,
803
+ },
804
+ })
805
+ .json<{
806
+ data: { nodes: (ProjectV2ItemNode | null)[] } | null;
807
+ errors?: { message: string }[];
808
+ }>(),
809
+ );
810
+ if (response.errors && response.errors.length > 0) {
811
+ throw new Error(
812
+ `GitHub GraphQL errors: ${stringifyGraphqlErrorsForLog(response.errors)}`,
813
+ );
814
+ }
815
+ if (!response.data) {
816
+ throw new Error('No data returned from GitHub API');
817
+ }
818
+ return response.data.nodes;
819
+ };
820
+ const items: ProjectItem[] = [];
821
+ let batchIndex = 0;
822
+ for (
823
+ let start = 0;
824
+ start < ids.length;
825
+ start += FETCH_PROJECT_ITEMS_BY_IDS_BATCH_SIZE
826
+ ) {
827
+ if (start > 0) {
828
+ await new Promise((resolve) =>
829
+ setTimeout(resolve, PAGINATION_DELAY_MS),
830
+ );
831
+ }
832
+ const batchIds = ids.slice(
833
+ start,
834
+ start + FETCH_PROJECT_ITEMS_BY_IDS_BATCH_SIZE,
835
+ );
836
+ const nodes = await callGraphql(batchIds);
837
+ batchIndex++;
838
+ console.log(
839
+ `fetchProjectItemsByIds: batch ${batchIndex}, ids: ${batchIds.length}, nodes: ${nodes.length}`,
840
+ );
841
+ nodes.forEach((node) => {
842
+ const projectItem = this.mapProjectV2ItemNodeToProjectItem(node);
843
+ if (projectItem) {
844
+ items.push(projectItem);
845
+ }
846
+ });
847
+ }
848
+ return items;
849
+ };
615
850
  getProjectItemFieldsFromIssueUrl = async (
616
851
  issueUrl: string,
617
852
  ): Promise<
@@ -97,6 +97,7 @@ describe('GenerateInTmuxByHumanDataUseCase', () => {
97
97
  project?: Project;
98
98
  consoleBaseUrl?: string | null;
99
99
  consoleToken?: string | null;
100
+ newIssueRepo?: string;
100
101
  } = {},
101
102
  ) =>
102
103
  usecase.run({
@@ -106,6 +107,7 @@ describe('GenerateInTmuxByHumanDataUseCase', () => {
106
107
  assigneeLogin: ASSIGNEE,
107
108
  org: 'demo-org',
108
109
  repo: 'demo-repo',
110
+ newIssueRepo: overrides.newIssueRepo,
109
111
  consoleBaseUrl:
110
112
  overrides.consoleBaseUrl === undefined
111
113
  ? CONSOLE_BASE_URL
@@ -292,6 +294,15 @@ describe('GenerateInTmuxByHumanDataUseCase', () => {
292
294
  });
293
295
  });
294
296
 
297
+ it('overrides only the repo segment of the new issue url with newIssueRepo, leaving org and assignee unchanged', () => {
298
+ const result = run([makeIssue({ story: 'Story Alpha' })], {
299
+ newIssueRepo: 'other-repo',
300
+ });
301
+ expect(result.v4?.newIssueUrl).toBe(
302
+ 'https://github.com/demo-org/other-repo/issues/new?assignees=owner-login',
303
+ );
304
+ });
305
+
295
306
  it('maps each session to the issue url as name and the issue title as description', () => {
296
307
  const result = run([
297
308
  makeIssue({ story: 'Story Alpha' }),
@@ -55,6 +55,7 @@ export type GenerateInTmuxByHumanDataInput = {
55
55
  assigneeLogin: string;
56
56
  org: string;
57
57
  repo: string;
58
+ newIssueRepo?: string;
58
59
  consoleBaseUrl: string | null;
59
60
  consoleToken: string | null;
60
61
  now: Date;
@@ -77,6 +78,7 @@ export class GenerateInTmuxByHumanDataUseCase {
77
78
  assigneeLogin,
78
79
  org,
79
80
  repo,
81
+ newIssueRepo,
80
82
  consoleBaseUrl,
81
83
  consoleToken,
82
84
  } = input;
@@ -132,7 +134,7 @@ export class GenerateInTmuxByHumanDataUseCase {
132
134
  version: 4,
133
135
  overviewUrl,
134
136
  tdpmConsoleUrl: `${tdpmConsoleUrl}?k=${consoleToken}`,
135
- newIssueUrl: `https://github.com/${org}/${repo}/issues/new?assignees=${assigneeLogin}`,
137
+ newIssueUrl: `https://github.com/${org}/${newIssueRepo ?? repo}/issues/new?assignees=${assigneeLogin}`,
136
138
  groups: v4Groups,
137
139
  }
138
140
  : null;
@@ -1 +1 @@
1
- {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAiD3D,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,CAikBP;CACH"}
1
+ {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAiD3D,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,CAmkBP;CACH"}
@@ -9,6 +9,7 @@ export type InTmuxByHumanDataWriterParams = {
9
9
  assigneeLogin: string | null | undefined;
10
10
  org: string;
11
11
  repo: string;
12
+ newIssueRepo?: string | null | undefined;
12
13
  project: Project;
13
14
  issues: Issue[];
14
15
  now: Date;
@@ -1 +1 @@
1
- {"version":3,"file":"inTmuxByHumanDataWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAMhE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,mBAAmB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,oBAAoB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAUF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,6BAA6B,KACpC,IAwEF,CAAC"}
1
+ {"version":3,"file":"inTmuxByHumanDataWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/inTmuxByHumanDataWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAMhE,MAAM,MAAM,6BAA6B,GAAG;IAC1C,mBAAmB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,oBAAoB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAUF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,6BAA6B,KACpC,IA0EF,CAAC"}
@@ -13,6 +13,7 @@ import { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/P
13
13
  import { DateRepository } from '../../../domain/usecases/adapter-interfaces/DateRepository';
14
14
  import { Sleep } from './githubRateLimitRetry';
15
15
  export declare const FULL_ISSUE_FETCH_INTERVAL_MS: number;
16
+ export declare const INCREMENTAL_FETCH_SKEW_BUFFER_MS: number;
16
17
  export type CachedProjectIssues = {
17
18
  lastFetchedAt: string;
18
19
  lastFullFetchAt: string;
@@ -22,14 +23,14 @@ export type CachedProjectIssues = {
22
23
  export declare class ApiV3CheerioRestIssueRepository extends BaseGitHubRepository implements IssueRepository {
23
24
  readonly apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>;
24
25
  readonly restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>;
25
- readonly graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>;
26
+ readonly graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemsLight' | 'fetchProjectItemsByIds' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>;
26
27
  readonly localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getSingle' | 'setSingle'>;
27
28
  readonly projectRepository: Pick<ProjectRepository, 'getProject'>;
28
29
  readonly dateRepository: DateRepository;
29
30
  readonly localStorageRepository: LocalStorageRepository;
30
31
  readonly ghToken: string;
31
32
  readonly sleep: Sleep;
32
- constructor(apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>, restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>, graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>, localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getSingle' | 'setSingle'>, projectRepository: Pick<ProjectRepository, 'getProject'>, dateRepository: DateRepository, localStorageRepository: LocalStorageRepository, ghToken?: string, sleep?: Sleep);
33
+ constructor(apiV3IssueRepository: Pick<ApiV3IssueRepository, 'searchIssue'>, restIssueRepository: Pick<RestIssueRepository, 'createNewIssue' | 'updateIssue' | 'createComment' | 'getIssue' | 'updateLabels' | 'removeLabel' | 'updateAssigneeList'>, graphqlProjectItemRepository: Pick<GraphqlProjectItemRepository, 'fetchProjectItems' | 'fetchProjectItemsLight' | 'fetchProjectItemsByIds' | 'fetchProjectItemByUrl' | 'updateProjectField' | 'clearProjectField' | 'updateProjectTextField' | 'addIssueToProject'>, localStorageCacheRepository: Pick<LocalStorageCacheRepository, 'getSingle' | 'setSingle'>, projectRepository: Pick<ProjectRepository, 'getProject'>, dateRepository: DateRepository, localStorageRepository: LocalStorageRepository, ghToken?: string, sleep?: Sleep);
33
34
  private readonly getAllIssuesRefreshMemo;
34
35
  private fetchWithRateLimitRetry;
35
36
  updateStatus: (project: Project, issue: Issue, statusId: string) => Promise<void>;