@gitkraken/core-gitlens 0.5.114 → 0.5.116

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 (162) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/dist/plus/git-github/api/github.d.ts +3 -2
  3. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  4. package/dist/plus/git-github/api/github.js +37 -37
  5. package/dist/plus/git-github/api/github.js.map +1 -1
  6. package/dist/plus/integrations/collectionMetadata.d.ts +2 -0
  7. package/dist/plus/integrations/collectionMetadata.d.ts.map +1 -1
  8. package/dist/plus/integrations/collectionMetadata.js +17 -1
  9. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  10. package/dist/plus/integrations/context.d.ts +4 -1
  11. package/dist/plus/integrations/context.d.ts.map +1 -1
  12. package/dist/plus/integrations/index.d.ts +1 -0
  13. package/dist/plus/integrations/index.d.ts.map +1 -1
  14. package/dist/plus/integrations/integrationService.d.ts +9 -1
  15. package/dist/plus/integrations/integrationService.d.ts.map +1 -1
  16. package/dist/plus/integrations/integrationService.js +8 -4
  17. package/dist/plus/integrations/integrationService.js.map +1 -1
  18. package/dist/plus/integrations/manager.d.ts +65 -6
  19. package/dist/plus/integrations/manager.d.ts.map +1 -1
  20. package/dist/plus/integrations/models/gitHostIntegration.d.ts +22 -26
  21. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
  22. package/dist/plus/integrations/models/gitHostIntegration.js +92 -47
  23. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  24. package/dist/plus/integrations/models/integration.d.ts +9 -0
  25. package/dist/plus/integrations/models/integration.d.ts.map +1 -1
  26. package/dist/plus/integrations/models/integration.js +52 -19
  27. package/dist/plus/integrations/models/integration.js.map +1 -1
  28. package/dist/plus/integrations/models/issueCache.d.ts +16 -0
  29. package/dist/plus/integrations/models/issueCache.d.ts.map +1 -0
  30. package/dist/plus/integrations/models/issueCache.js +9 -0
  31. package/dist/plus/integrations/models/issueCache.js.map +1 -0
  32. package/dist/plus/integrations/models/issueReads.d.ts +13 -0
  33. package/dist/plus/integrations/models/issueReads.d.ts.map +1 -1
  34. package/dist/plus/integrations/models/issuesIntegration.d.ts +11 -13
  35. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
  36. package/dist/plus/integrations/models/issuesIntegration.js +15 -1
  37. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  38. package/dist/plus/integrations/providers/azureDevOps.d.ts +3 -5
  39. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -1
  40. package/dist/plus/integrations/providers/azureDevOps.js +9 -8
  41. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  42. package/dist/plus/integrations/providers/bitbucket-server.d.ts +3 -5
  43. package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -1
  44. package/dist/plus/integrations/providers/bitbucket-server.js +2 -2
  45. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  46. package/dist/plus/integrations/providers/bitbucket.d.ts +3 -5
  47. package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -1
  48. package/dist/plus/integrations/providers/bitbucket.js +2 -1
  49. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  50. package/dist/plus/integrations/providers/github.d.ts +3 -5
  51. package/dist/plus/integrations/providers/github.d.ts.map +1 -1
  52. package/dist/plus/integrations/providers/github.js +3 -3
  53. package/dist/plus/integrations/providers/github.js.map +1 -1
  54. package/dist/plus/integrations/providers/gitlab.d.ts +3 -5
  55. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
  56. package/dist/plus/integrations/providers/gitlab.js +2 -2
  57. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  58. package/dist/plus/integrations/providers/jira.d.ts +3 -7
  59. package/dist/plus/integrations/providers/jira.d.ts.map +1 -1
  60. package/dist/plus/integrations/providers/jira.js +35 -22
  61. package/dist/plus/integrations/providers/jira.js.map +1 -1
  62. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +7 -0
  63. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts.map +1 -0
  64. package/dist/plus/integrations/providers/jiraIssueByKey.js +102 -0
  65. package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -0
  66. package/dist/plus/integrations/providers/linear.d.ts +3 -7
  67. package/dist/plus/integrations/providers/linear.d.ts.map +1 -1
  68. package/dist/plus/integrations/providers/linear.js +23 -22
  69. package/dist/plus/integrations/providers/linear.js.map +1 -1
  70. package/dist/plus/integrations/providers/models.d.ts +3 -1
  71. package/dist/plus/integrations/providers/models.d.ts.map +1 -1
  72. package/dist/plus/integrations/providers/models.js +10 -4
  73. package/dist/plus/integrations/providers/models.js.map +1 -1
  74. package/dist/plus/integrations/providers/providerErrors.d.ts +7 -0
  75. package/dist/plus/integrations/providers/providerErrors.d.ts.map +1 -0
  76. package/dist/plus/integrations/providers/providerErrors.js +91 -0
  77. package/dist/plus/integrations/providers/providerErrors.js.map +1 -0
  78. package/dist/plus/integrations/providers/providersApi.d.ts +3 -2
  79. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -1
  80. package/dist/plus/integrations/providers/providersApi.js +18 -52
  81. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  82. package/dist/plus/integrations/providers/trello.d.ts +2 -7
  83. package/dist/plus/integrations/providers/trello.d.ts.map +1 -1
  84. package/dist/plus/integrations/providers/trello.js +3 -1
  85. package/dist/plus/integrations/providers/trello.js.map +1 -1
  86. package/dist/plus/integrations/providers/utils/providerPaging.d.ts +2 -0
  87. package/dist/plus/integrations/providers/utils/providerPaging.d.ts.map +1 -1
  88. package/dist/plus/integrations/providers/utils/providerPaging.js +12 -7
  89. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  90. package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
  91. package/dist/plus/integrations/reads/broaden.js +26 -14
  92. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  93. package/dist/plus/integrations/reads/counts.d.ts.map +1 -1
  94. package/dist/plus/integrations/reads/counts.js +39 -15
  95. package/dist/plus/integrations/reads/counts.js.map +1 -1
  96. package/dist/plus/integrations/reads/filters.d.ts +33 -11
  97. package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
  98. package/dist/plus/integrations/reads/filters.js +114 -25
  99. package/dist/plus/integrations/reads/filters.js.map +1 -1
  100. package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
  101. package/dist/plus/integrations/reads/issueTracker.js +23 -17
  102. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  103. package/dist/plus/integrations/reads/searchIssues.d.ts +1 -5
  104. package/dist/plus/integrations/reads/searchIssues.d.ts.map +1 -1
  105. package/dist/plus/integrations/reads/searchIssues.js +12 -6
  106. package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
  107. package/dist/plus/integrations/reads/searchPullRequests.d.ts +1 -0
  108. package/dist/plus/integrations/reads/searchPullRequests.d.ts.map +1 -1
  109. package/dist/plus/integrations/reads/searchPullRequests.js +8 -3
  110. package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
  111. package/dist/plus/integrations/reads/trackerIssue.d.ts +21 -0
  112. package/dist/plus/integrations/reads/trackerIssue.d.ts.map +1 -0
  113. package/dist/plus/integrations/reads/trackerIssue.js +51 -0
  114. package/dist/plus/integrations/reads/trackerIssue.js.map +1 -0
  115. package/dist/plus/integrations/reads/warnings.d.ts +18 -15
  116. package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
  117. package/dist/plus/integrations/reads/warnings.js +37 -1
  118. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  119. package/dist/plus/integrations/results.d.ts +4 -20
  120. package/dist/plus/integrations/results.d.ts.map +1 -1
  121. package/dist/plus/integrations/results.js.map +1 -1
  122. package/dist/utils/promise.d.ts +2 -0
  123. package/dist/utils/promise.d.ts.map +1 -1
  124. package/dist/utils/promise.js +11 -0
  125. package/dist/utils/promise.js.map +1 -1
  126. package/docs/integrations.md +63 -28
  127. package/docs/kepler-read-api-parity.md +13 -0
  128. package/package.json +2 -2
  129. package/src/plus/git-github/api/github.ts +54 -60
  130. package/src/plus/integrations/collectionMetadata.ts +23 -1
  131. package/src/plus/integrations/context.ts +1 -1
  132. package/src/plus/integrations/index.ts +1 -0
  133. package/src/plus/integrations/integrationService.ts +14 -4
  134. package/src/plus/integrations/manager.ts +65 -6
  135. package/src/plus/integrations/models/gitHostIntegration.ts +117 -129
  136. package/src/plus/integrations/models/integration.ts +56 -22
  137. package/src/plus/integrations/models/issueCache.ts +29 -0
  138. package/src/plus/integrations/models/issueReads.ts +15 -0
  139. package/src/plus/integrations/models/issuesIntegration.ts +38 -8
  140. package/src/plus/integrations/providers/azureDevOps.ts +16 -13
  141. package/src/plus/integrations/providers/bitbucket-server.ts +4 -6
  142. package/src/plus/integrations/providers/bitbucket.ts +3 -4
  143. package/src/plus/integrations/providers/github.ts +5 -7
  144. package/src/plus/integrations/providers/gitlab.ts +4 -6
  145. package/src/plus/integrations/providers/jira.ts +52 -26
  146. package/src/plus/integrations/providers/jiraIssueByKey.ts +155 -0
  147. package/src/plus/integrations/providers/linear.ts +38 -25
  148. package/src/plus/integrations/providers/models.ts +17 -5
  149. package/src/plus/integrations/providers/providerErrors.ts +115 -0
  150. package/src/plus/integrations/providers/providersApi.ts +26 -68
  151. package/src/plus/integrations/providers/trello.ts +5 -4
  152. package/src/plus/integrations/providers/utils/providerPaging.ts +14 -7
  153. package/src/plus/integrations/reads/broaden.ts +35 -16
  154. package/src/plus/integrations/reads/counts.ts +62 -15
  155. package/src/plus/integrations/reads/filters.ts +131 -29
  156. package/src/plus/integrations/reads/issueTracker.ts +26 -24
  157. package/src/plus/integrations/reads/searchIssues.ts +23 -13
  158. package/src/plus/integrations/reads/searchPullRequests.ts +16 -2
  159. package/src/plus/integrations/reads/trackerIssue.ts +105 -0
  160. package/src/plus/integrations/reads/warnings.ts +42 -17
  161. package/src/plus/integrations/results.ts +4 -20
  162. package/src/utils/promise.ts +15 -0
@@ -11,6 +11,7 @@ import type { Disposable } from '../../../utils/disposable.js';
11
11
  import type { Event } from '../../../utils/event.js';
12
12
  import { Emitter } from '../../../utils/event.js';
13
13
  import { fnv1aHash64 } from '../../../utils/hash.js';
14
+ import { Logger } from '../../../utils/logger.js';
14
15
  import type { ScopedLogger } from '../../../utils/logger.scoped.js';
15
16
  import { getScopedLogger } from '../../../utils/logger.scoped.js';
16
17
  import type {
@@ -30,6 +31,7 @@ import type { Sources } from '../telemetry.js';
30
31
  import { areDomainsOnSameHost } from '../utils/domain.utils.js';
31
32
  import { isGitSelfManagedHostIntegrationId } from '../utils/integration.utils.js';
32
33
  import type { GitHostIntegration } from './gitHostIntegration.js';
34
+ import { getCachedIssue } from './issueCache.js';
33
35
  import type { AccountWideIssuesResult, SearchMyIssuesOptions } from './issueReads.js';
34
36
  import type { IssuesIntegration } from './issuesIntegration.js';
35
37
 
@@ -492,7 +494,11 @@ export abstract class IntegrationBase<
492
494
  ): void {
493
495
  if (isCancellationError(ex)) return;
494
496
 
495
- options?.scope?.error(ex);
497
+ if (options?.scope != null) {
498
+ options.scope.error(ex);
499
+ } else {
500
+ Logger.error(ex);
501
+ }
496
502
 
497
503
  // A per-connection (multi-account) read resolved its session through `resolveReadSession`'s
498
504
  // `connectionId` branch, which deliberately never touches the cached primary `_session`. So the
@@ -822,38 +828,66 @@ export abstract class IntegrationBase<
822
828
  type: undefined | IssueOrPullRequestType,
823
829
  ): Promise<IssueOrPullRequest | undefined>;
824
830
 
825
- @trace()
826
831
  async getIssue(
827
832
  resource: T,
828
833
  id: string,
829
- options?: { expiryOverride?: boolean | number },
834
+ options?: { connectionId?: string; expiryOverride?: boolean | number },
830
835
  ): Promise<Issue | undefined> {
831
- const scope = getScopedLogger();
836
+ return (await this.getIssueResult(resource, id, options))?.value;
837
+ }
832
838
 
833
- const connected = this.maybeConnected ?? (await this.isConnected());
834
- if (!connected) return undefined;
839
+ getIssueResult(
840
+ resource: T,
841
+ id: string,
842
+ options?: { connectionId?: string; expiryOverride?: boolean | number },
843
+ ): Promise<IntegrationResult<Issue | undefined>> {
844
+ return this.getIssueResultCore(resource, id, options, session => this.getProviderIssue(session, resource, id));
845
+ }
835
846
 
836
- await this.refreshSessionIfExpired(scope);
847
+ @trace()
848
+ protected async getIssueResultCore(
849
+ resource: ResourceDescriptor,
850
+ id: string,
851
+ options: { connectionId?: string; expiryOverride?: boolean | number } | undefined,
852
+ getProviderIssue: (session: ProviderAuthenticationSession) => Promise<Issue | undefined>,
853
+ ): Promise<IntegrationResult<Issue | undefined>> {
854
+ const scope = getScopedLogger();
855
+ const { connectionId: requestedConnectionId, expiryOverride } = options ?? {};
856
+ const connectionId = requestedConnectionId || undefined;
857
+ const session = await this.resolveReadSession(connectionId, scope);
858
+ if (session == null) return undefined;
837
859
 
838
- const issue = this.ctx.cache.getIssue(
839
- id,
840
- resource,
841
- this,
842
- () => ({
843
- value: (async () => {
860
+ try {
861
+ const issue = await getCachedIssue({
862
+ cache: this.ctx.cache,
863
+ id: id,
864
+ resource: resource,
865
+ integration: this,
866
+ load: async () => {
844
867
  try {
845
- const result = await this.getProviderIssue(this._session!, resource, id);
868
+ const issue = await getProviderIssue(session);
846
869
  this.resetRequestExceptionCount('getIssue');
847
- return result;
870
+ return issue;
848
871
  } catch (ex) {
849
- this.handleProviderException('getIssue', ex, { scope: scope });
850
- return undefined;
872
+ if (!isCancellationError(ex)) {
873
+ this.handleProviderException('getIssue', toError(ex), {
874
+ scope: scope,
875
+ connectionId: connectionId,
876
+ });
877
+ }
878
+ throw ex;
851
879
  }
852
- })(),
853
- }),
854
- options,
855
- );
856
- return issue;
880
+ },
881
+ cacheOptions: {
882
+ connectionId: connectionId,
883
+ expiryOverride: expiryOverride,
884
+ etag: `${this.id}:${this.maybeConnected ?? false}:${this.getSessionFingerprint(session)}`,
885
+ },
886
+ });
887
+ return { value: issue };
888
+ } catch (ex) {
889
+ return { error: toError(ex) };
890
+ }
857
891
  }
858
892
 
859
893
  protected abstract getProviderIssue(
@@ -0,0 +1,29 @@
1
+ import type { Issue } from '../../../git/models/issue.js';
2
+ import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
3
+ import type { IntegrationCacheProvider } from '../context.js';
4
+
5
+ export async function getCachedIssue(options: {
6
+ cache: IntegrationCacheProvider;
7
+ id: string;
8
+ resource: ResourceDescriptor;
9
+ integration: Parameters<IntegrationCacheProvider['getIssue']>[2];
10
+ load: () => Promise<Issue | undefined>;
11
+ cacheOptions: {
12
+ connectionId: string | undefined;
13
+ expiryOverride: boolean | number | undefined;
14
+ etag: string;
15
+ };
16
+ }): Promise<Issue | undefined> {
17
+ return options.cache.getIssue(
18
+ options.id,
19
+ options.resource,
20
+ options.integration,
21
+ cacheable => ({
22
+ value: options.load().catch((ex: unknown) => {
23
+ cacheable.invalidate();
24
+ throw ex;
25
+ }),
26
+ }),
27
+ options.cacheOptions,
28
+ );
29
+ }
@@ -66,6 +66,21 @@ export type IssuesForProjectOptions = {
66
66
  sort?: IssueSorting;
67
67
  };
68
68
 
69
+ export type ProjectIssuesDrain = {
70
+ values: IssueShape[];
71
+ metadata?: CollectionMetadata;
72
+ } & (
73
+ | { truncated: false }
74
+ | {
75
+ truncated: true;
76
+ /**
77
+ * `narrow-scope` means a smaller server-side scope avoids this truncation. `none` covers incomplete
78
+ * results without that guarantee, including Linear's client-side assignee filtering.
79
+ */
80
+ recovery: 'narrow-scope' | 'none';
81
+ }
82
+ );
83
+
69
84
  /**
70
85
  * Options for the REPO-scoped issue read (`GitHostIntegration.getMyIssuesForRepos*`), the git-host counterpart of
71
86
  * {@link IssuesForProjectOptions}.
@@ -1,17 +1,16 @@
1
- import type { CollectionMetadata } from '@gitkraken/provider-apis';
2
1
  import type { Account } from '../../../git/models/author.js';
3
- import type { IssueShape } from '../../../git/models/issue.js';
2
+ import type { Issue, IssueShape } from '../../../git/models/issue.js';
4
3
  import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
5
4
  import { gate } from '../../../utils/decorators/gate.js';
6
5
  import { trace } from '../../../utils/decorators/log.js';
7
6
  import { getScopedLogger } from '../../../utils/logger.scoped.js';
8
7
  import type { ProviderAuthenticationSession } from '../authentication/models.js';
9
8
  import type { IntegrationIds } from '../constants.js';
10
- import { toError } from '../errors.js';
9
+ import { IntegrationReadUnavailableError, toError } from '../errors.js';
11
10
  import type { ProviderApiCollectionResult } from '../providers/models.js';
12
11
  import type { Integration, IntegrationResult, IntegrationType } from './integration.js';
13
12
  import { IntegrationBase } from './integration.js';
14
- import type { IssuesForProjectOptions } from './issueReads.js';
13
+ import type { IssuesForProjectOptions, ProjectIssuesDrain } from './issueReads.js';
15
14
 
16
15
  export function isIssuesIntegration(integration: Integration): integration is IssuesIntegration {
17
16
  return integration.type === 'issues';
@@ -23,6 +22,39 @@ export abstract class IssuesIntegration<
23
22
  > extends IntegrationBase<ID> {
24
23
  readonly type: IntegrationType = 'issues';
25
24
 
25
+ get supportsIssueLookupByResourceId(): boolean {
26
+ return this.getProviderIssueByResourceId != null;
27
+ }
28
+
29
+ getIssueByResourceIdResult(
30
+ resourceId: string,
31
+ id: string,
32
+ options?: { connectionId?: string; expiryOverride?: boolean | number; resourceUrl?: string },
33
+ ): Promise<IntegrationResult<Issue | undefined>> {
34
+ const getProviderIssue = this.getProviderIssueByResourceId;
35
+ if (getProviderIssue == null) {
36
+ return Promise.resolve({
37
+ error: new IntegrationReadUnavailableError(
38
+ this.name,
39
+ 'does not support direct issue reads by resource id',
40
+ ),
41
+ });
42
+ }
43
+
44
+ const { resourceUrl, ...readOptions } = options ?? {};
45
+ const resource = { key: resourceId, resourceId: resourceId, resourceUrl: resourceUrl };
46
+ return this.getIssueResultCore(resource, id, readOptions, session =>
47
+ getProviderIssue.call(this, session, resourceId, id, resourceUrl),
48
+ );
49
+ }
50
+
51
+ protected getProviderIssueByResourceId?(
52
+ _session: ProviderAuthenticationSession,
53
+ _resourceId: string,
54
+ _id: string,
55
+ _resourceUrl: string | undefined,
56
+ ): Promise<Issue | undefined>;
57
+
26
58
  @trace()
27
59
  async getAccountForResource(resource: T, connectionId?: string): Promise<Account | undefined> {
28
60
  return (await this.getAccountForResourceResult(resource, connectionId))?.value;
@@ -177,9 +209,7 @@ export abstract class IssuesIntegration<
177
209
  project: T,
178
210
  options?: IssuesForProjectOptions,
179
211
  connectionId?: string,
180
- ): Promise<
181
- IntegrationResult<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined>
182
- > {
212
+ ): Promise<IntegrationResult<ProjectIssuesDrain | undefined>> {
183
213
  const scope = getScopedLogger();
184
214
  const session = await this.resolveReadSession(connectionId, scope);
185
215
  if (session == null) return undefined;
@@ -210,7 +240,7 @@ export abstract class IssuesIntegration<
210
240
  session: ProviderAuthenticationSession,
211
241
  project: T,
212
242
  options?: IssuesForProjectOptions,
213
- ): Promise<{ values: IssueShape[]; truncated: boolean; metadata?: CollectionMetadata } | undefined> {
243
+ ): Promise<ProjectIssuesDrain | undefined> {
214
244
  const values = await this.getProviderIssuesForProject(session, project, options);
215
245
  if (values == null) return undefined;
216
246
  return { values: values, truncated: false };
@@ -14,6 +14,7 @@ import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.
14
14
  import { base64 } from '../../../utils/base64.js';
15
15
  import { CancellationError } from '../../../utils/cancellation.js';
16
16
  import type { Emitter } from '../../../utils/event.js';
17
+ import { mapSettledBounded } from '../../../utils/promise.js';
17
18
  import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
18
19
  import type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';
19
20
  import type {
@@ -23,10 +24,10 @@ import type {
23
24
  } from '../authentication/models.js';
24
25
  import { toTokenWithInfo } from '../authentication/models.js';
25
26
  import { toCollectionScopeFailure } from '../collectionMetadata.js';
26
- import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../constants.js';
27
+ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId, providerFanOutConcurrency } from '../constants.js';
27
28
  import type { IntegrationServiceContext } from '../context.js';
28
29
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
29
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
30
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
30
31
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
31
32
  import type { AccountWideIssuesResult, IntegrationKey, SearchMyIssuesOptions } from '../models/integration.js';
32
33
  import type {
@@ -56,7 +57,11 @@ import {
56
57
  toProviderPullRequestStates,
57
58
  } from './models.js';
58
59
  import type { ProvidersApi } from './providersApi.js';
59
- import { collectProviderPagedResult, flatSettledOrThrow, mergeCollectionMetadata } from './utils/providerPaging.js';
60
+ import {
61
+ collectProviderPagedResult,
62
+ flatSettledResultsOrThrow,
63
+ mergeCollectionMetadata,
64
+ } from './utils/providerPaging.js';
60
65
 
61
66
  function getAzureRepositoryIdentity(repo: Pick<AzureRepositoryDescriptor, 'owner' | 'name' | 'project'>): {
62
67
  resourceName: string;
@@ -654,9 +659,7 @@ export abstract class AzureDevOpsIntegrationBase<
654
659
  session: ProviderAuthenticationSession,
655
660
  repos?: AzureRepositoryDescriptor[],
656
661
  _cancellation?: AbortSignal,
657
- _silent?: boolean,
658
- state?: PullRequestStateFilter,
659
- _options?: SearchMyPullRequestsOptions,
662
+ options?: SearchMyPullRequestsOptions,
660
663
  ): Promise<PullRequest[] | undefined> {
661
664
  const api = await this.getProvidersApi();
662
665
  if (repos != null) {
@@ -664,7 +667,7 @@ export abstract class AzureDevOpsIntegrationBase<
664
667
  return undefined;
665
668
  }
666
669
 
667
- const states = toProviderPullRequestStates(state);
670
+ const states = toProviderPullRequestStates(options?.state);
668
671
 
669
672
  const user = await this.getProviderCurrentAccount(session);
670
673
  // Azure filters key on the identity GUID (account id), not the display name — see
@@ -683,21 +686,21 @@ export abstract class AzureDevOpsIntegrationBase<
683
686
  .filter(r => r != null)
684
687
  .flat();
685
688
 
686
- const { tokenWithInfo, options } = this.getApiOptions(session);
689
+ const { tokenWithInfo, options: apiOptions } = this.getApiOptions(session);
687
690
  const projectInputs = projects.values.map(p => ({ namespace: p.resourceName, project: p.name }));
688
691
  // Legacy array-returning path (Launchpad/focus view): unwrap `.values` from the SDK collection result.
689
692
  // The metadata (partial/failures) isn't surfaced here because this path's return type has no warning
690
693
  // channel; the metadata-aware ProviderBackend surface is getProviderMyPullRequestsForUser above.
691
694
  const assignedPrs = (
692
695
  await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
693
- ...options,
696
+ ...apiOptions,
694
697
  assigneeLogins: [user.id],
695
698
  states: states,
696
699
  })
697
700
  ).values.map(pr => this.fromAzureProviderPullRequest(pr, repoDescriptors, projects.values));
698
701
  const authoredPrs = (
699
702
  await api.getPullRequestsForAzureProjects(tokenWithInfo, projectInputs, {
700
- ...options,
703
+ ...apiOptions,
701
704
  authorLogin: user.id,
702
705
  states: states,
703
706
  })
@@ -883,7 +886,7 @@ export abstract class AzureDevOpsIntegrationBase<
883
886
  searchQuery: string,
884
887
  repos?: AzureRepositoryDescriptor[],
885
888
  cancellation?: AbortSignal,
886
- options?: { include?: PullRequestState[] },
889
+ options?: SearchPullRequestsOptions,
887
890
  ): Promise<PullRequest[] | undefined> {
888
891
  if (cancellation?.aborted) throw new CancellationError();
889
892
 
@@ -939,8 +942,8 @@ export abstract class AzureDevOpsIntegrationBase<
939
942
  project: { namespace: project.resourceName, project: project.name },
940
943
  }));
941
944
 
942
- const providerPullRequests = await flatSettledOrThrow(
943
- searchScopes.map(async scope => {
945
+ const providerPullRequests = flatSettledResultsOrThrow(
946
+ await mapSettledBounded(searchScopes, providerFanOutConcurrency, async scope => {
944
947
  const values: ProviderPullRequest[] = [];
945
948
  let page: number | undefined;
946
949
  for (let i = 0; i < 20; i++) {
@@ -25,7 +25,7 @@ import { toTokenWithInfo } from '../authentication/models.js';
25
25
  import { GitSelfManagedHostIntegrationId } from '../constants.js';
26
26
  import type { IntegrationServiceContext } from '../context.js';
27
27
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
28
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
28
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
29
29
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
30
30
  import type { IntegrationKey } from '../models/integration.js';
31
31
  import type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';
@@ -251,9 +251,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
251
251
  session: ProviderAuthenticationSession,
252
252
  repos?: BitbucketRepositoryDescriptor[],
253
253
  _cancellation?: AbortSignal,
254
- _silent?: boolean,
255
- state?: PullRequestStateFilter,
256
- _options?: SearchMyPullRequestsOptions,
254
+ options?: SearchMyPullRequestsOptions,
257
255
  ): Promise<PullRequest[] | undefined> {
258
256
  if (repos != null) {
259
257
  // TODO: implement repos version
@@ -268,7 +266,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
268
266
  const prs = await api.getBitbucketServerPullRequestsForCurrentUser(
269
267
  toTokenWithInfo(this.id, session),
270
268
  this.apiBaseUrl,
271
- { states: toProviderPullRequestStates(state) },
269
+ { states: toProviderPullRequestStates(options?.state) },
272
270
  );
273
271
  return prs?.data.map(pr => fromProviderPullRequest(pr, this));
274
272
  }
@@ -331,7 +329,7 @@ export class BitbucketServerIntegration extends GitHostIntegration<
331
329
  searchQuery: string,
332
330
  repos?: BitbucketRepositoryDescriptor[],
333
331
  cancellation?: AbortSignal,
334
- options?: { include?: PullRequestState[] },
332
+ options?: SearchPullRequestsOptions,
335
333
  ): Promise<PullRequest[] | undefined> {
336
334
  if (cancellation?.aborted) throw new CancellationError();
337
335
 
@@ -23,7 +23,7 @@ import type {
23
23
  import { toTokenWithInfo } from '../authentication/models.js';
24
24
  import { toCollectionScopeFailure } from '../collectionMetadata.js';
25
25
  import { GitCloudHostIntegrationId } from '../constants.js';
26
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
26
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
27
27
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
28
28
  import type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';
29
29
  import type {
@@ -321,8 +321,6 @@ export class BitbucketIntegration extends GitHostIntegration<
321
321
  session: ProviderAuthenticationSession,
322
322
  repos?: BitbucketRepositoryDescriptor[],
323
323
  _cancellation?: AbortSignal,
324
- _silent?: boolean,
325
- state?: PullRequestStateFilter,
326
324
  options?: SearchMyPullRequestsOptions,
327
325
  ): Promise<PullRequest[] | undefined> {
328
326
  if (repos != null) {
@@ -330,6 +328,7 @@ export class BitbucketIntegration extends GitHostIntegration<
330
328
  return undefined;
331
329
  }
332
330
 
331
+ const state = options?.state;
333
332
  const states = toProviderPullRequestStates(state);
334
333
 
335
334
  const api = await this.getProvidersApi();
@@ -624,7 +623,7 @@ export class BitbucketIntegration extends GitHostIntegration<
624
623
  searchQuery: string,
625
624
  repos?: BitbucketRepositoryDescriptor[],
626
625
  cancellation?: AbortSignal,
627
- options?: { include?: PullRequestState[] },
626
+ options?: SearchPullRequestsOptions,
628
627
  ): Promise<PullRequest[] | undefined> {
629
628
  if (cancellation?.aborted) throw new CancellationError();
630
629
 
@@ -26,7 +26,7 @@ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../c
26
26
  import type { IntegrationServiceContext } from '../context.js';
27
27
  import { IntegrationReadUnavailableError } from '../errors.js';
28
28
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
29
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
29
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
30
30
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
31
31
  import type {
32
32
  ProviderIssueSearchPage,
@@ -397,9 +397,7 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
397
397
  session: ProviderAuthenticationSession,
398
398
  repos?: GitHubRepositoryDescriptor[],
399
399
  cancellation?: AbortSignal,
400
- silent?: boolean,
401
- state?: PullRequestStateFilter,
402
- _options?: SearchMyPullRequestsOptions,
400
+ options?: SearchMyPullRequestsOptions,
403
401
  ): Promise<PullRequest[] | undefined> {
404
402
  return (await this.authenticationService.apis.github)?.searchMyPullRequests(
405
403
  this,
@@ -407,8 +405,8 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
407
405
  {
408
406
  repos: repos?.map(r => `${r.owner}/${r.name}`),
409
407
  baseUrl: this.apiBaseUrl,
410
- silent: silent,
411
- state: state,
408
+ silent: options?.silent,
409
+ state: options?.state,
412
410
  },
413
411
  cancellation,
414
412
  );
@@ -734,7 +732,7 @@ abstract class GitHubIntegrationBase<ID extends GitHubIntegrationIds> extends Gi
734
732
  searchQuery: string,
735
733
  repos?: GitHubRepositoryDescriptor[],
736
734
  cancellation?: AbortSignal,
737
- options?: { include?: PullRequestState[] },
735
+ options?: SearchPullRequestsOptions,
738
736
  ): Promise<PullRequest[] | undefined> {
739
737
  return (await this.authenticationService.apis.github)?.searchPullRequests(
740
738
  this,
@@ -25,7 +25,7 @@ import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId } from '../c
25
25
  import type { IntegrationServiceContext } from '../context.js';
26
26
  import { IntegrationReadUnavailableError } from '../errors.js';
27
27
  import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
28
- import type { SearchMyPullRequestsOptions } from '../models/gitHostIntegration.js';
28
+ import type { SearchMyPullRequestsOptions, SearchPullRequestsOptions } from '../models/gitHostIntegration.js';
29
29
  import { GitHostIntegration } from '../models/gitHostIntegration.js';
30
30
  import type { AccountWideIssuesResult, SearchMyIssuesOptions } from '../models/integration.js';
31
31
  import type { GitLabIntegrationIds } from './gitlab/gitlab.utils.js';
@@ -406,9 +406,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
406
406
  session: ProviderAuthenticationSession,
407
407
  repos?: GitLabRepositoryDescriptor[],
408
408
  _cancellation?: AbortSignal,
409
- _silent?: boolean,
410
- state?: PullRequestStateFilter,
411
- _options?: SearchMyPullRequestsOptions,
409
+ options?: SearchMyPullRequestsOptions,
412
410
  ): Promise<PullRequest[] | undefined> {
413
411
  const api = await this.getProvidersApi();
414
412
  // Resolve the username from THIS session's token (multi-account: `session` may be a non-primary
@@ -421,7 +419,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
421
419
  const apiResult = await api.getPullRequestsForUser(toTokenWithInfo(this.id, session), username, {
422
420
  isPAT: this.isEnterprise,
423
421
  baseUrl: this.isEnterprise ? `https://${this.domain}` : undefined,
424
- states: toProviderPullRequestStates(state),
422
+ states: toProviderPullRequestStates(options?.state),
425
423
  });
426
424
 
427
425
  if (apiResult == null) {
@@ -709,7 +707,7 @@ abstract class GitLabIntegrationBase<ID extends GitLabIntegrationIds> extends Gi
709
707
  searchQuery: string,
710
708
  repos?: GitLabRepositoryDescriptor[],
711
709
  cancellation?: AbortSignal,
712
- options?: { include?: PullRequestState[] },
710
+ options?: SearchPullRequestsOptions,
713
711
  ): Promise<PullRequest[] | undefined> {
714
712
  const api = await this.authenticationService.apis.gitlab;
715
713
  if (!api) {