@gitkraken/core-gitlens 0.11.1 → 0.13.0

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 (201) hide show
  1. package/CHANGELOG.md +84 -1
  2. package/dist/git/cache.d.ts +84 -29
  3. package/dist/git/cache.js +188 -54
  4. package/dist/git/cache.js.map +1 -1
  5. package/dist/git/features.d.ts +1 -1
  6. package/dist/git/features.js +4 -0
  7. package/dist/git/features.js.map +1 -1
  8. package/dist/git/models/branch.d.ts +15 -2
  9. package/dist/git/models/branch.js +27 -5
  10. package/dist/git/models/branch.js.map +1 -1
  11. package/dist/git/models/issue.d.ts +3 -1
  12. package/dist/git/models/issue.js.map +1 -1
  13. package/dist/git/models/status.js +1 -1
  14. package/dist/git/models/worktree.d.ts +4 -1
  15. package/dist/git/models/worktree.js +4 -2
  16. package/dist/git/models/worktree.js.map +1 -1
  17. package/dist/git/providers/branches.d.ts +73 -8
  18. package/dist/git/providers/pausedOperations.d.ts +6 -0
  19. package/dist/git/providers/provider.d.ts +34 -2
  20. package/dist/git/providers/status.d.ts +8 -2
  21. package/dist/git/remotes/azure-devops.js +61 -53
  22. package/dist/git/remotes/azure-devops.js.map +1 -1
  23. package/dist/git/service.d.ts +8 -5
  24. package/dist/git/service.js +16 -8
  25. package/dist/git/service.js.map +1 -1
  26. package/dist/git/utils/branch.utils.d.ts +8 -1
  27. package/dist/git/utils/branch.utils.js +30 -1
  28. package/dist/git/utils/branch.utils.js.map +1 -1
  29. package/dist/git/utils/issue.utils.d.ts +3 -1
  30. package/dist/git/utils/issue.utils.js +5 -1
  31. package/dist/git/utils/issue.utils.js.map +1 -1
  32. package/dist/git/watching/changeEvent.d.ts +13 -2
  33. package/dist/git/watching/changeEvent.js +17 -3
  34. package/dist/git/watching/changeEvent.js.map +1 -1
  35. package/dist/git/watching/gitDirPoller.d.ts +111 -0
  36. package/dist/git/watching/gitDirPoller.js +266 -0
  37. package/dist/git/watching/gitDirPoller.js.map +1 -0
  38. package/dist/git/watching/provider.d.ts +16 -0
  39. package/dist/git/watching/watchGroup.d.ts +40 -4
  40. package/dist/git/watching/watchGroup.js +143 -17
  41. package/dist/git/watching/watchGroup.js.map +1 -1
  42. package/dist/git/watching/watchService.d.ts +70 -1
  43. package/dist/git/watching/watchService.js +158 -13
  44. package/dist/git/watching/watchService.js.map +1 -1
  45. package/dist/git/watching/watchSession.d.ts +44 -0
  46. package/dist/git/watching/watchSession.js +91 -6
  47. package/dist/git/watching/watchSession.js.map +1 -1
  48. package/dist/git/watching/watcherPatterns.d.ts +21 -0
  49. package/dist/git/watching/watcherPatterns.js +67 -1
  50. package/dist/git/watching/watcherPatterns.js.map +1 -1
  51. package/dist/git/watching/worktreeSummary.d.ts +34 -7
  52. package/dist/git/watching/worktreeSummary.js +39 -12
  53. package/dist/git/watching/worktreeSummary.js.map +1 -1
  54. package/dist/git-cli/cliGitProvider.d.ts +34 -2
  55. package/dist/git-cli/cliGitProvider.js +119 -17
  56. package/dist/git-cli/cliGitProvider.js.map +1 -1
  57. package/dist/git-cli/exec/commandClassifier.d.ts +15 -0
  58. package/dist/git-cli/exec/commandClassifier.js +48 -2
  59. package/dist/git-cli/exec/commandClassifier.js.map +1 -1
  60. package/dist/git-cli/exec/git.d.ts +15 -3
  61. package/dist/git-cli/exec/git.js +38 -17
  62. package/dist/git-cli/exec/git.js.map +1 -1
  63. package/dist/git-cli/exec/gitQueue.d.ts +2 -0
  64. package/dist/git-cli/exec/gitQueue.js +2 -1
  65. package/dist/git-cli/exec/gitQueue.js.map +1 -1
  66. package/dist/git-cli/exec/indexLock.d.ts +38 -0
  67. package/dist/git-cli/exec/indexLock.js +150 -0
  68. package/dist/git-cli/exec/indexLock.js.map +1 -0
  69. package/dist/git-cli/parsers/worktreeParser.js +42 -2
  70. package/dist/git-cli/parsers/worktreeParser.js.map +1 -1
  71. package/dist/git-cli/providers/branches.d.ts +109 -10
  72. package/dist/git-cli/providers/branches.js +624 -131
  73. package/dist/git-cli/providers/branches.js.map +1 -1
  74. package/dist/git-cli/providers/config.d.ts +9 -5
  75. package/dist/git-cli/providers/config.js +60 -27
  76. package/dist/git-cli/providers/config.js.map +1 -1
  77. package/dist/git-cli/providers/operations.d.ts +17 -0
  78. package/dist/git-cli/providers/operations.js +153 -96
  79. package/dist/git-cli/providers/operations.js.map +1 -1
  80. package/dist/git-cli/providers/pausedOperations.d.ts +8 -0
  81. package/dist/git-cli/providers/pausedOperations.js +60 -40
  82. package/dist/git-cli/providers/pausedOperations.js.map +1 -1
  83. package/dist/git-cli/providers/refs.js +11 -8
  84. package/dist/git-cli/providers/refs.js.map +1 -1
  85. package/dist/git-cli/providers/remotes.js +19 -10
  86. package/dist/git-cli/providers/remotes.js.map +1 -1
  87. package/dist/git-cli/providers/staging.js +40 -15
  88. package/dist/git-cli/providers/staging.js.map +1 -1
  89. package/dist/git-cli/providers/stash.d.ts +2 -0
  90. package/dist/git-cli/providers/stash.js +33 -18
  91. package/dist/git-cli/providers/stash.js.map +1 -1
  92. package/dist/git-cli/providers/status.d.ts +3 -1
  93. package/dist/git-cli/providers/status.js +38 -20
  94. package/dist/git-cli/providers/status.js.map +1 -1
  95. package/dist/git-cli/providers/tags.js +6 -4
  96. package/dist/git-cli/providers/tags.js.map +1 -1
  97. package/dist/git-cli/providers/worktrees.d.ts +1 -0
  98. package/dist/git-cli/providers/worktrees.js +60 -31
  99. package/dist/git-cli/providers/worktrees.js.map +1 -1
  100. package/dist/git-cli/service.d.ts +6 -0
  101. package/dist/git-cli/service.js +5 -2
  102. package/dist/git-cli/service.js.map +1 -1
  103. package/dist/ipc/discovery.js +1 -1
  104. package/dist/plus/agents/providers/claudeCodeTranscript.js +6 -6
  105. package/dist/plus/agents/providers/claudeCodeTranscript.js.map +1 -1
  106. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +1 -1
  107. package/dist/plus/git-github/providers/github/status.d.ts +3 -1
  108. package/dist/plus/git-github/providers/github/status.js +1 -1
  109. package/dist/plus/git-github/providers/github/status.js.map +1 -1
  110. package/dist/plus/integrations/collectionMetadata.d.ts +13 -2
  111. package/dist/plus/integrations/collectionMetadata.js +14 -2
  112. package/dist/plus/integrations/collectionMetadata.js.map +1 -1
  113. package/dist/plus/integrations/index.d.ts +2 -2
  114. package/dist/plus/integrations/index.js.map +1 -1
  115. package/dist/plus/integrations/integrationService.d.ts +1 -0
  116. package/dist/plus/integrations/integrationService.js +1 -1
  117. package/dist/plus/integrations/integrationService.js.map +1 -1
  118. package/dist/plus/integrations/manager.d.ts +1 -0
  119. package/dist/plus/integrations/models/gitHostIntegration.d.ts +41 -5
  120. package/dist/plus/integrations/models/gitHostIntegration.js +109 -30
  121. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -1
  122. package/dist/plus/integrations/models/integration.js +1 -1
  123. package/dist/plus/integrations/models/issueReads.d.ts +17 -4
  124. package/dist/plus/integrations/providers/apiClients.d.ts +2 -0
  125. package/dist/plus/integrations/providers/apiClients.js +7 -1
  126. package/dist/plus/integrations/providers/apiClients.js.map +1 -1
  127. package/dist/plus/integrations/providers/azure/azure.d.ts +5 -4
  128. package/dist/plus/integrations/providers/azure/azure.js +38 -77
  129. package/dist/plus/integrations/providers/azure/azure.js.map +1 -1
  130. package/dist/plus/integrations/providers/azure/azure.utils.js +20 -17
  131. package/dist/plus/integrations/providers/azure/azure.utils.js.map +1 -1
  132. package/dist/plus/integrations/providers/azure/models.d.ts +27 -10
  133. package/dist/plus/integrations/providers/azure/models.js +40 -20
  134. package/dist/plus/integrations/providers/azure/models.js.map +1 -1
  135. package/dist/plus/integrations/providers/azure/workItemStateCategories.d.ts +23 -0
  136. package/dist/plus/integrations/providers/azure/workItemStateCategories.js +84 -0
  137. package/dist/plus/integrations/providers/azure/workItemStateCategories.js.map +1 -0
  138. package/dist/plus/integrations/providers/azureDevOps.d.ts +44 -0
  139. package/dist/plus/integrations/providers/azureDevOps.js +113 -22
  140. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -1
  141. package/dist/plus/integrations/providers/azureDevOpsServer.d.ts +45 -1
  142. package/dist/plus/integrations/providers/azureDevOpsServer.js +121 -6
  143. package/dist/plus/integrations/providers/azureDevOpsServer.js.map +1 -1
  144. package/dist/plus/integrations/providers/issueSorts.d.ts +0 -1
  145. package/dist/plus/integrations/providers/jira-server.js +29 -19
  146. package/dist/plus/integrations/providers/jira-server.js.map +1 -1
  147. package/dist/plus/integrations/providers/jira.d.ts +5 -2
  148. package/dist/plus/integrations/providers/jira.js +63 -44
  149. package/dist/plus/integrations/providers/jira.js.map +1 -1
  150. package/dist/plus/integrations/providers/jiraIssueByKey.d.ts +3 -4
  151. package/dist/plus/integrations/providers/jiraIssueByKey.js +3 -4
  152. package/dist/plus/integrations/providers/jiraIssueByKey.js.map +1 -1
  153. package/dist/plus/integrations/providers/linearIssuesEtag.d.ts +5 -5
  154. package/dist/plus/integrations/providers/linearIssuesEtag.js +6 -6
  155. package/dist/plus/integrations/providers/linearIssuesEtag.js.map +1 -1
  156. package/dist/plus/integrations/providers/models.d.ts +12 -3
  157. package/dist/plus/integrations/providers/models.js +16 -9
  158. package/dist/plus/integrations/providers/models.js.map +1 -1
  159. package/dist/plus/integrations/providers/providersApi.d.ts +21 -33
  160. package/dist/plus/integrations/providers/providersApi.js +159 -49
  161. package/dist/plus/integrations/providers/providersApi.js.map +1 -1
  162. package/dist/plus/integrations/providers/utils/jiraIssueDrains.d.ts +49 -15
  163. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js +132 -10
  164. package/dist/plus/integrations/providers/utils/jiraIssueDrains.js.map +1 -1
  165. package/dist/plus/integrations/providers/utils/providerPaging.js +8 -2
  166. package/dist/plus/integrations/providers/utils/providerPaging.js.map +1 -1
  167. package/dist/plus/integrations/reads/cursors.js +1 -1
  168. package/dist/plus/integrations/reads/drains.d.ts +0 -1
  169. package/dist/plus/integrations/reads/filters.d.ts +3 -3
  170. package/dist/plus/integrations/reads/filters.js.map +1 -1
  171. package/dist/plus/integrations/reads/hierarchy.js +2 -2
  172. package/dist/plus/integrations/reads/hierarchy.js.map +1 -1
  173. package/dist/plus/integrations/reads/hierarchy.utils.d.ts +13 -0
  174. package/dist/plus/integrations/reads/hierarchy.utils.js +26 -1
  175. package/dist/plus/integrations/reads/hierarchy.utils.js.map +1 -1
  176. package/dist/plus/integrations/reads/issueBatch.d.ts +2 -1
  177. package/dist/plus/integrations/reads/issueBatch.js +1 -1
  178. package/dist/plus/integrations/reads/issueBatch.js.map +1 -1
  179. package/dist/plus/integrations/reads/issueTracker.js +27 -18
  180. package/dist/plus/integrations/reads/issueTracker.js.map +1 -1
  181. package/dist/plus/integrations/reads/issues.d.ts +2 -1
  182. package/dist/plus/integrations/reads/issues.js +19 -4
  183. package/dist/plus/integrations/reads/issues.js.map +1 -1
  184. package/dist/plus/integrations/reads/pullRequestBatch.js +1 -1
  185. package/dist/plus/integrations/reads/resolveRepository.js +12 -3
  186. package/dist/plus/integrations/reads/resolveRepository.js.map +1 -1
  187. package/dist/plus/integrations/reads/warnings.d.ts +11 -4
  188. package/dist/plus/integrations/reads/warnings.js +15 -5
  189. package/dist/plus/integrations/reads/warnings.js.map +1 -1
  190. package/dist/plus/integrations/results.d.ts +48 -4
  191. package/dist/plus/integrations/results.js +33 -13
  192. package/dist/plus/integrations/results.js.map +1 -1
  193. package/dist/plus/integrations/utils/integration.utils.d.ts +6 -1
  194. package/dist/plus/integrations/utils/integration.utils.js +8 -1
  195. package/dist/plus/integrations/utils/integration.utils.js.map +1 -1
  196. package/dist/utils/env/node/exec.js +2 -2
  197. package/dist/utils/promiseCache.d.ts +10 -0
  198. package/dist/utils/promiseCache.js +17 -2
  199. package/dist/utils/promiseCache.js.map +1 -1
  200. package/docs/integrations.md +93 -31
  201. package/package.json +2 -2
@@ -12,9 +12,9 @@ import { isProviderUnreachableError, toError } from "../errors.js";
12
12
  import "../constants.js";
13
13
  import { isAzureProviderId } from "../providers/providerErrors.js";
14
14
  import { attributeScopedAuthFailures, hasOnlyScopedAuthFailures, markCredentialRefusals, toCollectionScopeFailure } from "../collectionMetadata.js";
15
- import { throwIfAllSettledFailed } from "../providers/utils/providerPaging.js";
16
15
  import { areDomainsOnSameHost } from "../utils/domain.utils.js";
17
16
  import { isSelfManagedHostIntegrationId } from "../utils/integration.utils.js";
17
+ import { throwIfAllSettledFailed } from "../providers/utils/providerPaging.js";
18
18
  import { providersMetadata } from "../providers/models.js";
19
19
  import { RejectedTokenTracker } from "../authentication/rejectedTokenTracker.js";
20
20
  import { getCachedIssue } from "./issueCache.js";
@@ -1,6 +1,6 @@
1
1
  import { IssueShape, IssueSorting, IssueStateFilter } from "../../../git/models/issue.js";
2
2
  import { IssueFilter } from "../providerFilters.js";
3
- import { CollectionMetadata } from "@gitkraken/provider-apis";
3
+ import { CollectionMetadata, CollectionScope } from "@gitkraken/provider-apis";
4
4
  //#region ../plus/integrations/src/models/issueReads.d.ts
5
5
  /**
6
6
  * The result and option contracts of the integration layer's issue reads — the shapes a PROVIDER returns to the
@@ -105,9 +105,22 @@ export type ProjectIssuesRequest<T> = {
105
105
  project: T;
106
106
  options: IssuesForProjectOptions;
107
107
  };
108
+ /** How a truncated project read could be recovered: see {@link ProjectIssuesDrain}. */
109
+ export type ProjectIssuesRecovery = 'narrow-scope' | 'none';
110
+ /**
111
+ * One project's issues as a tracker read them. A truncated result whose `metadata` reports a failure or an omission is
112
+ * explained by it; one whose metadata reports neither is a cut the facade reports for the project when it names its
113
+ * `scope` (Jira, whose drains record every other cut in their metadata), and for the read as a whole otherwise, where
114
+ * `narrow-scope` is not offered.
115
+ */
108
116
  export type ProjectIssuesDrain = {
109
117
  values: IssueShape[];
110
118
  metadata?: CollectionMetadata;
119
+ /**
120
+ * The scope the provider records this project's failures under, so a cut the facade reports names the project
121
+ * the same way: a Jira Cloud project by its key, a Jira Data Center one by its id. Omitted names no scope.
122
+ */
123
+ scope?: CollectionScope;
111
124
  } & ({
112
125
  truncated: false;
113
126
  } | {
@@ -116,7 +129,7 @@ export type ProjectIssuesDrain = {
116
129
  * `narrow-scope` means a smaller server-side scope avoids this truncation. `none` covers incomplete
117
130
  * results without that guarantee, including Linear's client-side assignee filtering.
118
131
  */
119
- recovery: 'narrow-scope' | 'none';
132
+ recovery: ProjectIssuesRecovery;
120
133
  });
121
134
  /**
122
135
  * Options for the REPO-scoped issue read (`GitHostIntegration.getMyIssuesForRepos*`), the git-host counterpart of
@@ -183,8 +196,8 @@ export type SearchMyIssuesOptions = {
183
196
  /**
184
197
  * Which issue states to read. Omitted reads open issues only.
185
198
  *
186
- * Honored by the issue trackers that declare `ProviderMetadata.supportsIssueStates` (Jira, Jira Data Center,
187
- * Linear). The git hosts' account-wide reads ignore it and keep their own open-only default.
199
+ * Honored by providers declaring `ProviderMetadata.supportsIssueStates`, including Azure DevOps Services and
200
+ * Server. Other git hosts keep their own open-only account-wide default.
188
201
  */
189
202
  state?: IssueStateFilter;
190
203
  /**
@@ -1,5 +1,6 @@
1
1
  import { Disposable } from "../../../utils/disposable.js";
2
2
  import { GitHubApi } from "../../git-github/api/github.js";
3
+ import { AzureWorkItemStatesCache } from "./azure/workItemStateCategories.js";
3
4
  import { AzureDevOpsApi } from "./azure/azure.js";
4
5
  import { BitbucketApi } from "./bitbucket/bitbucket.js";
5
6
  import "./github/github.js";
@@ -13,6 +14,7 @@ import { IntegrationServiceContext } from "../context.js";
13
14
  * offline/limited runtimes.
14
15
  */
15
16
  export interface ApiClients {
17
+ readonly azureWorkItemStates: AzureWorkItemStatesCache;
16
18
  readonly github: Promise<GitHubApi | undefined>;
17
19
  readonly gitlab: Promise<GitLabApi | undefined>;
18
20
  readonly bitbucket: Promise<BitbucketApi | undefined>;
@@ -1,4 +1,5 @@
1
1
  import { getScopedLogger } from "../../../utils/logger.scoped.js";
2
+ import { AzureWorkItemStatesCache } from "./azure/workItemStateCategories.js";
2
3
  //#region ../plus/integrations/src/providers/apiClients.ts
3
4
  /**
4
5
  * Lazily constructs + memoizes the API clients from the runtime context, pushing each to `disposables` for
@@ -6,6 +7,10 @@ import { getScopedLogger } from "../../../utils/logger.scoped.js";
6
7
  * ownership (the host used to build these and inject them back through the context — a pure round-trip).
7
8
  */
8
9
  function createApiClients(ctx, disposables) {
10
+ const azureWorkItemStates = new AzureWorkItemStatesCache();
11
+ disposables.push(ctx.config.onDidChange((e) => {
12
+ if (e.httpProxy) azureWorkItemStates.clear();
13
+ }), { dispose: () => azureWorkItemStates.clear() });
9
14
  let github;
10
15
  let gitlab;
11
16
  let bitbucket;
@@ -22,6 +27,7 @@ function createApiClients(ctx, disposables) {
22
27
  }
23
28
  };
24
29
  return {
30
+ azureWorkItemStates,
25
31
  get github() {
26
32
  return github ??= build(async () => (await import(
27
33
  /* webpackChunkName: "integrations" */
@@ -44,7 +50,7 @@ function createApiClients(ctx, disposables) {
44
50
  return azure ??= build(async () => (await import(
45
51
  /* webpackChunkName: "integrations" */
46
52
  "./azure/azure.js"
47
- )).createAzureDevOpsApi(ctx));
53
+ )).createAzureDevOpsApi(ctx, azureWorkItemStates));
48
54
  }
49
55
  };
50
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"apiClients.js","names":[],"sources":["../../../../../plus/integrations/src/providers/apiClients.ts"],"sourcesContent":["import type { Disposable } from '@gitlens/utils/disposable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport type { AzureDevOpsApi } from './azure/azure.js';\nimport type { BitbucketApi } from './bitbucket/bitbucket.js';\nimport type { GitHubApi } from './github/github.js';\nimport type { GitLabApi } from './gitlab/gitlab.js';\n\n/**\n * The per-provider API clients, owned and built by the package. `GitLabApi`/`BitbucketApi`/`AzureDevOpsApi`\n * live in the package; `GitHubApi` comes from `@gitlens/git-github` (shared with the host's GitHub git\n * provider, which reads the manager's memoized instance via `manager.github`). `undefined` is tolerated for\n * offline/limited runtimes.\n */\nexport interface ApiClients {\n\treadonly github: Promise<GitHubApi | undefined>;\n\treadonly gitlab: Promise<GitLabApi | undefined>;\n\treadonly bitbucket: Promise<BitbucketApi | undefined>;\n\treadonly azure: Promise<AzureDevOpsApi | undefined>;\n}\n\n/**\n * Lazily constructs + memoizes the API clients from the runtime context, pushing each to `disposables` for\n * teardown. Mirrors the lazy-chunked construction the host's `Container` did before the package took\n * ownership (the host used to build these and inject them back through the context — a pure round-trip).\n */\nexport function createApiClients(ctx: IntegrationServiceContext, disposables: Disposable[]): ApiClients {\n\tlet github: Promise<GitHubApi | undefined> | undefined;\n\tlet gitlab: Promise<GitLabApi | undefined> | undefined;\n\tlet bitbucket: Promise<BitbucketApi | undefined> | undefined;\n\tlet azure: Promise<AzureDevOpsApi | undefined> | undefined;\n\n\tconst build = async <T extends Disposable>(load: () => Promise<T>): Promise<T | undefined> => {\n\t\tconst scope = getScopedLogger();\n\t\ttry {\n\t\t\tconst api = await load();\n\t\t\tdisposables.push(api);\n\t\t\treturn api;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex, 'Failed to construct integration API client');\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\treturn {\n\t\tget github() {\n\t\t\treturn (github ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './github/github.js')).createGitHubApi(ctx),\n\t\t\t));\n\t\t},\n\t\tget gitlab() {\n\t\t\treturn (gitlab ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './gitlab/gitlab.js')).createGitLabApi(ctx),\n\t\t\t));\n\t\t},\n\t\tget bitbucket() {\n\t\t\treturn (bitbucket ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './bitbucket/bitbucket.js')).createBitbucketApi(\n\t\t\t\t\tctx,\n\t\t\t\t),\n\t\t\t));\n\t\t},\n\t\tget azure() {\n\t\t\treturn (azure ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './azure/azure.js')).createAzureDevOpsApi(ctx),\n\t\t\t));\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,iBAAiB,KAAgC,aAAuC;CACvG,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,QAAQ,OAA6B,SAAmD;EAC7F,MAAM,QAAQ,gBAAgB;EAC9B,IAAI;GACH,MAAM,MAAM,MAAM,KAAK;GACvB,YAAY,KAAK,GAAG;GACpB,OAAO;EACR,SAAS,IAAI;GACZ,OAAO,MAAM,IAAI,4CAA4C;GAC7D;EACD;CACD;CAEA,OAAO;EACN,IAAI,SAAS;GACZ,OAAQ,WAAW,MAAM,aACvB,MAAM;;IAA8C;EAAqB,CAAE,gBAAgB,GAAG,CAChG;EACD;EACA,IAAI,SAAS;GACZ,OAAQ,WAAW,MAAM,aACvB,MAAM;;IAA8C;EAAqB,CAAE,gBAAgB,GAAG,CAChG;EACD;EACA,IAAI,YAAY;GACf,OAAQ,cAAc,MAAM,aAC1B,MAAM;;IAA8C;EAA2B,CAAE,mBACjF,GACD,CACD;EACD;EACA,IAAI,QAAQ;GACX,OAAQ,UAAU,MAAM,aACtB,MAAM;;IAA8C;EAAmB,CAAE,qBAAqB,GAAG,CACnG;EACD;CACD;AACD"}
1
+ {"version":3,"file":"apiClients.js","names":[],"sources":["../../../../../plus/integrations/src/providers/apiClients.ts"],"sourcesContent":["import type { Disposable } from '@gitlens/utils/disposable.js';\nimport { getScopedLogger } from '@gitlens/utils/logger.scoped.js';\nimport type { IntegrationServiceContext } from '../context.js';\nimport type { AzureDevOpsApi } from './azure/azure.js';\nimport { AzureWorkItemStatesCache } from './azure/workItemStateCategories.js';\nimport type { BitbucketApi } from './bitbucket/bitbucket.js';\nimport type { GitHubApi } from './github/github.js';\nimport type { GitLabApi } from './gitlab/gitlab.js';\n\n/**\n * The per-provider API clients, owned and built by the package. `GitLabApi`/`BitbucketApi`/`AzureDevOpsApi`\n * live in the package; `GitHubApi` comes from `@gitlens/git-github` (shared with the host's GitHub git\n * provider, which reads the manager's memoized instance via `manager.github`). `undefined` is tolerated for\n * offline/limited runtimes.\n */\nexport interface ApiClients {\n\treadonly azureWorkItemStates: AzureWorkItemStatesCache;\n\treadonly github: Promise<GitHubApi | undefined>;\n\treadonly gitlab: Promise<GitLabApi | undefined>;\n\treadonly bitbucket: Promise<BitbucketApi | undefined>;\n\treadonly azure: Promise<AzureDevOpsApi | undefined>;\n}\n\n/**\n * Lazily constructs + memoizes the API clients from the runtime context, pushing each to `disposables` for\n * teardown. Mirrors the lazy-chunked construction the host's `Container` did before the package took\n * ownership (the host used to build these and inject them back through the context — a pure round-trip).\n */\nexport function createApiClients(ctx: IntegrationServiceContext, disposables: Disposable[]): ApiClients {\n\tconst azureWorkItemStates = new AzureWorkItemStatesCache();\n\tdisposables.push(\n\t\tctx.config.onDidChange(e => {\n\t\t\tif (e.httpProxy) {\n\t\t\t\tazureWorkItemStates.clear();\n\t\t\t}\n\t\t}),\n\t\t{ dispose: () => azureWorkItemStates.clear() },\n\t);\n\tlet github: Promise<GitHubApi | undefined> | undefined;\n\tlet gitlab: Promise<GitLabApi | undefined> | undefined;\n\tlet bitbucket: Promise<BitbucketApi | undefined> | undefined;\n\tlet azure: Promise<AzureDevOpsApi | undefined> | undefined;\n\n\tconst build = async <T extends Disposable>(load: () => Promise<T>): Promise<T | undefined> => {\n\t\tconst scope = getScopedLogger();\n\t\ttry {\n\t\t\tconst api = await load();\n\t\t\tdisposables.push(api);\n\t\t\treturn api;\n\t\t} catch (ex) {\n\t\t\tscope?.error(ex, 'Failed to construct integration API client');\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\treturn {\n\t\tazureWorkItemStates: azureWorkItemStates,\n\t\tget github() {\n\t\t\treturn (github ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './github/github.js')).createGitHubApi(ctx),\n\t\t\t));\n\t\t},\n\t\tget gitlab() {\n\t\t\treturn (gitlab ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './gitlab/gitlab.js')).createGitLabApi(ctx),\n\t\t\t));\n\t\t},\n\t\tget bitbucket() {\n\t\t\treturn (bitbucket ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './bitbucket/bitbucket.js')).createBitbucketApi(\n\t\t\t\t\tctx,\n\t\t\t\t),\n\t\t\t));\n\t\t},\n\t\tget azure() {\n\t\t\treturn (azure ??= build(async () =>\n\t\t\t\t(await import(/* webpackChunkName: \"integrations\" */ './azure/azure.js')).createAzureDevOpsApi(\n\t\t\t\t\tctx,\n\t\t\t\t\tazureWorkItemStates,\n\t\t\t\t),\n\t\t\t));\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;AA4BA,SAAgB,iBAAiB,KAAgC,aAAuC;CACvG,MAAM,sBAAsB,IAAI,yBAAyB;CACzD,YAAY,KACX,IAAI,OAAO,aAAY,MAAK;EAC3B,IAAI,EAAE,WACL,oBAAoB,MAAM;CAE5B,CAAC,GACD,EAAE,eAAe,oBAAoB,MAAM,EAAE,CAC9C;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,MAAM,QAAQ,OAA6B,SAAmD;EAC7F,MAAM,QAAQ,gBAAgB;EAC9B,IAAI;GACH,MAAM,MAAM,MAAM,KAAK;GACvB,YAAY,KAAK,GAAG;GACpB,OAAO;EACR,SAAS,IAAI;GACZ,OAAO,MAAM,IAAI,4CAA4C;GAC7D;EACD;CACD;CAEA,OAAO;EACe;EACrB,IAAI,SAAS;GACZ,OAAQ,WAAW,MAAM,aACvB,MAAM;;IAA8C;EAAqB,CAAE,gBAAgB,GAAG,CAChG;EACD;EACA,IAAI,SAAS;GACZ,OAAQ,WAAW,MAAM,aACvB,MAAM;;IAA8C;EAAqB,CAAE,gBAAgB,GAAG,CAChG;EACD;EACA,IAAI,YAAY;GACf,OAAQ,cAAc,MAAM,aAC1B,MAAM;;IAA8C;EAA2B,CAAE,mBACjF,GACD,CACD;EACD;EACA,IAAI,QAAQ;GACX,OAAQ,UAAU,MAAM,aACtB,MAAM;;IAA8C;EAAmB,CAAE,qBACzE,KACA,mBACD,CACD;EACD;CACD;AACD"}
@@ -8,6 +8,7 @@ import { DefaultBranch } from "../../../../git/models/defaultBranch.js";
8
8
  import { RepositoryMetadata } from "../../../../git/models/repositoryMetadata.js";
9
9
  import { TokenWithInfo } from "../../authentication/models.js";
10
10
  import { AzureProjectDescriptor, AzureWorkItemStateCategory } from "./models.js";
11
+ import { AzureWorkItemStatesCache } from "./workItemStateCategories.js";
11
12
  import { ProviderIssueSearchPage } from "../../models/issueReads.js";
12
13
  import { ProviderApiConfig } from "../apiConfig.js";
13
14
  import { IntegrationServiceContext } from "../../context.js";
@@ -15,7 +16,8 @@ import { IntegrationServiceContext } from "../../context.js";
15
16
  export declare class AzureDevOpsApi implements Disposable {
16
17
  private readonly config;
17
18
  private readonly _disposable;
18
- private _workItemStates;
19
+ private readonly _workItemStates;
20
+ private readonly ownsWorkItemStates;
19
21
  private readonly _forkRepositoryUrls;
20
22
  /**
21
23
  * The ordered ids each filtered work-item search's first page queried, paged through by its continuations. Kept
@@ -23,7 +25,7 @@ export declare class AzureDevOpsApi implements Disposable {
23
25
  * the capacity leaves room for repeated first pages before an idle pagination's snapshot is the one evicted.
24
26
  */
25
27
  private readonly _workItemSearches;
26
- constructor(config: ProviderApiConfig);
28
+ constructor(config: ProviderApiConfig, workItemStates?: AzureWorkItemStatesCache);
27
29
  dispose(): void;
28
30
  private resetCaches;
29
31
  getPullRequestForBranch(provider: Provider, token: TokenWithInfo, owner: string, repo: string, branch: string, options: {
@@ -68,7 +70,6 @@ export declare class AzureDevOpsApi implements Disposable {
68
70
  getWorkItemStateCategory(issueType: string, state: string, provider: Provider, token: TokenWithInfo, owner: string, projectName: string, options: {
69
71
  baseUrl: string;
70
72
  }): Promise<AzureWorkItemStateCategory | undefined>;
71
- private retrieveWorkItemTypeStates;
72
73
  getRepositoryMetadata(provider: Provider, token: TokenWithInfo, owner: string, repo: string, options: {
73
74
  baseUrl: string;
74
75
  }, cancellation?: AbortSignal): Promise<RepositoryMetadata | undefined>;
@@ -137,6 +138,6 @@ export declare class AzureDevOpsApi implements Disposable {
137
138
  private handleRequestError;
138
139
  }
139
140
  /** Wires an {@link AzureDevOpsApi} from the full runtime context, mapping `ctx` down to the narrow config. */
140
- export declare function createAzureDevOpsApi(ctx: IntegrationServiceContext): AzureDevOpsApi;
141
+ export declare function createAzureDevOpsApi(ctx: IntegrationServiceContext, workItemStates?: AzureWorkItemStatesCache): AzureDevOpsApi;
141
142
  //#endregion
142
143
  //# sourceMappingURL=azure.d.ts.map
@@ -5,15 +5,16 @@ import { trace } from "../../../../utils/decorators/log.js";
5
5
  import { PromiseCache } from "../../../../utils/promiseCache.js";
6
6
  import __decorate from "../../../../_virtual/@oxc-project+runtime/helpers/esm/decorate.js";
7
7
  import { AuthenticationError, RequestClientError, RequestNotFoundError } from "../../../../git/errors.js";
8
+ import { sha256, uuid } from "../../../../utils/crypto.js";
8
9
  import { maybeStopWatch } from "../../../../utils/stopwatch.js";
9
10
  import { base64 } from "../../../../utils/base64.js";
10
- import { sha256, uuid } from "../../../../utils/crypto.js";
11
11
  import { effectiveIssueSort } from "../../../../git/utils/issue.utils.js";
12
12
  import { ProviderFetchError, isRateLimitResponse, toRateLimitError } from "../../errors.js";
13
- import { azureWorkItemSearchResultLimit, parseAzureWorkItemSearchCursor, toAzureSearchPageSize, toAzureWorkItemSearchCursorKey, toAzureWorkItemSearchWiql } from "./search.js";
14
13
  import { decodePathSegment } from "../../utils/domain.utils.js";
15
- import { baseProviderApiConfig } from "../apiConfig.js";
14
+ import { azureWorkItemSearchResultLimit, parseAzureWorkItemSearchCursor, toAzureSearchPageSize, toAzureWorkItemSearchCursorKey, toAzureWorkItemSearchWiql } from "./search.js";
16
15
  import { azurePullRequestStatusToState, azureWorkItemsStateCategoryToState, encodeAzurePathSegment, fromAzurePullRequest, fromAzureWorkItem, getAzurePullRequestWebUrl, isClosedAzurePullRequestStatus, isClosedAzureWorkItemStateCategory, normalizeAzureBranchName, sanitizeAzureRepositoryUrl } from "./models.js";
16
+ import { AzureWorkItemStatesCache, getAzureWorkItemTypeStatesPath } from "./workItemStateCategories.js";
17
+ import { baseProviderApiConfig } from "../apiConfig.js";
17
18
  import * as l10n from "@vscode/l10n";
18
19
  //#region ../plus/integrations/src/providers/azure/azure.ts
19
20
  const forkRepositoryUrlCacheTtl = 3e5;
@@ -33,44 +34,11 @@ function parseAzureRepositoryDescriptor(repo) {
33
34
  repoName
34
35
  };
35
36
  }
36
- var WorkItemStates = class {
37
- _categories = /* @__PURE__ */ new Map();
38
- _types = /* @__PURE__ */ new Map();
39
- getStateCategory(project, workItemType, stateName) {
40
- return this._categories.get(this.getStateKey(project, workItemType, stateName));
41
- }
42
- clear() {
43
- this._categories.clear();
44
- this._types.clear();
45
- }
46
- saveTypeStates(project, workItemType, states) {
47
- this.clearTypeStates(project, workItemType);
48
- this._types.set(this.getTypeKey(project, workItemType), states);
49
- for (const state of states) this._categories.set(this.getStateKey(project, workItemType, state.name), state.category);
50
- }
51
- hasTypeStates(project, workItemType) {
52
- return this._types.has(this.getTypeKey(project, workItemType));
53
- }
54
- clearTypeStates(project, workItemType) {
55
- const states = this._types.get(this.getTypeKey(project, workItemType));
56
- if (states == null) return;
57
- for (const state of states) this._categories.delete(this.getStateKey(project, workItemType, state.name));
58
- }
59
- getStateKey(project, workItemType, stateName) {
60
- return JSON.stringify([
61
- project,
62
- workItemType,
63
- stateName
64
- ]);
65
- }
66
- getTypeKey(project, workItemType) {
67
- return JSON.stringify([project, workItemType]);
68
- }
69
- };
70
37
  var AzureDevOpsApi = class {
71
38
  config;
72
39
  _disposable;
73
- _workItemStates = new WorkItemStates();
40
+ _workItemStates;
41
+ ownsWorkItemStates;
74
42
  _forkRepositoryUrls = new PromiseCache({
75
43
  capacity: 100,
76
44
  createTTL: forkRepositoryUrlCacheTtl
@@ -85,15 +53,17 @@ var AzureDevOpsApi = class {
85
53
  accessTTL: workItemSearchSnapshotTtl,
86
54
  createTTL: workItemSearchSnapshotMaxTtl
87
55
  });
88
- constructor(config) {
56
+ constructor(config, workItemStates) {
89
57
  this.config = config;
58
+ this._workItemStates = workItemStates ?? new AzureWorkItemStatesCache();
59
+ this.ownsWorkItemStates = workItemStates == null;
90
60
  this._disposable = config.onConfigChanged?.(() => this.resetCaches());
91
61
  }
92
62
  dispose() {
93
63
  this._disposable?.dispose();
94
64
  }
95
65
  resetCaches() {
96
- this._workItemStates.clear();
66
+ if (this.ownsWorkItemStates) this._workItemStates.clear();
97
67
  this._forkRepositoryUrls.clear();
98
68
  this._workItemSearches.clear();
99
69
  }
@@ -150,8 +120,17 @@ var AzureDevOpsApi = class {
150
120
  async getIssueOrPullRequest(provider, token, owner, repo, id, options) {
151
121
  const scope = getScopedLogger();
152
122
  const { projectName, repoName } = parseAzureRepositoryDescriptor(repo);
153
- if (options?.type === void 0 || options?.type === "issue") try {
154
- const issueResult = await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(owner)}/${encodeAzurePathSegment(projectName)}/_apis/wit/workItems/${encodeAzurePathSegment(id)}`, { method: "GET" }, scope);
123
+ if (options?.type === void 0 || options?.type === "issue") {
124
+ let issueResult;
125
+ try {
126
+ issueResult = await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(owner)}/${encodeAzurePathSegment(projectName)}/_apis/wit/workItems/${encodeAzurePathSegment(id)}`, { method: "GET" }, scope);
127
+ } catch (ex) {
128
+ if (ex instanceof AuthenticationError) throw ex;
129
+ if (ex.original?.status !== 404) {
130
+ scope?.error(ex);
131
+ return;
132
+ }
133
+ }
155
134
  if (issueResult != null) {
156
135
  const issueType = issueResult.fields["System.WorkItemType"];
157
136
  const state = issueResult.fields["System.State"];
@@ -169,12 +148,6 @@ var AzureDevOpsApi = class {
169
148
  url: issueResult._links.html.href
170
149
  };
171
150
  }
172
- } catch (ex) {
173
- if (ex instanceof AuthenticationError) throw ex;
174
- if (ex.original?.status !== 404) {
175
- scope?.error(ex);
176
- return;
177
- }
178
151
  }
179
152
  if (options?.type === void 0 || options?.type === "pullrequest") try {
180
153
  const prResult = await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(owner)}/${encodeAzurePathSegment(projectName)}/_apis/git/repositories/${encodeAzurePathSegment(repoName)}/pullRequests/${encodeAzurePathSegment(id)}`, { method: "GET" }, scope);
@@ -201,14 +174,9 @@ var AzureDevOpsApi = class {
201
174
  }
202
175
  async getIssue(provider, token, project, id, options) {
203
176
  const scope = getScopedLogger();
177
+ let issueResult;
204
178
  try {
205
- const issueResult = await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(project.resourceName)}/${encodeAzurePathSegment(project.name)}/_apis/wit/workItems/${encodeAzurePathSegment(id)}`, { method: "GET" }, scope);
206
- if (issueResult != null) {
207
- const issueType = issueResult.fields["System.WorkItemType"];
208
- const state = issueResult.fields["System.State"];
209
- const stateCategory = await this.getWorkItemStateCategory(issueType, state, provider, token, project.resourceName, project.name, options);
210
- return fromAzureWorkItem(issueResult, provider, project, stateCategory, "point");
211
- }
179
+ issueResult = await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(project.resourceName)}/${encodeAzurePathSegment(project.name)}/_apis/wit/workItems/${encodeAzurePathSegment(id)}`, { method: "GET" }, scope);
212
180
  } catch (ex) {
213
181
  if (ex instanceof AuthenticationError) throw ex;
214
182
  if (ex.original?.status !== 404) {
@@ -216,6 +184,12 @@ var AzureDevOpsApi = class {
216
184
  return;
217
185
  }
218
186
  }
187
+ if (issueResult != null) {
188
+ const issueType = issueResult.fields["System.WorkItemType"];
189
+ const state = issueResult.fields["System.State"];
190
+ const stateCategory = await this.getWorkItemStateCategory(issueType, state, provider, token, project.resourceName, project.name, options);
191
+ return fromAzureWorkItem(issueResult, provider, project, stateCategory, "point");
192
+ }
219
193
  }
220
194
  async getAccountForCommit(provider, token, owner, repo, rev, baseUrl, _options) {
221
195
  const scope = getScopedLogger();
@@ -279,26 +253,13 @@ var AzureDevOpsApi = class {
279
253
  }
280
254
  }
281
255
  async getWorkItemStateCategory(issueType, state, provider, token, owner, projectName, options) {
282
- const project = JSON.stringify([
283
- options.baseUrl,
284
- owner,
285
- projectName
286
- ]);
287
- const category = this._workItemStates.getStateCategory(project, issueType, state);
288
- if (category != null) return category;
289
- const states = await this.retrieveWorkItemTypeStates(issueType, provider, token, owner, projectName, options);
290
- this._workItemStates.saveTypeStates(project, issueType, states);
291
- return this._workItemStates.getStateCategory(project, issueType, state);
292
- }
293
- async retrieveWorkItemTypeStates(workItemType, provider, token, owner, projectName, options) {
294
- const scope = getScopedLogger();
295
- try {
296
- return (await this.request(provider, token, options?.baseUrl, `${encodeAzurePathSegment(owner)}/${encodeAzurePathSegment(projectName)}/_apis/wit/workItemTypes/${encodeAzurePathSegment(workItemType)}/states`, { method: "GET" }, scope))?.value ?? [];
297
- } catch (ex) {
298
- if (ex instanceof AuthenticationError) throw ex;
299
- scope?.error(ex);
300
- return [];
301
- }
256
+ return (await this._workItemStates.getStates({
257
+ baseUrl: options.baseUrl,
258
+ namespace: owner,
259
+ project: projectName,
260
+ token: token.accessToken,
261
+ isPAT: true
262
+ }, issueType, () => this.request(provider, token, options.baseUrl, getAzureWorkItemTypeStatesPath(owner, projectName, issueType), { method: "GET" }, void 0))).find((s) => s.name === state)?.category;
302
263
  }
303
264
  async getRepositoryMetadata(provider, token, owner, repo, options, cancellation) {
304
265
  const scope = getScopedLogger();
@@ -638,8 +599,8 @@ __decorate([trace({ args: (provider, token, collection) => ({
638
599
  collection
639
600
  }) })], AzureDevOpsApi.prototype, "countWorkItems", null);
640
601
  /** Wires an {@link AzureDevOpsApi} from the full runtime context, mapping `ctx` down to the narrow config. */
641
- function createAzureDevOpsApi(ctx) {
642
- return new AzureDevOpsApi(baseProviderApiConfig(ctx));
602
+ function createAzureDevOpsApi(ctx, workItemStates) {
603
+ return new AzureDevOpsApi(baseProviderApiConfig(ctx), workItemStates);
643
604
  }
644
605
  //#endregion
645
606
  export { AzureDevOpsApi, createAzureDevOpsApi };