@gitkraken/core-gitlens 0.7.0 → 0.7.2

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 (125) hide show
  1. package/CHANGELOG.md +28 -2
  2. package/dist/git/remotes/azure-devops.js +3 -3
  3. package/dist/git/remotes/azure-devops.js.map +1 -1
  4. package/dist/plus/integrations/authentication/configuredIntegrationService.js +9 -2
  5. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -1
  6. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +1 -1
  7. package/dist/plus/integrations/collectionMetadata.d.ts +48 -3
  8. package/dist/plus/integrations/collectionMetadata.js +138 -8
  9. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  10. package/dist/plus/integrations/errors.d.ts +3 -1
  11. package/dist/plus/integrations/errors.js +7 -3
  12. package/dist/plus/integrations/errors.js.map +1 -1
  13. package/dist/plus/integrations/index.d.ts +3 -3
  14. package/dist/plus/integrations/index.js.map +1 -1
  15. package/dist/plus/integrations/integrationService.d.ts +35 -1
  16. package/dist/plus/integrations/integrationService.js +90 -43
  17. package/dist/plus/integrations/integrationService.js.map +1 -1
  18. package/dist/plus/integrations/lite.js +5 -4
  19. package/dist/plus/integrations/lite.js.map +1 -1
  20. package/dist/plus/integrations/manager.d.ts +68 -23
  21. package/dist/plus/integrations/models/gitHostIntegration.d.ts +31 -15
  22. package/dist/plus/integrations/models/gitHostIntegration.js +71 -22
  23. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  24. package/dist/plus/integrations/models/integration.d.ts +70 -12
  25. package/dist/plus/integrations/models/integration.js +56 -1
  26. package/dist/plus/integrations/models/integration.js.map +1 -1
  27. package/dist/plus/integrations/models/issueReads.d.ts +17 -0
  28. package/dist/plus/integrations/models/issuesIntegration.js +2 -0
  29. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -1
  30. package/dist/plus/integrations/models/pullRequestReads.d.ts +26 -0
  31. package/dist/plus/integrations/providers/azure/azure.d.ts +66 -1
  32. package/dist/plus/integrations/providers/azure/azure.js +192 -12
  33. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  34. package/dist/plus/integrations/providers/azure/search.d.ts +144 -0
  35. package/dist/plus/integrations/providers/azure/search.js +250 -0
  36. package/dist/plus/integrations/providers/azure/search.js.map +1 -0
  37. package/dist/plus/integrations/providers/azureDevOps.d.ts +73 -36
  38. package/dist/plus/integrations/providers/azureDevOps.js +191 -122
  39. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  40. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +176 -0
  41. package/dist/plus/integrations/providers/azureDevOpsServer.js +560 -0
  42. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -0
  43. package/dist/plus/integrations/providers/bitbucket-server/discovery.d.ts +12 -0
  44. package/dist/plus/integrations/providers/bitbucket-server/discovery.js +128 -0
  45. package/dist/plus/integrations/providers/bitbucket-server/discovery.js.map +1 -0
  46. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +10 -1
  47. package/dist/plus/integrations/providers/bitbucket-server/models.js +3 -2
  48. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -1
  49. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.d.ts +58 -0
  50. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js +485 -0
  51. package/dist/plus/integrations/providers/bitbucket-server/pullRequestSearch.js.map +1 -0
  52. package/dist/plus/integrations/providers/bitbucket-server.d.ts +61 -3
  53. package/dist/plus/integrations/providers/bitbucket-server.js +114 -20
  54. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -1
  55. package/dist/plus/integrations/providers/bitbucket.d.ts +9 -1
  56. package/dist/plus/integrations/providers/bitbucket.js +13 -2
  57. package/dist/plus/integrations/providers/bitbucket.js.map +1 -1
  58. package/dist/plus/integrations/providers/github.d.ts +6 -6
  59. package/dist/plus/integrations/providers/github.js +35 -34
  60. package/dist/plus/integrations/providers/github.js.map +1 -1
  61. package/dist/plus/integrations/providers/gitlab.d.ts +6 -4
  62. package/dist/plus/integrations/providers/gitlab.js +32 -28
  63. package/dist/plus/integrations/providers/gitlab.js.map +1 -1
  64. package/dist/plus/integrations/providers/issueSorts.d.ts +1 -0
  65. package/dist/plus/integrations/providers/jira-server.d.ts +9 -0
  66. package/dist/plus/integrations/providers/jira-server.js +15 -7
  67. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  68. package/dist/plus/integrations/providers/jira.d.ts +9 -0
  69. package/dist/plus/integrations/providers/jira.js +14 -2
  70. package/dist/plus/integrations/providers/jira.js.map +1 -1
  71. package/dist/plus/integrations/providers/linear.js +2 -2
  72. package/dist/plus/integrations/providers/models.d.ts +10 -1
  73. package/dist/plus/integrations/providers/models.js +86 -0
  74. package/dist/plus/integrations/providers/models.js.map +1 -1
  75. package/dist/plus/integrations/providers/providersApi.d.ts +10 -0
  76. package/dist/plus/integrations/providers/providersApi.js +18 -3
  77. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  78. package/dist/plus/integrations/providers/utils.d.ts +12 -1
  79. package/dist/plus/integrations/providers/utils.js +36 -6
  80. package/dist/plus/integrations/providers/utils.js.map +1 -1
  81. package/dist/plus/integrations/reads/broaden.js +6 -6
  82. package/dist/plus/integrations/reads/broaden.js.map +1 -1
  83. package/dist/plus/integrations/reads/context.d.ts +1 -1
  84. package/dist/plus/integrations/reads/counts.d.ts +18 -4
  85. package/dist/plus/integrations/reads/counts.js +66 -15
  86. package/dist/plus/integrations/reads/counts.js.map +1 -1
  87. package/dist/plus/integrations/reads/cursors.js +1 -1
  88. package/dist/plus/integrations/reads/drains.d.ts +2 -1
  89. package/dist/plus/integrations/reads/drains.js +1 -1
  90. package/dist/plus/integrations/reads/filters.d.ts +1 -1
  91. package/dist/plus/integrations/reads/filters.js +17 -12
  92. package/dist/plus/integrations/reads/filters.js.map +1 -1
  93. package/dist/plus/integrations/reads/hierarchy.js +2 -2
  94. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  95. package/dist/plus/integrations/reads/hierarchy.utils.js +1 -1
  96. package/dist/plus/integrations/reads/issueBatch.js +1 -1
  97. package/dist/plus/integrations/reads/issueTracker.js +2 -2
  98. package/dist/plus/integrations/reads/issues.js +2 -2
  99. package/dist/plus/integrations/reads/paging.js +1 -1
  100. package/dist/plus/integrations/reads/resolveRepository.d.ts +12 -11
  101. package/dist/plus/integrations/reads/resolveRepository.js +110 -19
  102. package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
  103. package/dist/plus/integrations/reads/searchIssues.js +4 -2
  104. package/dist/plus/integrations/reads/searchIssues.js.map +1 -1
  105. package/dist/plus/integrations/reads/searchPullRequests.js +9 -3
  106. package/dist/plus/integrations/reads/searchPullRequests.js.map +1 -1
  107. package/dist/plus/integrations/reads/sweeps.js +1 -1
  108. package/dist/plus/integrations/reads/trackerIssue.d.ts +9 -5
  109. package/dist/plus/integrations/reads/trackerIssue.js +15 -9
  110. package/dist/plus/integrations/reads/trackerIssue.js.map +1 -1
  111. package/dist/plus/integrations/reads/warnings.d.ts +6 -2
  112. package/dist/plus/integrations/reads/warnings.js +15 -19
  113. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  114. package/dist/plus/integrations/results.d.ts +84 -6
  115. package/dist/plus/integrations/results.js +9 -2
  116. package/dist/plus/integrations/results.js.map +1 -1
  117. package/dist/plus/integrations/utils/domain.utils.d.ts +19 -0
  118. package/dist/plus/integrations/utils/domain.utils.js +36 -1
  119. package/dist/plus/integrations/utils/domain.utils.js.map +1 -1
  120. package/dist/plus/integrations/utils/integration.utils.d.ts +1 -0
  121. package/dist/plus/integrations/utils/integration.utils.js +12 -1
  122. package/dist/plus/integrations/utils/integration.utils.js.map +1 -1
  123. package/docs/integrations.md +263 -74
  124. package/docs/kepler-read-api-parity.md +19 -6
  125. package/package.json +1 -1
@@ -1,16 +1,18 @@
1
1
  import { filterMap, flatten } from "../../utils/iterable.js";
2
2
  import { getScopedLogger } from "../../utils/logger.scoped.js";
3
+ import { mapSettledBounded } from "../../utils/promise.js";
3
4
  import { debug, trace } from "../../utils/decorators/log.js";
4
5
  import __decorate from "../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
5
6
  import { fromDisposables } from "../../utils/disposable.js";
6
7
  import { Emitter } from "../../utils/event.js";
7
8
  import { gate } from "../../utils/decorators/gate.js";
9
+ import { toError } from "./errors.js";
8
10
  import { GitCloudHostIntegrationId, GitSelfManagedHostIntegrationId, IssuesCloudHostIntegrationId, IssuesSelfManagedHostIntegrationId } from "./constants.js";
9
11
  import { getSupportedCloudIntegrationIds, isSupportedCloudIntegrationId, toIntegrationId } from "./authentication/models.js";
10
12
  import { CloudIntegrationService } from "./authentication/cloudIntegrationService.js";
13
+ import { getRemoteHostMatcher, hostFromDomain, sameConfiguredBaseUrl } from "./utils/domain.utils.js";
11
14
  import { convertRemoteProviderIdToIntegrationId, getIntegrationIdForRemote, isCloudSelfManagedHostIntegrationId, isGitCloudHostIntegrationId, isGitSelfManagedHostIntegrationId, isNonExpiringZeroTokenIntegrationId, isSelfManagedHostIntegrationId, remoteProviderTypeForConfig, remoteProviderTypeForIntegration } from "./utils/integration.utils.js";
12
15
  import { providersMetadata } from "./providers/models.js";
13
- import { hostFromDomain, sameConfiguredBaseUrl } from "./utils/domain.utils.js";
14
16
  import { ConfiguredIntegrationService } from "./authentication/configuredIntegrationService.js";
15
17
  import { IntegrationAuthenticationService } from "./authentication/integrationAuthenticationService.js";
16
18
  import { createApiClients } from "./providers/apiClients.js";
@@ -228,7 +230,7 @@ var IntegrationService = class {
228
230
  if (configuredDomain == null) throw new Error(`Domain is required for '${id}' integration`);
229
231
  integration = new (await (import(
230
232
  /* webpackChunkName: "integrations" */
231
- "./providers/azureDevOps.js"
233
+ "./providers/azureDevOpsServer.js"
232
234
  ))).AzureDevOpsServerIntegration(this.ctx, this.authenticationService, this.getProvidersApi.bind(this), this._onDidChangeIntegrationConnection, configuredDomain);
233
235
  domain = configuredDomain;
234
236
  break;
@@ -237,7 +239,7 @@ var IntegrationService = class {
237
239
  }
238
240
  integration = new (await (import(
239
241
  /* webpackChunkName: "integrations" */
240
- "./providers/azureDevOps.js"
242
+ "./providers/azureDevOpsServer.js"
241
243
  ))).AzureDevOpsServerIntegration(this.ctx, this.authenticationService, this.getProvidersApi.bind(this), this._onDidChangeIntegrationConnection, domain);
242
244
  break;
243
245
  case "jira":
@@ -309,48 +311,51 @@ var IntegrationService = class {
309
311
  return integration?.type === "git" ? integration : void 0;
310
312
  }
311
313
  async getMyIssues(integrationIds, options) {
312
- const integrations = /* @__PURE__ */ new Map();
313
- const hostingIntegrationIds = integrationIds?.filter((id) => id in GitCloudHostIntegrationId || id in GitSelfManagedHostIntegrationId);
314
314
  const openRemotesByIntegrationId = /* @__PURE__ */ new Map();
315
315
  let hasOpenAzureRepository = false;
316
316
  for (const remote of await this.ctx.repositories.getOpenRemotes()) {
317
- const remoteIntegration = await this.getByRemote(remote);
318
- if (remoteIntegration == null) continue;
319
- if (remoteIntegration.id === "azureDevOps") hasOpenAzureRepository = true;
320
- for (const integrationId of hostingIntegrationIds?.length ? hostingIntegrationIds : [...Object.values(GitCloudHostIntegrationId), ...Object.values(GitSelfManagedHostIntegrationId)]) if (remoteIntegration.id === integrationId && remote.provider?.owner != null && remote.provider?.repoName != null) {
321
- const descriptor = {
322
- key: `${remote.provider.owner}/${remote.provider.repoName}`,
323
- owner: remote.provider.owner,
324
- name: remote.provider.repoName
325
- };
326
- if (openRemotesByIntegrationId.has(integrationId)) openRemotesByIntegrationId.get(integrationId)?.push(descriptor);
327
- else openRemotesByIntegrationId.set(integrationId, [descriptor]);
328
- }
317
+ const integrationId = getIntegrationIdForRemote(remote.provider);
318
+ if (integrationId == null) continue;
319
+ if (integrationId === "azureDevOps") hasOpenAzureRepository = true;
320
+ if (remote.provider?.owner == null || remote.provider?.repoName == null) continue;
321
+ const repo = {
322
+ key: `${remote.provider.owner}/${remote.provider.repoName}`,
323
+ owner: remote.provider.owner,
324
+ name: remote.provider.repoName
325
+ };
326
+ const remotes = openRemotesByIntegrationId.get(integrationId);
327
+ if (remotes != null) remotes.push({
328
+ remote,
329
+ repo
330
+ });
331
+ else openRemotesByIntegrationId.set(integrationId, [{
332
+ remote,
333
+ repo
334
+ }]);
329
335
  }
336
+ const integrations = /* @__PURE__ */ new Map();
330
337
  for (const integrationId of integrationIds?.length ? integrationIds : [
331
338
  ...Object.values(GitCloudHostIntegrationId),
332
339
  ...Object.values(IssuesCloudHostIntegrationId),
333
340
  ...Object.values(IssuesSelfManagedHostIntegrationId),
334
341
  ...Object.values(GitSelfManagedHostIntegrationId)
335
342
  ]) {
336
- const integration = await this.get(integrationId);
337
- const isInvalidIntegration = options?.openRepositoriesOnly && integrationId !== "azureDevOps" && (isGitCloudHostIntegrationId(integrationId) || isGitSelfManagedHostIntegrationId(integrationId)) && !openRemotesByIntegrationId.has(integrationId) || integrationId === "azureDevOps" && !hasOpenAzureRepository;
338
- if (integration == null || isInvalidIntegration) continue;
339
- integrations.set(integration, options?.openRepositoriesOnly && !isInvalidIntegration ? openRemotesByIntegrationId.get(integrationId) : void 0);
343
+ if (integrationId === "azureDevOps" && !hasOpenAzureRepository) continue;
344
+ const integrationsForId = await this.getIntegrationsForAccountWideRead(integrationId);
345
+ for (const integration of integrationsForId) {
346
+ const openRemotes = this.getOpenRemotesForHost(integration, integrationsForId, openRemotesByIntegrationId.get(integrationId));
347
+ if (options?.openRepositoriesOnly && integrationId !== "azureDevOps" && (isGitCloudHostIntegrationId(integrationId) || isGitSelfManagedHostIntegrationId(integrationId)) && openRemotes == null) continue;
348
+ integrations.set(integration, options?.openRepositoriesOnly ? openRemotes : void 0);
349
+ }
340
350
  }
341
351
  if (integrations.size === 0) return void 0;
342
352
  return this.getMyIssuesCore(integrations, options?.cancellation);
343
353
  }
344
354
  async getMyIssuesCore(integrations, cancellation) {
345
355
  const start = performance.now();
346
- const promises = [];
347
- for (const [integration, repos] of integrations) {
348
- if (integration == null) continue;
349
- promises.push(integration.searchMyIssuesResult(repos, cancellation));
350
- }
351
- const results = await Promise.allSettled(promises);
356
+ const results = await mapSettledBounded([...integrations], 6, ([integration, repos]) => integration.searchMyIssuesResult(repos, cancellation));
352
357
  const successfulResults = [...flatten(filterMap(results, (r) => r.status === "fulfilled" && r.value?.value != null ? r.value.value : void 0))];
353
- const errors = [...filterMap(results, (r) => r.status === "fulfilled" && r.value?.error != null ? r.value.error : void 0)];
358
+ const errors = [...filterMap(results, (r) => r.status === "rejected" ? toError(r.reason) : r.value?.error)];
354
359
  return {
355
360
  value: successfulResults,
356
361
  error: errors.length === 0 ? void 0 : errors.length === 1 ? errors[0] : new AggregateError(errors, "Failed to get some issues"),
@@ -391,27 +396,15 @@ var IntegrationService = class {
391
396
  }
392
397
  async getMyPullRequests(integrationIds, cancellation, options) {
393
398
  const integrations = /* @__PURE__ */ new Map();
394
- for (const integrationId of integrationIds?.length ? integrationIds : Object.values(GitCloudHostIntegrationId)) {
395
- let integration;
396
- try {
397
- integration = await this.get(integrationId);
398
- } catch {}
399
- if (integration == null) continue;
400
- integrations.set(integration, void 0);
401
- }
399
+ for (const integrationId of integrationIds?.length ? integrationIds : [...Object.values(GitCloudHostIntegrationId), ...Object.values(GitSelfManagedHostIntegrationId)]) for (const integration of await this.getIntegrationsForAccountWideRead(integrationId)) integrations.set(integration, void 0);
402
400
  if (integrations.size === 0) return void 0;
403
401
  return this.getMyPullRequestsCore(integrations, cancellation, options);
404
402
  }
405
403
  async getMyPullRequestsCore(integrations, cancellation, options) {
406
404
  const start = performance.now();
407
- const promises = [];
408
- for (const [integration, repos] of integrations) {
409
- if (integration == null) continue;
410
- promises.push(integration.searchMyPullRequests(repos, cancellation, options));
411
- }
412
- const results = await Promise.allSettled(promises);
405
+ const results = await mapSettledBounded([...integrations], 6, ([integration, repos]) => integration.searchMyPullRequests(repos, cancellation, options));
413
406
  const successfulResults = [...flatten(filterMap(results, (r) => r.status === "fulfilled" && r.value?.value != null ? r.value.value : void 0))];
414
- const errors = [...filterMap(results, (r) => r.status === "fulfilled" && r.value?.error != null ? r.value.error : void 0)];
407
+ const errors = [...filterMap(results, (r) => r.status === "rejected" ? toError(r.reason) : r.value?.error)];
415
408
  return {
416
409
  value: successfulResults,
417
410
  error: errors.length === 0 ? void 0 : errors.length === 1 ? errors[0] : new AggregateError(errors, "Failed to get some pull requests"),
@@ -481,6 +474,60 @@ var IntegrationService = class {
481
474
  return;
482
475
  }
483
476
  }
477
+ /**
478
+ * Resolves every integration instance an account-wide read must cover for `id`. A cloud id has one instance;
479
+ * a self-managed id has one per configured host, so the read fans out over all of them rather than `get(id)`
480
+ * silently picking whichever host was cached (or flagged primary) first, which dropped every other GitHub
481
+ * Enterprise server, GitLab instance, Bitbucket Data Center, Azure DevOps Server or Jira Data Center the user
482
+ * is connected to (#5873).
483
+ *
484
+ * Hosts come from every configured connection, local as well as cloud: that is the set `get(id)` already picked
485
+ * its primary from, and a locally configured host is as much the user's as a cloud-synced one. This is where it
486
+ * departs from {@link getSupportedCloudIntegrations}, which only walks cloud connections because it exists to
487
+ * sync them. The two share the per-host resolution and the fallback to whatever instance is already cached when
488
+ * no host is configured. A lookup that throws counts as "not available", like {@link getIntegrationForRead}.
489
+ */
490
+ async getIntegrationsForAccountWideRead(id) {
491
+ const hosts = /* @__PURE__ */ new Set();
492
+ if (isSelfManagedHostIntegrationId(id)) for (const { domain } of this.getConfigured(id)) {
493
+ const host = hostFromDomain(domain) ?? domain;
494
+ if (host) hosts.add(host);
495
+ }
496
+ const targets = hosts.size !== 0 ? [...hosts] : [void 0];
497
+ const integrations = [];
498
+ for (const host of targets) {
499
+ const integration = await this.get(id, host).catch(() => void 0);
500
+ if (integration != null) integrations.push(integration);
501
+ }
502
+ return integrations;
503
+ }
504
+ async isConnectedForAccountWideRead(id, options) {
505
+ const integrations = await this.getIntegrationsForAccountWideRead(id);
506
+ return (await mapSettledBounded(integrations, 6, async (integration) => {
507
+ return (integration.maybeConnected ?? await integration.isConnected()) && (!options?.access || await integration.access());
508
+ })).some((result) => result.status === "fulfilled" && result.value);
509
+ }
510
+ /**
511
+ * The open repositories to scope `integration`'s read to, out of the remotes open for its integration id.
512
+ *
513
+ * With a single host for the id (every cloud id, and a self-managed id with one configured host) every remote
514
+ * is that host's, as it was before the read fanned out, so a remote addressed through an SSH alias or a custom
515
+ * domain keeps its repositories scoped. With several hosts a remote belongs to the one configured host it
516
+ * names, compared the way {@link resolveRepository} compares them: exactly for a web remote, by hostname for an
517
+ * SSH/git one, whose parsed domain has lost any port. A remote naming no host, or several (two ports on one
518
+ * machine), is credited to none, like `resolveRepository`'s `host-mismatch`: asking one server about another
519
+ * server's `owner/name` reads a different repository, or nothing, under the right name.
520
+ */
521
+ getOpenRemotesForHost(integration, integrationsForId, remotes) {
522
+ if (!remotes?.length) return void 0;
523
+ if (integrationsForId.length <= 1) return remotes.map((r) => r.repo);
524
+ const owned = remotes.filter((r) => {
525
+ const hostsMatch = getRemoteHostMatcher(r.remote.scheme);
526
+ const matching = integrationsForId.filter((i) => hostsMatch(r.remote.provider?.domain, i.domain));
527
+ return matching.length === 1 && matching[0] === integration;
528
+ });
529
+ return owned.length ? owned.map((r) => r.repo) : void 0;
530
+ }
484
531
  resolveDomainForRead(id, connectionId, domain) {
485
532
  if (!isSelfManagedHostIntegrationId(id)) return void 0;
486
533
  return (connectionId != null ? this.getConfiguredConnectionDomain(id, connectionId) : void 0) ?? hostFromDomain(domain) ?? this.primaryConfiguredDomain(id);