@gitkraken/core-gitlens 0.4.100 → 0.4.101
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 +4 -1
- package/dist/plus/integrations/errors.d.ts.map +1 -1
- package/dist/plus/integrations/errors.js +6 -2
- package/dist/plus/integrations/errors.js.map +1 -1
- package/dist/plus/integrations/integrationService.d.ts +8 -5
- package/dist/plus/integrations/integrationService.d.ts.map +1 -1
- package/dist/plus/integrations/integrationService.js +20 -652
- package/dist/plus/integrations/integrationService.js.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.d.ts +10 -17
- package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/gitHostIntegration.js +38 -88
- package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.d.ts +4 -21
- package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -1
- package/dist/plus/integrations/models/issuesIntegration.js +5 -47
- package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
- package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
- package/dist/plus/integrations/reads/broaden.d.ts +20 -0
- package/dist/plus/integrations/reads/broaden.d.ts.map +1 -0
- package/dist/plus/integrations/reads/broaden.js +326 -0
- package/dist/plus/integrations/reads/broaden.js.map +1 -0
- package/dist/plus/integrations/reads/context.d.ts +22 -0
- package/dist/plus/integrations/reads/context.d.ts.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.d.ts +1 -1
- package/dist/plus/integrations/reads/hierarchy.d.ts.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.js +109 -137
- package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.d.ts +25 -1
- package/dist/plus/integrations/reads/hierarchy.utils.d.ts.map +1 -1
- package/dist/plus/integrations/reads/hierarchy.utils.js +43 -0
- package/dist/plus/integrations/reads/hierarchy.utils.js.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts +1 -1
- package/dist/plus/integrations/reads/issueTracker.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issueTracker.js +13 -25
- package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
- package/dist/plus/integrations/reads/issues.d.ts +2 -2
- package/dist/plus/integrations/reads/issues.d.ts.map +1 -1
- package/dist/plus/integrations/reads/issues.js.map +1 -1
- package/dist/plus/integrations/reads/pullRequests.d.ts +1 -1
- package/dist/plus/integrations/reads/pullRequests.d.ts.map +1 -1
- package/dist/plus/integrations/reads/pullRequests.js +1 -1
- package/dist/plus/integrations/reads/pullRequests.js.map +1 -1
- package/dist/plus/integrations/reads/resolveRepository.d.ts +25 -0
- package/dist/plus/integrations/reads/resolveRepository.d.ts.map +1 -0
- package/dist/plus/integrations/reads/resolveRepository.js +235 -0
- package/dist/plus/integrations/reads/resolveRepository.js.map +1 -0
- package/dist/plus/integrations/reads/sweeps.d.ts +11 -0
- package/dist/plus/integrations/reads/sweeps.d.ts.map +1 -0
- package/dist/plus/integrations/reads/sweeps.js +125 -0
- package/dist/plus/integrations/reads/sweeps.js.map +1 -0
- package/package.json +1 -1
- package/src/plus/integrations/errors.ts +6 -2
- package/src/plus/integrations/integrationService.ts +27 -801
- package/src/plus/integrations/models/gitHostIntegration.ts +71 -93
- package/src/plus/integrations/models/issuesIntegration.ts +5 -52
- package/src/plus/integrations/providers/azureDevOps.ts +1 -1
- package/src/plus/integrations/reads/broaden.ts +452 -0
- package/src/plus/integrations/reads/context.ts +24 -0
- package/src/plus/integrations/reads/hierarchy.ts +133 -153
- package/src/plus/integrations/reads/hierarchy.utils.ts +50 -1
- package/src/plus/integrations/reads/issueTracker.ts +15 -27
- package/src/plus/integrations/reads/issues.ts +4 -2
- package/src/plus/integrations/reads/pullRequests.ts +2 -9
- package/src/plus/integrations/reads/resolveRepository.ts +272 -0
- package/src/plus/integrations/reads/sweeps.ts +185 -0
|
@@ -104,6 +104,21 @@ export type SearchMyPullRequestsOptions = {
|
|
|
104
104
|
includeReviewRequested?: boolean;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Rejects a read the provider can't serve as asked: logs the reason and returns it as the `{ error }` half of an
|
|
109
|
+
* {@link IntegrationResult}, timed from `start`.
|
|
110
|
+
*
|
|
111
|
+
* A single builder because these refusals are a contract, not incidental returns — the read cores below reject on
|
|
112
|
+
* unsupported input, an inexpressible filter set, or an unresolvable filter account, and each one must reach the
|
|
113
|
+
* caller as an error it can surface as a warning rather than as an empty success. Writing the message once also
|
|
114
|
+
* keeps the logged text and the thrown text from drifting apart, which is exactly what happened while each site
|
|
115
|
+
* spelled its message out twice.
|
|
116
|
+
*/
|
|
117
|
+
function unsupportedRead<T>(message: string, start: number, logContext?: string): IntegrationResult<T> {
|
|
118
|
+
Logger.warn(message, logContext);
|
|
119
|
+
return { error: new Error(message), duration: performance.now() - start };
|
|
120
|
+
}
|
|
121
|
+
|
|
107
122
|
export abstract class GitHostIntegration<
|
|
108
123
|
ID extends IntegrationIds = IntegrationIds,
|
|
109
124
|
T extends ResourceDescriptor = ResourceDescriptor,
|
|
@@ -289,15 +304,6 @@ export abstract class GitHostIntegration<
|
|
|
289
304
|
cancellation?: AbortSignal,
|
|
290
305
|
): Promise<RepositoryMetadata | undefined>;
|
|
291
306
|
|
|
292
|
-
/**
|
|
293
|
-
* Lists the organizations (orgs/workspaces/groups) the current user belongs to on this host.
|
|
294
|
-
* `truncated === true` means the defensive page-drain backstop stopped before the upstream listing
|
|
295
|
-
* was exhausted.
|
|
296
|
-
*/
|
|
297
|
-
async getOrganizationsForUser(): Promise<ProviderHierarchyResult<ProviderOrganization> | undefined> {
|
|
298
|
-
return (await this.getOrganizationsForUserResult())?.value;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
307
|
/**
|
|
302
308
|
* Whether this git host implements generic org discovery. False for providers that register no
|
|
303
309
|
* {@link getProviderOrganizationsForUser} hook (e.g. Bitbucket Data Center) — the facade uses this to
|
|
@@ -344,9 +350,13 @@ export abstract class GitHostIntegration<
|
|
|
344
350
|
}
|
|
345
351
|
|
|
346
352
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
353
|
+
* Lists the organizations (orgs/workspaces/groups) the current user belongs to on this host.
|
|
354
|
+
* `truncated === true` means the defensive page-drain backstop stopped before the upstream listing was
|
|
355
|
+
* exhausted.
|
|
356
|
+
*
|
|
357
|
+
* Resolves the session for `connectionId` (or the primary connection when omitted, honoring multi-account
|
|
358
|
+
* reads) and recovers a thrown error into `{ error }` so callers can surface it as a warning instead of
|
|
359
|
+
* swallowing it to `undefined`.
|
|
350
360
|
*/
|
|
351
361
|
@trace()
|
|
352
362
|
async getOrganizationsForUserResult(
|
|
@@ -416,17 +426,9 @@ export abstract class GitHostIntegration<
|
|
|
416
426
|
* every other host ignores it. (Azure without a project can't page its cross-project merge, so it
|
|
417
427
|
* returns all matches in a single page.) `truncated === true` means the defensive page-drain
|
|
418
428
|
* backstop stopped before the upstream listing was exhausted.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
options?: { project?: string; cursor?: string },
|
|
423
|
-
): Promise<ProviderHierarchyResult<ProviderRepository> | undefined> {
|
|
424
|
-
return (await this.getRepositoriesForOrgResult(org, options))?.value;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Result-returning core of {@link getRepositoriesForOrg}. Resolves the session for `connectionId`
|
|
429
|
-
* (or the primary connection when omitted) and recovers a thrown error into `{ error }` for warnings.
|
|
429
|
+
*
|
|
430
|
+
* Resolves the session for `connectionId` (or the primary connection when omitted) and recovers a thrown
|
|
431
|
+
* error into `{ error }`, so a caller surfaces it as a warning instead of a silent `undefined`.
|
|
430
432
|
*/
|
|
431
433
|
@trace()
|
|
432
434
|
async getRepositoriesForOrgResult(
|
|
@@ -706,11 +708,7 @@ export abstract class GitHostIntegration<
|
|
|
706
708
|
(isAzureDevOpsProvider(providerId) &&
|
|
707
709
|
!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))
|
|
708
710
|
) {
|
|
709
|
-
|
|
710
|
-
return {
|
|
711
|
-
error: new Error(`Unsupported input for provider ${providerId}`),
|
|
712
|
-
duration: performance.now() - start,
|
|
713
|
-
};
|
|
711
|
+
return unsupportedRead(`Unsupported input for provider ${providerId}`, start, 'getIssuesForRepos');
|
|
714
712
|
}
|
|
715
713
|
|
|
716
714
|
let getIssuesOptions: GetIssuesOptions | undefined;
|
|
@@ -723,28 +721,24 @@ export abstract class GitHostIntegration<
|
|
|
723
721
|
}
|
|
724
722
|
|
|
725
723
|
if (organizations.size > 1) {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
724
|
+
return unsupportedRead(
|
|
725
|
+
`Multiple organizations not supported for provider ${providerId}`,
|
|
726
|
+
start,
|
|
727
|
+
'getIssuesForRepos',
|
|
728
|
+
);
|
|
731
729
|
} else if (organizations.size === 0) {
|
|
732
|
-
|
|
733
|
-
return {
|
|
734
|
-
error: new Error(`No organizations found for provider ${providerId}`),
|
|
735
|
-
duration: performance.now() - start,
|
|
736
|
-
};
|
|
730
|
+
return unsupportedRead(`No organizations found for provider ${providerId}`, start, 'getIssuesForRepos');
|
|
737
731
|
}
|
|
738
732
|
|
|
739
733
|
const organization: string = first(organizations.values())!;
|
|
740
734
|
|
|
741
735
|
if (options?.filters != null) {
|
|
742
736
|
if (!api.providerSupportsIssueFilters(providerId, options.filters)) {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
737
|
+
return unsupportedRead(
|
|
738
|
+
`Unsupported filters for provider ${providerId}`,
|
|
739
|
+
start,
|
|
740
|
+
'getIssuesForRepos',
|
|
741
|
+
);
|
|
748
742
|
}
|
|
749
743
|
|
|
750
744
|
let userAccount: ProviderAccount | undefined;
|
|
@@ -756,21 +750,17 @@ export abstract class GitHostIntegration<
|
|
|
756
750
|
}
|
|
757
751
|
|
|
758
752
|
if (userAccount == null) {
|
|
759
|
-
|
|
760
|
-
return {
|
|
761
|
-
error: new Error(`Unable to get current user for ${providerId}`),
|
|
762
|
-
duration: performance.now() - start,
|
|
763
|
-
};
|
|
753
|
+
return unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');
|
|
764
754
|
}
|
|
765
755
|
|
|
766
756
|
const userFilterProperty = userAccount.name;
|
|
767
757
|
|
|
768
758
|
if (userFilterProperty == null) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
759
|
+
return unsupportedRead(
|
|
760
|
+
`Unable to get user property for filter for ${providerId}`,
|
|
761
|
+
start,
|
|
762
|
+
'getIssuesForRepos',
|
|
763
|
+
);
|
|
774
764
|
}
|
|
775
765
|
|
|
776
766
|
getIssuesOptions = {
|
|
@@ -889,11 +879,7 @@ export abstract class GitHostIntegration<
|
|
|
889
879
|
// branch above applies. Without it an unsupported filter (e.g. GitLab has no Mention endpoint) would
|
|
890
880
|
// resolve to no filter property being set and silently degrade to an unfiltered, project-wide read.
|
|
891
881
|
if (!api.providerSupportsIssueFilters(providerId, options.filters)) {
|
|
892
|
-
|
|
893
|
-
return {
|
|
894
|
-
error: new Error(`Unsupported filters for provider ${providerId}`),
|
|
895
|
-
duration: performance.now() - start,
|
|
896
|
-
};
|
|
882
|
+
return unsupportedRead(`Unsupported filters for provider ${providerId}`, start, 'getIssuesForRepos');
|
|
897
883
|
}
|
|
898
884
|
|
|
899
885
|
let userAccount: ProviderAccount | undefined;
|
|
@@ -905,20 +891,16 @@ export abstract class GitHostIntegration<
|
|
|
905
891
|
}
|
|
906
892
|
|
|
907
893
|
if (userAccount == null) {
|
|
908
|
-
|
|
909
|
-
return {
|
|
910
|
-
error: new Error(`Unable to get current user for ${providerId}`),
|
|
911
|
-
duration: performance.now() - start,
|
|
912
|
-
};
|
|
894
|
+
return unsupportedRead(`Unable to get current user for ${providerId}`, start, 'getIssuesForRepos');
|
|
913
895
|
}
|
|
914
896
|
|
|
915
897
|
const userFilterProperty = userAccount.username;
|
|
916
898
|
if (userFilterProperty == null) {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
899
|
+
return unsupportedRead(
|
|
900
|
+
`Unable to get user property for filter for ${providerId}`,
|
|
901
|
+
start,
|
|
902
|
+
'getIssuesForRepos',
|
|
903
|
+
);
|
|
922
904
|
}
|
|
923
905
|
|
|
924
906
|
getIssuesOptions = {
|
|
@@ -1124,21 +1106,17 @@ export abstract class GitHostIntegration<
|
|
|
1124
1106
|
(isAzureDevOpsProvider(providerId) &&
|
|
1125
1107
|
!reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))
|
|
1126
1108
|
) {
|
|
1127
|
-
|
|
1128
|
-
return {
|
|
1129
|
-
error: new Error(`Unsupported input for provider ${providerId}`),
|
|
1130
|
-
duration: performance.now() - start,
|
|
1131
|
-
};
|
|
1109
|
+
return unsupportedRead(`Unsupported input for provider ${providerId}`, start);
|
|
1132
1110
|
}
|
|
1133
1111
|
|
|
1134
1112
|
let getPullRequestsOptions: GetPullRequestsOptions | undefined;
|
|
1135
1113
|
if (options?.filters != null) {
|
|
1136
1114
|
if (!api.providerSupportsPullRequestFilters(providerId, options.filters)) {
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1115
|
+
return unsupportedRead(
|
|
1116
|
+
`Unsupported filters for provider ${providerId}`,
|
|
1117
|
+
start,
|
|
1118
|
+
'getPullRequestsForRepos',
|
|
1119
|
+
);
|
|
1142
1120
|
}
|
|
1143
1121
|
|
|
1144
1122
|
let userAccount: ProviderAccount | undefined;
|
|
@@ -1158,11 +1136,11 @@ export abstract class GitHostIntegration<
|
|
|
1158
1136
|
duration: performance.now() - start,
|
|
1159
1137
|
};
|
|
1160
1138
|
} else if (organizations.size === 0) {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1139
|
+
return unsupportedRead(
|
|
1140
|
+
`No organizations found for provider ${providerId}`,
|
|
1141
|
+
start,
|
|
1142
|
+
'getPullRequestsForRepos',
|
|
1143
|
+
);
|
|
1166
1144
|
}
|
|
1167
1145
|
|
|
1168
1146
|
const organization: string = first(organizations.values())!;
|
|
@@ -1182,11 +1160,11 @@ export abstract class GitHostIntegration<
|
|
|
1182
1160
|
}
|
|
1183
1161
|
|
|
1184
1162
|
if (userAccount == null) {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1163
|
+
return unsupportedRead(
|
|
1164
|
+
`Unable to get current user for ${providerId}`,
|
|
1165
|
+
start,
|
|
1166
|
+
'getPullRequestsForRepos',
|
|
1167
|
+
);
|
|
1190
1168
|
}
|
|
1191
1169
|
|
|
1192
1170
|
let userFilterProperty: string | null;
|
|
@@ -1202,11 +1180,11 @@ export abstract class GitHostIntegration<
|
|
|
1202
1180
|
}
|
|
1203
1181
|
|
|
1204
1182
|
if (userFilterProperty == null) {
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1183
|
+
return unsupportedRead(
|
|
1184
|
+
`Unable to get user property for filter for ${providerId}`,
|
|
1185
|
+
start,
|
|
1186
|
+
'getPullRequestsForRepos',
|
|
1187
|
+
);
|
|
1210
1188
|
}
|
|
1211
1189
|
|
|
1212
1190
|
// Route the "review requested from me" filter to the field each provider actually reads:
|
|
@@ -87,31 +87,13 @@ export abstract class IssuesIntegration<
|
|
|
87
87
|
|
|
88
88
|
protected abstract getProviderResourcesForUser(session: ProviderAuthenticationSession): Promise<T[] | undefined>;
|
|
89
89
|
|
|
90
|
-
@trace()
|
|
91
|
-
async getProjectsForResources(resources: T[], connectionId?: string): Promise<T[] | undefined> {
|
|
92
|
-
return (await this.getProjectsForResourcesResult(resources, connectionId))?.value;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Result-returning core of {@link getProjectsForResources}. Recovers thrown errors into `{ error }` so callers
|
|
97
|
-
* can surface them as warnings rather than silently swallowing them to `undefined`. Implemented by unwrapping
|
|
98
|
-
* the metadata-aware path's `values` so the array-returning contract stays backward compatible.
|
|
99
|
-
*/
|
|
100
|
-
async getProjectsForResourcesResult(
|
|
101
|
-
resources: T[],
|
|
102
|
-
connectionId?: string,
|
|
103
|
-
): Promise<IntegrationResult<T[] | undefined>> {
|
|
104
|
-
const result = await this.getProjectsForResourcesWithMetadataResult(resources, connectionId);
|
|
105
|
-
if (result == null) return undefined;
|
|
106
|
-
if (result.error != null) return { value: result.value?.values, error: result.error };
|
|
107
|
-
return { value: result.value?.values };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
90
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
91
|
+
* Project discovery for a set of resources, returning the SDK collection `{ values, metadata }` (completeness
|
|
92
|
+
* + per-resource failures) so callers can warn on failed resources and set `fetchFailed` without discarding
|
|
93
|
+
* the resources that succeeded. Thrown errors are recovered into `{ error }` for the same reason: a caller
|
|
94
|
+
* surfaces them as a warning rather than swallowing them to `undefined`.
|
|
114
95
|
*/
|
|
96
|
+
@trace()
|
|
115
97
|
async getProjectsForResourcesWithMetadataResult(
|
|
116
98
|
resources: T[],
|
|
117
99
|
connectionId?: string,
|
|
@@ -131,35 +113,6 @@ export abstract class IssuesIntegration<
|
|
|
131
113
|
}
|
|
132
114
|
}
|
|
133
115
|
|
|
134
|
-
async getProjectsForUser(connectionId?: string): Promise<T[] | undefined> {
|
|
135
|
-
return (await this.getProjectsForUserResult(connectionId))?.value;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Result-returning core of {@link getProjectsForUser}. Composes the resource and project result methods so
|
|
140
|
-
* callers can surface per-step warnings. Unwraps the metadata-aware path for the array-returning contract.
|
|
141
|
-
*/
|
|
142
|
-
async getProjectsForUserResult(connectionId?: string): Promise<IntegrationResult<T[] | undefined>> {
|
|
143
|
-
const result = await this.getProjectsForUserWithMetadataResult(connectionId);
|
|
144
|
-
if (result == null) return undefined;
|
|
145
|
-
if (result.error != null) return { value: result.value?.values, error: result.error };
|
|
146
|
-
return { value: result.value?.values };
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Metadata-aware counterpart of {@link getProjectsForUserResult}: composes resource discovery with the
|
|
151
|
-
* metadata-aware project read so ProviderBackend consumers get completeness/failures across resources.
|
|
152
|
-
*/
|
|
153
|
-
async getProjectsForUserWithMetadataResult(
|
|
154
|
-
connectionId?: string,
|
|
155
|
-
): Promise<IntegrationResult<ProviderApiCollectionResult<T> | undefined>> {
|
|
156
|
-
const resources = await this.getResourcesForUserResult(connectionId);
|
|
157
|
-
if (resources?.error != null) return { error: resources.error };
|
|
158
|
-
if (resources?.value == null) return undefined;
|
|
159
|
-
|
|
160
|
-
return this.getProjectsForResourcesWithMetadataResult(resources.value, connectionId);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
116
|
/**
|
|
164
117
|
* Metadata-aware provider project discovery. The default wraps the array-returning
|
|
165
118
|
* {@link getProviderProjectsForResources} in `{ values }` with no metadata, so providers without a
|
|
@@ -1062,7 +1062,7 @@ export abstract class AzureDevOpsIntegrationBase<
|
|
|
1062
1062
|
{ providerId: this.id, resourceId: p.resourceId, projectId: p.name },
|
|
1063
1063
|
);
|
|
1064
1064
|
return {
|
|
1065
|
-
issues: result.values.map(i => fromProviderIssue(i, this
|
|
1065
|
+
issues: result.values.map(i => fromProviderIssue(i, this, { project: p })),
|
|
1066
1066
|
// Azure work-item ids are organization-scoped. Include both org and project so the
|
|
1067
1067
|
// assigned/authored passes dedupe the same item without collapsing another org's item.
|
|
1068
1068
|
projectKey: `${p.resourceId}:${p.id}`,
|