@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.
- package/CHANGELOG.md +38 -1
- package/dist/plus/git-github/api/github.d.ts +3 -2
- package/dist/plus/git-github/api/github.d.ts.map +1 -1
- package/dist/plus/git-github/api/github.js +37 -37
- package/dist/plus/git-github/api/github.js.map +1 -1
- package/dist/plus/integrations/collectionMetadata.d.ts +2 -0
- package/dist/plus/integrations/collectionMetadata.d.ts.map +1 -1
- package/dist/plus/integrations/collectionMetadata.js +17 -1
- package/dist/plus/integrations/collectionMetadata.js.map +1 -1
- package/dist/plus/integrations/context.d.ts +4 -1
- package/dist/plus/integrations/context.d.ts.map +1 -1
- package/dist/plus/integrations/index.d.ts +1 -0
- package/dist/plus/integrations/index.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +9 -1
- package/dist/plus/integrations/integrationService.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.js +8 -4
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/manager.d.ts +65 -6
- package/dist/plus/integrations/manager.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +22 -26
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +92 -47
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/integration.d.ts +9 -0
- package/dist/plus/integrations/models/integration.d.ts.map +1 -1
- package/dist/plus/integrations/models/integration.js +52 -19
- package/dist/plus/integrations/models/integration.js.map +1 -1
- package/dist/plus/integrations/models/issueCache.d.ts +16 -0
- package/dist/plus/integrations/models/issueCache.d.ts.map +1 -0
- package/dist/plus/integrations/models/issueCache.js +9 -0
- package/dist/plus/integrations/models/issueCache.js.map +1 -0
- package/dist/plus/integrations/models/issueReads.d.ts +13 -0
- package/dist/plus/integrations/models/issueReads.d.ts.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +11 -13
- package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.js +15 -1
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.d.ts +3 -5
- package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.js +9 -8
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.d.ts +3 -5
- package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -1
- package/dist/plus/integrations/providers/bitbucket-server.js +2 -2
- package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.d.ts +3 -5
- package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -1
- package/dist/plus/integrations/providers/bitbucket.js +2 -1
- package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
- package/dist/plus/integrations/providers/github.d.ts +3 -5
- package/dist/plus/integrations/providers/github.d.ts.map +1 -1
- package/dist/plus/integrations/providers/github.js +3 -3
- package/dist/plus/integrations/providers/github.js.map +1 -1
- package/dist/plus/integrations/providers/gitlab.d.ts +3 -5
- package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -1
- package/dist/plus/integrations/providers/gitlab.js +2 -2
- package/dist/plus/integrations/providers/gitlab.js.map +1 -1
- package/dist/plus/integrations/providers/jira.d.ts +3 -7
- package/dist/plus/integrations/providers/jira.d.ts.map +1 -1
- package/dist/plus/integrations/providers/jira.js +35 -22
- package/dist/plus/integrations/providers/jira.js.map +1 -1
- package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +7 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.d.ts.map +1 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.js +102 -0
- package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -0
- package/dist/plus/integrations/providers/linear.d.ts +3 -7
- package/dist/plus/integrations/providers/linear.d.ts.map +1 -1
- package/dist/plus/integrations/providers/linear.js +23 -22
- package/dist/plus/integrations/providers/linear.js.map +1 -1
- package/dist/plus/integrations/providers/models.d.ts +3 -1
- package/dist/plus/integrations/providers/models.d.ts.map +1 -1
- package/dist/plus/integrations/providers/models.js +10 -4
- package/dist/plus/integrations/providers/models.js.map +1 -1
- package/dist/plus/integrations/providers/providerErrors.d.ts +7 -0
- package/dist/plus/integrations/providers/providerErrors.d.ts.map +1 -0
- package/dist/plus/integrations/providers/providerErrors.js +91 -0
- package/dist/plus/integrations/providers/providerErrors.js.map +1 -0
- package/dist/plus/integrations/providers/providersApi.d.ts +3 -2
- package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -1
- package/dist/plus/integrations/providers/providersApi.js +18 -52
- package/dist/plus/integrations/providers/providersApi.js.map +1 -1
- package/dist/plus/integrations/providers/trello.d.ts +2 -7
- package/dist/plus/integrations/providers/trello.d.ts.map +1 -1
- package/dist/plus/integrations/providers/trello.js +3 -1
- package/dist/plus/integrations/providers/trello.js.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts +2 -0
- package/dist/plus/integrations/providers/utils/providerPaging.d.ts.map +1 -1
- package/dist/plus/integrations/providers/utils/providerPaging.js +12 -7
- package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
- package/dist/plus/integrations/reads/broaden.d.ts.map +1 -1
- package/dist/plus/integrations/reads/broaden.js +26 -14
- package/dist/plus/integrations/reads/broaden.js.map +1 -1
- package/dist/plus/integrations/reads/counts.d.ts.map +1 -1
- package/dist/plus/integrations/reads/counts.js +39 -15
- package/dist/plus/integrations/reads/counts.js.map +1 -1
- package/dist/plus/integrations/reads/filters.d.ts +33 -11
- package/dist/plus/integrations/reads/filters.d.ts.map +1 -1
- package/dist/plus/integrations/reads/filters.js +114 -25
- package/dist/plus/integrations/reads/filters.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +23 -17
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/searchIssues.d.ts +1 -5
- package/dist/plus/integrations/reads/searchIssues.d.ts.map +1 -1
- package/dist/plus/integrations/reads/searchIssues.js +12 -6
- package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.d.ts +1 -0
- package/dist/plus/integrations/reads/searchPullRequests.d.ts.map +1 -1
- package/dist/plus/integrations/reads/searchPullRequests.js +8 -3
- package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/trackerIssue.d.ts +21 -0
- package/dist/plus/integrations/reads/trackerIssue.d.ts.map +1 -0
- package/dist/plus/integrations/reads/trackerIssue.js +51 -0
- package/dist/plus/integrations/reads/trackerIssue.js.map +1 -0
- package/dist/plus/integrations/reads/warnings.d.ts +18 -15
- package/dist/plus/integrations/reads/warnings.d.ts.map +1 -1
- package/dist/plus/integrations/reads/warnings.js +37 -1
- package/dist/plus/integrations/reads/warnings.js.map +1 -1
- package/dist/plus/integrations/results.d.ts +4 -20
- package/dist/plus/integrations/results.d.ts.map +1 -1
- package/dist/plus/integrations/results.js.map +1 -1
- package/dist/utils/promise.d.ts +2 -0
- package/dist/utils/promise.d.ts.map +1 -1
- package/dist/utils/promise.js +11 -0
- package/dist/utils/promise.js.map +1 -1
- package/docs/integrations.md +63 -28
- package/docs/kepler-read-api-parity.md +13 -0
- package/package.json +2 -2
- package/src/plus/git-github/api/github.ts +54 -60
- package/src/plus/integrations/collectionMetadata.ts +23 -1
- package/src/plus/integrations/context.ts +1 -1
- package/src/plus/integrations/index.ts +1 -0
- package/src/plus/integrations/integrationService.ts +14 -4
- package/src/plus/integrations/manager.ts +65 -6
- package/src/plus/integrations/models/gitHostIntegration.ts +117 -129
- package/src/plus/integrations/models/integration.ts +56 -22
- package/src/plus/integrations/models/issueCache.ts +29 -0
- package/src/plus/integrations/models/issueReads.ts +15 -0
- package/src/plus/integrations/models/issuesIntegration.ts +38 -8
- package/src/plus/integrations/providers/azureDevOps.ts +16 -13
- package/src/plus/integrations/providers/bitbucket-server.ts +4 -6
- package/src/plus/integrations/providers/bitbucket.ts +3 -4
- package/src/plus/integrations/providers/github.ts +5 -7
- package/src/plus/integrations/providers/gitlab.ts +4 -6
- package/src/plus/integrations/providers/jira.ts +52 -26
- package/src/plus/integrations/providers/jiraIssueByKey.ts +155 -0
- package/src/plus/integrations/providers/linear.ts +38 -25
- package/src/plus/integrations/providers/models.ts +17 -5
- package/src/plus/integrations/providers/providerErrors.ts +115 -0
- package/src/plus/integrations/providers/providersApi.ts +26 -68
- package/src/plus/integrations/providers/trello.ts +5 -4
- package/src/plus/integrations/providers/utils/providerPaging.ts +14 -7
- package/src/plus/integrations/reads/broaden.ts +35 -16
- package/src/plus/integrations/reads/counts.ts +62 -15
- package/src/plus/integrations/reads/filters.ts +131 -29
- package/src/plus/integrations/reads/issueTracker.ts +26 -24
- package/src/plus/integrations/reads/searchIssues.ts +23 -13
- package/src/plus/integrations/reads/searchPullRequests.ts +16 -2
- package/src/plus/integrations/reads/trackerIssue.ts +105 -0
- package/src/plus/integrations/reads/warnings.ts +42 -17
- package/src/plus/integrations/results.ts +4 -20
- 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
|
|
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
|
-
|
|
836
|
+
return (await this.getIssueResult(resource, id, options))?.value;
|
|
837
|
+
}
|
|
832
838
|
|
|
833
|
-
|
|
834
|
-
|
|
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
|
-
|
|
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
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
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
|
|
868
|
+
const issue = await getProviderIssue(session);
|
|
846
869
|
this.resetRequestExceptionCount('getIssue');
|
|
847
|
-
return
|
|
870
|
+
return issue;
|
|
848
871
|
} catch (ex) {
|
|
849
|
-
|
|
850
|
-
|
|
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
|
-
|
|
855
|
-
|
|
856
|
-
|
|
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<
|
|
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 {
|
|
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
|
-
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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?:
|
|
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 =
|
|
943
|
-
searchScopes
|
|
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
|
-
|
|
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?:
|
|
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?:
|
|
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
|
-
|
|
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?:
|
|
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
|
-
|
|
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?:
|
|
710
|
+
options?: SearchPullRequestsOptions,
|
|
713
711
|
): Promise<PullRequest[] | undefined> {
|
|
714
712
|
const api = await this.authenticationService.apis.gitlab;
|
|
715
713
|
if (!api) {
|