@gitkraken/core-gitlens 0.5.108 → 0.5.109

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 (137) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/dist/git/models/issue.d.ts +70 -0
  3. package/dist/git/models/issue.d.ts.map +1 -1
  4. package/dist/git/models/issue.js +17 -0
  5. package/dist/git/models/issue.js.map +1 -1
  6. package/dist/git/utils/issue.utils.d.ts +41 -1
  7. package/dist/git/utils/issue.utils.d.ts.map +1 -1
  8. package/dist/git/utils/issue.utils.js +80 -0
  9. package/dist/git/utils/issue.utils.js.map +1 -1
  10. package/dist/plus/git-github/api/github.d.ts +33 -6
  11. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  12. package/dist/plus/git-github/api/github.js +137 -15
  13. package/dist/plus/git-github/api/github.js.map +1 -1
  14. package/dist/plus/git-github/api/issueSearchQuery.d.ts +49 -5
  15. package/dist/plus/git-github/api/issueSearchQuery.d.ts.map +1 -1
  16. package/dist/plus/git-github/api/issueSearchQuery.js +64 -6
  17. package/dist/plus/git-github/api/issueSearchQuery.js.map +1 -1
  18. package/dist/plus/integrations/collectionMetadata.d.ts +18 -0
  19. package/dist/plus/integrations/collectionMetadata.d.ts.map +1 -1
  20. package/dist/plus/integrations/collectionMetadata.js +24 -0
  21. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  22. package/dist/plus/integrations/integrationService.d.ts +15 -9
  23. package/dist/plus/integrations/integrationService.d.ts.map +1 -1
  24. package/dist/plus/integrations/integrationService.js.map +1 -1
  25. package/dist/plus/integrations/manager.d.ts +40 -26
  26. package/dist/plus/integrations/manager.d.ts.map +1 -1
  27. package/dist/plus/integrations/models/gitHostIntegration.d.ts +6 -31
  28. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
  29. package/dist/plus/integrations/models/gitHostIntegration.js +11 -1
  30. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  31. package/dist/plus/integrations/models/issueReads.d.ts +63 -1
  32. package/dist/plus/integrations/models/issueReads.d.ts.map +1 -1
  33. package/dist/plus/integrations/models/issuesIntegration.d.ts +7 -21
  34. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
  35. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  36. package/dist/plus/integrations/providerFilters.d.ts +1 -1
  37. package/dist/plus/integrations/providerFilters.d.ts.map +1 -1
  38. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -1
  39. package/dist/plus/integrations/providers/azureDevOps.js +1 -0
  40. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  41. package/dist/plus/integrations/providers/github.d.ts.map +1 -1
  42. package/dist/plus/integrations/providers/github.js +1 -0
  43. package/dist/plus/integrations/providers/github.js.map +1 -1
  44. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
  45. package/dist/plus/integrations/providers/gitlab.js +1 -0
  46. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  47. package/dist/plus/integrations/providers/issueSorts.d.ts +36 -0
  48. package/dist/plus/integrations/providers/issueSorts.d.ts.map +1 -0
  49. package/dist/plus/integrations/providers/issueSorts.js +76 -0
  50. package/dist/plus/integrations/providers/issueSorts.js.map +1 -0
  51. package/dist/plus/integrations/providers/jira.d.ts +3 -9
  52. package/dist/plus/integrations/providers/jira.d.ts.map +1 -1
  53. package/dist/plus/integrations/providers/jira.js +5 -1
  54. package/dist/plus/integrations/providers/jira.js.map +1 -1
  55. package/dist/plus/integrations/providers/linear.d.ts +24 -9
  56. package/dist/plus/integrations/providers/linear.d.ts.map +1 -1
  57. package/dist/plus/integrations/providers/linear.js +63 -5
  58. package/dist/plus/integrations/providers/linear.js.map +1 -1
  59. package/dist/plus/integrations/providers/models.d.ts +63 -7
  60. package/dist/plus/integrations/providers/models.d.ts.map +1 -1
  61. package/dist/plus/integrations/providers/models.js +55 -0
  62. package/dist/plus/integrations/providers/models.js.map +1 -1
  63. package/dist/plus/integrations/providers/providersApi.d.ts +18 -3
  64. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -1
  65. package/dist/plus/integrations/providers/providersApi.js +24 -7
  66. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  67. package/dist/plus/integrations/providers/trello.d.ts +3 -9
  68. package/dist/plus/integrations/providers/trello.d.ts.map +1 -1
  69. package/dist/plus/integrations/providers/trello.js +1 -0
  70. package/dist/plus/integrations/providers/trello.js.map +1 -1
  71. package/dist/plus/integrations/providers/utils/providerPaging.d.ts.map +1 -1
  72. package/dist/plus/integrations/providers/utils/providerPaging.js +5 -1
  73. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  74. package/dist/plus/integrations/reads/broaden.d.ts +6 -0
  75. package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
  76. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  77. package/dist/plus/integrations/reads/counts.d.ts +8 -1
  78. package/dist/plus/integrations/reads/counts.d.ts.map +1 -1
  79. package/dist/plus/integrations/reads/counts.js.map +1 -1
  80. package/dist/plus/integrations/reads/filters.d.ts +59 -9
  81. package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
  82. package/dist/plus/integrations/reads/filters.js +17 -0
  83. package/dist/plus/integrations/reads/filters.js.map +1 -1
  84. package/dist/plus/integrations/reads/issueTracker.d.ts +18 -1
  85. package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
  86. package/dist/plus/integrations/reads/issueTracker.js +40 -3
  87. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  88. package/dist/plus/integrations/reads/issues.d.ts +27 -3
  89. package/dist/plus/integrations/reads/issues.d.ts.map +1 -1
  90. package/dist/plus/integrations/reads/issues.js +223 -123
  91. package/dist/plus/integrations/reads/issues.js.map +1 -1
  92. package/dist/plus/integrations/reads/ordering.d.ts +101 -0
  93. package/dist/plus/integrations/reads/ordering.d.ts.map +1 -0
  94. package/dist/plus/integrations/reads/ordering.js +48 -0
  95. package/dist/plus/integrations/reads/ordering.js.map +1 -0
  96. package/dist/plus/integrations/reads/searchIssues.d.ts +7 -2
  97. package/dist/plus/integrations/reads/searchIssues.d.ts.map +1 -1
  98. package/dist/plus/integrations/reads/searchIssues.js +9 -3
  99. package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
  100. package/dist/plus/integrations/reads/warnings.d.ts +34 -2
  101. package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
  102. package/dist/plus/integrations/reads/warnings.js +47 -2
  103. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  104. package/dist/plus/integrations/results.d.ts +10 -0
  105. package/dist/plus/integrations/results.d.ts.map +1 -1
  106. package/dist/plus/integrations/results.js.map +1 -1
  107. package/package.json +2 -2
  108. package/src/git/models/issue.ts +73 -0
  109. package/src/git/utils/issue.utils.ts +91 -1
  110. package/src/plus/git-github/api/github.ts +180 -20
  111. package/src/plus/git-github/api/issueSearchQuery.ts +67 -7
  112. package/src/plus/integrations/collectionMetadata.ts +24 -0
  113. package/src/plus/integrations/integrationService.ts +15 -10
  114. package/src/plus/integrations/manager.ts +40 -31
  115. package/src/plus/integrations/models/gitHostIntegration.ts +18 -31
  116. package/src/plus/integrations/models/issueReads.ts +65 -1
  117. package/src/plus/integrations/models/issuesIntegration.ts +7 -6
  118. package/src/plus/integrations/providerFilters.ts +2 -0
  119. package/src/plus/integrations/providers/azureDevOps.ts +1 -0
  120. package/src/plus/integrations/providers/github.ts +1 -0
  121. package/src/plus/integrations/providers/gitlab.ts +1 -0
  122. package/src/plus/integrations/providers/issueSorts.ts +89 -0
  123. package/src/plus/integrations/providers/jira.ts +9 -3
  124. package/src/plus/integrations/providers/linear.ts +77 -8
  125. package/src/plus/integrations/providers/models.ts +122 -5
  126. package/src/plus/integrations/providers/providersApi.ts +51 -13
  127. package/src/plus/integrations/providers/trello.ts +4 -3
  128. package/src/plus/integrations/providers/utils/providerPaging.ts +6 -1
  129. package/src/plus/integrations/reads/broaden.ts +6 -0
  130. package/src/plus/integrations/reads/counts.ts +8 -1
  131. package/src/plus/integrations/reads/filters.ts +70 -8
  132. package/src/plus/integrations/reads/issueTracker.ts +78 -4
  133. package/src/plus/integrations/reads/issues.ts +386 -194
  134. package/src/plus/integrations/reads/ordering.ts +124 -0
  135. package/src/plus/integrations/reads/searchIssues.ts +15 -3
  136. package/src/plus/integrations/reads/warnings.ts +72 -1
  137. package/src/plus/integrations/results.ts +10 -0
@@ -1,5 +1,5 @@
1
1
  import type { CollectionMetadata } from '@gitkraken/provider-apis';
2
- import type { IssueShape } from '../../../git/models/issue.js';
2
+ import type { IssueShape, IssueSorting } from '../../../git/models/issue.js';
3
3
  import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
4
4
  import { mapBounded } from '../../../utils/promise.js';
5
5
  import { mergeAssessmentInto } from '../collectionMetadata.js';
@@ -15,7 +15,14 @@ import type { ProviderReadContext } from './context.js';
15
15
  import { parseIssueTrackerPageCursor, toIssueTrackerPageCursor } from './cursors.js';
16
16
  import { runCaptured } from './drains.js';
17
17
  import { projectKey, resourceIdForProject, resourceLabel, resourceMatchesOrg } from './hierarchy.utils.js';
18
- import { incompleteReadWarning, issueTrackerOnlySurfaceWarning, otherWarning } from './warnings.js';
18
+ import { resolveIssueSort, toIssueOrdering } from './ordering.js';
19
+ import {
20
+ incompleteReadWarning,
21
+ issueTrackerOnlySurfaceWarning,
22
+ otherWarning,
23
+ unmergeableIssueSortWarning,
24
+ unsupportedIssueSortWarning,
25
+ } from './warnings.js';
19
26
 
20
27
  export async function listIssueTrackerIssuesPage(
21
28
  ctx: ProviderReadContext,
@@ -26,6 +33,23 @@ export async function listIssueTrackerIssuesPage(
26
33
  filters?: IssueFilter[];
27
34
  /** Broadens the read to every assignee. Scopes to user-assigned issues when omitted. */
28
35
  includeAllAssignees?: boolean;
36
+ /**
37
+ * How to order the issues, as `field:direction`. Omitted orders most-recently-updated-first where the
38
+ * tracker can express it.
39
+ *
40
+ * Validated against `getSupportedFilters().issues`' sibling `issueSorts` — a tracker reports there, not
41
+ * under the account-wide table, because resource -> project IS its only issue surface. A key it can't
42
+ * express refuses the read rather than serving a differently-ordered list.
43
+ *
44
+ * One page can span SEVERAL projects, whose issues are merged here, so a key no normalized issue carries
45
+ * (`priority`, `dueDate`, `resolved`) is refused for a multi-project page even though the tracker orders by
46
+ * it perfectly well within one project.
47
+ *
48
+ * Unlike the git-host reads this one is safe to change mid-pagination: its cursor windows PROJECTS and
49
+ * drains each to exhaustion, so which projects a round covers doesn't depend on how their issues are
50
+ * ordered. Only the order within a page changes.
51
+ */
52
+ sort?: IssueSorting;
29
53
  forceSync?: boolean;
30
54
  page?: number;
31
55
  cursor?: string;
@@ -128,6 +152,19 @@ export async function listIssueTrackerIssuesPage(
128
152
 
129
153
  const domain = ctx.domainForRead(integration, options.providerId, options.connectionId);
130
154
 
155
+ // Before any upstream request: the discovery fan-outs below (resources, projects, per-resource accounts) are
156
+ // three round trips, and an order this tracker can't express refuses the read whatever they return. Placed after
157
+ // `domain` only because every warning carries it.
158
+ const resolvedSort = resolveIssueSort(providersMetadata[options.providerId]?.supportedIssueSorts, options.sort);
159
+ if (resolvedSort.rejection != null) {
160
+ warnings.push(
161
+ unsupportedIssueSortWarning(options.providerId, domain, options.connectionId, resolvedSort.rejection),
162
+ );
163
+ return emptyPage(true);
164
+ }
165
+
166
+ const sort = resolvedSort.sort;
167
+
131
168
  await ctx.forceRefreshIfRequested(integration, options.forceSync, options.connectionId);
132
169
 
133
170
  const { value: resources, warning: resourcesWarning } = await runCaptured(
@@ -362,6 +399,37 @@ export async function listIssueTrackerIssuesPage(
362
399
  });
363
400
  }
364
401
 
402
+ // A read spanning several projects is a merge, so it can only honor a key a normalized issue carries. Bound here
403
+ // rather than next to the key's validation above, because the project count is only known now — while still
404
+ // before any project read, so a refusal costs no request. Refused rather than served as concatenated
405
+ // per-project runs, which would look ordered without being so.
406
+ //
407
+ // Counted over every project the READ covers, not the `scopedProjects` window this page happens to hold: the
408
+ // window is `itemsPerPage` projects wide, so counting it would refuse a 20-project page and then serve the
409
+ // final 1-project page of the same paginated call — the same key answered two ways, with the earlier pages'
410
+ // issues missing from a read that reported success.
411
+ //
412
+ // Projects are not the only thing a tracker read merges: a user-scoped read asking for several relationships
413
+ // issues one provider query PER relationship and unions them within each project (Jira runs one JQL drain per
414
+ // filter and folds them into one map, in filter order), so a single-project page of two filters is just as
415
+ // concatenated as a two-project one. Counting only projects published those runs under the requested key.
416
+ // Not gated on the provider: the two trackers that don't fan out (Linear, Trello) declare `Assignee` as their
417
+ // only supported filter, so a multi-filter read is already refused above and can never reach this.
418
+ const mergesFilters = options.includeAllAssignees !== true && (options.filters?.length ?? 0) > 1;
419
+ const ordering = toIssueOrdering(sort, scopedProjectsWithUsers.length > 1 || mergesFilters);
420
+ if (ordering.unmergeable != null) {
421
+ warnings.push(
422
+ unmergeableIssueSortWarning(
423
+ options.providerId,
424
+ domain,
425
+ options.connectionId,
426
+ ordering.unmergeable,
427
+ scopedProjectsWithUsers.length > 1 ? 'projects' : 'filters',
428
+ ),
429
+ );
430
+ return emptyPage(true);
431
+ }
432
+
365
433
  const perProject = await mapBounded(scopedProjects, providerFanOutConcurrency, async project => ({
366
434
  project: project,
367
435
  ...(await runCaptured(options.providerId, domain, options.connectionId, () =>
@@ -370,6 +438,7 @@ export async function listIssueTrackerIssuesPage(
370
438
  {
371
439
  user: userForProject(project),
372
440
  filters: options.filters,
441
+ sort: sort,
373
442
  },
374
443
  options.connectionId,
375
444
  ),
@@ -417,6 +486,11 @@ export async function listIssueTrackerIssuesPage(
417
486
  }
418
487
  }
419
488
 
489
+ // Each provider query arrived ordered by the tracker; the union of them — across projects, and across the
490
+ // per-relationship queries a multi-filter read fans out into — is not, and the union is what this read
491
+ // publishes. A no-op when nothing merged, since the tracker already ordered that single run.
492
+ const orderedItems = ordering.order(items);
493
+
420
494
  const drainAssessment = mergeAssessmentInto(
421
495
  warnings,
422
496
  options.providerId,
@@ -463,9 +537,9 @@ export async function listIssueTrackerIssuesPage(
463
537
  : [],
464
538
  });
465
539
  return {
466
- items: items,
540
+ items: orderedItems,
467
541
  warnings: warnings,
468
- page: { currentPage: page, itemsPerPage: items.length, truncated: projectTruncated || undefined },
542
+ page: { currentPage: page, itemsPerPage: orderedItems.length, truncated: projectTruncated || undefined },
469
543
  // Failed-project retries alone are manual. Only an untouched project window is automatic progress.
470
544
  hasMore: nextPage != null && cursor != null,
471
545
  cursor: cursor,