@gitkraken/core-gitlens 0.3.0 → 0.4.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 (378) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/README.md +13 -10
  3. package/dist/git/cache.d.ts +12 -6
  4. package/dist/git/cache.d.ts.map +1 -1
  5. package/dist/git/cache.js +40 -39
  6. package/dist/git/cache.js.map +1 -1
  7. package/dist/git/context.d.ts +23 -3
  8. package/dist/git/context.d.ts.map +1 -1
  9. package/dist/git/context.js.map +1 -1
  10. package/dist/git/features.d.ts +1 -1
  11. package/dist/git/features.d.ts.map +1 -1
  12. package/dist/git/features.js +1 -0
  13. package/dist/git/features.js.map +1 -1
  14. package/dist/git/models/graph.d.ts +96 -0
  15. package/dist/git/models/graph.d.ts.map +1 -1
  16. package/dist/git/models/graph.js +24 -1
  17. package/dist/git/models/graph.js.map +1 -1
  18. package/dist/git/models/remoteProvider.d.ts +1 -0
  19. package/dist/git/models/remoteProvider.d.ts.map +1 -1
  20. package/dist/git/models/remoteProvider.js.map +1 -1
  21. package/dist/git/models/repository.d.ts +21 -12
  22. package/dist/git/models/repository.d.ts.map +1 -1
  23. package/dist/git/models/repository.js +70 -84
  24. package/dist/git/models/repository.js.map +1 -1
  25. package/dist/git/models/statusFile.d.ts +9 -0
  26. package/dist/git/models/statusFile.d.ts.map +1 -1
  27. package/dist/git/models/statusFile.js +11 -0
  28. package/dist/git/models/statusFile.js.map +1 -1
  29. package/dist/git/providers/commits.d.ts +4 -0
  30. package/dist/git/providers/commits.d.ts.map +1 -1
  31. package/dist/git/providers/config.d.ts +1 -3
  32. package/dist/git/providers/config.d.ts.map +1 -1
  33. package/dist/git/providers/operations.d.ts +40 -13
  34. package/dist/git/providers/operations.d.ts.map +1 -1
  35. package/dist/git/providers/worktrees.d.ts +2 -0
  36. package/dist/git/providers/worktrees.d.ts.map +1 -1
  37. package/dist/git/remotes/custom.d.ts +2 -0
  38. package/dist/git/remotes/custom.d.ts.map +1 -1
  39. package/dist/git/remotes/custom.js +20 -0
  40. package/dist/git/remotes/custom.js.map +1 -1
  41. package/dist/git/utils/conflictResolution.utils.d.ts +32 -0
  42. package/dist/git/utils/conflictResolution.utils.d.ts.map +1 -1
  43. package/dist/git/utils/conflictResolution.utils.js +95 -0
  44. package/dist/git/utils/conflictResolution.utils.js.map +1 -1
  45. package/dist/git/utils/contributor.utils.d.ts +3 -0
  46. package/dist/git/utils/contributor.utils.d.ts.map +1 -1
  47. package/dist/git/utils/contributor.utils.js +22 -0
  48. package/dist/git/utils/contributor.utils.js.map +1 -1
  49. package/dist/git/utils/reachability.utils.d.ts +37 -0
  50. package/dist/git/utils/reachability.utils.d.ts.map +1 -0
  51. package/dist/git/utils/reachability.utils.js +96 -0
  52. package/dist/git/utils/reachability.utils.js.map +1 -0
  53. package/dist/git/watching/watchService.d.ts +4 -2
  54. package/dist/git/watching/watchService.d.ts.map +1 -1
  55. package/dist/git/watching/watchService.js +8 -3
  56. package/dist/git/watching/watchService.js.map +1 -1
  57. package/dist/git/watching/watchSession.d.ts +14 -12
  58. package/dist/git/watching/watchSession.d.ts.map +1 -1
  59. package/dist/git/watching/watchSession.js +56 -55
  60. package/dist/git/watching/watchSession.js.map +1 -1
  61. package/dist/git-cli/providers/branches.d.ts.map +1 -1
  62. package/dist/git-cli/providers/branches.js +1 -0
  63. package/dist/git-cli/providers/branches.js.map +1 -1
  64. package/dist/git-cli/providers/commits.d.ts +1 -0
  65. package/dist/git-cli/providers/commits.d.ts.map +1 -1
  66. package/dist/git-cli/providers/commits.js +12 -0
  67. package/dist/git-cli/providers/commits.js.map +1 -1
  68. package/dist/git-cli/providers/config.d.ts +8 -4
  69. package/dist/git-cli/providers/config.d.ts.map +1 -1
  70. package/dist/git-cli/providers/config.js +62 -39
  71. package/dist/git-cli/providers/config.js.map +1 -1
  72. package/dist/git-cli/providers/diff.d.ts.map +1 -1
  73. package/dist/git-cli/providers/diff.js +1 -1
  74. package/dist/git-cli/providers/diff.js.map +1 -1
  75. package/dist/git-cli/providers/graph.d.ts.map +1 -1
  76. package/dist/git-cli/providers/graph.js +132 -14
  77. package/dist/git-cli/providers/graph.js.map +1 -1
  78. package/dist/git-cli/providers/operations.d.ts +7 -5
  79. package/dist/git-cli/providers/operations.d.ts.map +1 -1
  80. package/dist/git-cli/providers/operations.js +118 -95
  81. package/dist/git-cli/providers/operations.js.map +1 -1
  82. package/dist/git-cli/providers/stash.d.ts.map +1 -1
  83. package/dist/git-cli/providers/stash.js +20 -2
  84. package/dist/git-cli/providers/stash.js.map +1 -1
  85. package/dist/git-cli/providers/status.d.ts.map +1 -1
  86. package/dist/git-cli/providers/status.js +5 -2
  87. package/dist/git-cli/providers/status.js.map +1 -1
  88. package/dist/git-cli/providers/worktrees.d.ts +2 -0
  89. package/dist/git-cli/providers/worktrees.d.ts.map +1 -1
  90. package/dist/git-cli/providers/worktrees.js +3 -0
  91. package/dist/git-cli/providers/worktrees.js.map +1 -1
  92. package/dist/ipc/discovery.d.ts +22 -0
  93. package/dist/ipc/discovery.d.ts.map +1 -1
  94. package/dist/ipc/discovery.js +111 -2
  95. package/dist/ipc/discovery.js.map +1 -1
  96. package/dist/plus/agents/providers/claudeCodeProvider.d.ts +73 -20
  97. package/dist/plus/agents/providers/claudeCodeProvider.d.ts.map +1 -1
  98. package/dist/plus/agents/providers/claudeCodeProvider.js +394 -88
  99. package/dist/plus/agents/providers/claudeCodeProvider.js.map +1 -1
  100. package/dist/plus/agents/types.d.ts +62 -11
  101. package/dist/plus/agents/types.d.ts.map +1 -1
  102. package/dist/plus/ai/models/model.d.ts +1 -1
  103. package/dist/plus/ai/models/model.d.ts.map +1 -1
  104. package/dist/plus/ai/models/model.js.map +1 -1
  105. package/dist/plus/ai/models/provider.d.ts +3 -0
  106. package/dist/plus/ai/models/provider.d.ts.map +1 -1
  107. package/dist/plus/ai/providers/gitkrakenProvider.d.ts +1 -1
  108. package/dist/plus/ai/providers/gitkrakenProvider.d.ts.map +1 -1
  109. package/dist/plus/ai/providers/gitkrakenProvider.js +4 -1
  110. package/dist/plus/ai/providers/gitkrakenProvider.js.map +1 -1
  111. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts +4 -3
  112. package/dist/plus/ai/providers/openAICompatibleProviderBase.d.ts.map +1 -1
  113. package/dist/plus/ai/providers/openAICompatibleProviderBase.js +9 -6
  114. package/dist/plus/ai/providers/openAICompatibleProviderBase.js.map +1 -1
  115. package/dist/plus/ai/utils/ai.utils.d.ts.map +1 -1
  116. package/dist/plus/ai/utils/ai.utils.js +6 -4
  117. package/dist/plus/ai/utils/ai.utils.js.map +1 -1
  118. package/dist/plus/git-github/api/github.d.ts +8 -13
  119. package/dist/plus/git-github/api/github.d.ts.map +1 -1
  120. package/dist/plus/git-github/api/github.js +96 -14
  121. package/dist/plus/git-github/api/github.js.map +1 -1
  122. package/dist/plus/git-github/providers/github/refs.js +1 -1
  123. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts +11 -0
  124. package/dist/plus/integrations/authentication/cloudIntegrationService.d.ts.map +1 -0
  125. package/dist/plus/integrations/authentication/cloudIntegrationService.js +90 -0
  126. package/dist/plus/integrations/authentication/cloudIntegrationService.js.map +1 -0
  127. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts +67 -0
  128. package/dist/plus/integrations/authentication/configuredIntegrationService.d.ts.map +1 -0
  129. package/dist/plus/integrations/authentication/configuredIntegrationService.js +295 -0
  130. package/dist/plus/integrations/authentication/configuredIntegrationService.js.map +1 -0
  131. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts +92 -0
  132. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.d.ts.map +1 -0
  133. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js +185 -0
  134. package/dist/plus/integrations/authentication/integrationAuthenticationProvider.js.map +1 -0
  135. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts +62 -0
  136. package/dist/plus/integrations/authentication/integrationAuthenticationService.d.ts.map +1 -0
  137. package/dist/plus/integrations/authentication/integrationAuthenticationService.js +122 -0
  138. package/dist/plus/integrations/authentication/integrationAuthenticationService.js.map +1 -0
  139. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts +15 -0
  140. package/dist/plus/integrations/authentication/manualTokenProvider.d.ts.map +1 -0
  141. package/dist/plus/integrations/authentication/manualTokenProvider.js +49 -0
  142. package/dist/plus/integrations/authentication/manualTokenProvider.js.map +1 -0
  143. package/dist/plus/integrations/authentication/models.d.ts +87 -0
  144. package/dist/plus/integrations/authentication/models.d.ts.map +1 -0
  145. package/dist/plus/integrations/authentication/models.js +64 -0
  146. package/dist/plus/integrations/authentication/models.js.map +1 -0
  147. package/dist/plus/integrations/constants.d.ts +47 -0
  148. package/dist/plus/integrations/constants.d.ts.map +1 -0
  149. package/dist/plus/integrations/constants.js +128 -0
  150. package/dist/plus/integrations/constants.js.map +1 -0
  151. package/dist/plus/integrations/context.d.ts +354 -0
  152. package/dist/plus/integrations/context.d.ts.map +1 -0
  153. package/dist/plus/integrations/context.js +2 -0
  154. package/dist/plus/integrations/context.js.map +1 -0
  155. package/dist/plus/integrations/errors.d.ts +14 -0
  156. package/dist/plus/integrations/errors.d.ts.map +1 -0
  157. package/dist/plus/integrations/errors.js +19 -0
  158. package/dist/plus/integrations/errors.js.map +1 -0
  159. package/dist/plus/integrations/index.d.ts +32 -0
  160. package/dist/plus/integrations/index.d.ts.map +1 -0
  161. package/dist/plus/integrations/index.js +62 -0
  162. package/dist/plus/integrations/index.js.map +1 -0
  163. package/dist/plus/integrations/integrationService.d.ts +98 -0
  164. package/dist/plus/integrations/integrationService.d.ts.map +1 -0
  165. package/dist/plus/integrations/integrationService.js +627 -0
  166. package/dist/plus/integrations/integrationService.js.map +1 -0
  167. package/dist/plus/integrations/models/gitHostIntegration.d.ts +82 -0
  168. package/dist/plus/integrations/models/gitHostIntegration.d.ts.map +1 -0
  169. package/dist/plus/integrations/models/gitHostIntegration.js +522 -0
  170. package/dist/plus/integrations/models/gitHostIntegration.js.map +1 -0
  171. package/dist/plus/integrations/models/integration.d.ts +127 -0
  172. package/dist/plus/integrations/models/integration.d.ts.map +1 -0
  173. package/dist/plus/integrations/models/integration.js +456 -0
  174. package/dist/plus/integrations/models/integration.js.map +1 -0
  175. package/dist/plus/integrations/models/issuesIntegration.d.ts +28 -0
  176. package/dist/plus/integrations/models/issuesIntegration.d.ts.map +1 -0
  177. package/dist/plus/integrations/models/issuesIntegration.js +101 -0
  178. package/dist/plus/integrations/models/issuesIntegration.js.map +1 -0
  179. package/dist/plus/integrations/providers/apiClients.d.ts +25 -0
  180. package/dist/plus/integrations/providers/apiClients.d.ts.map +1 -0
  181. package/dist/plus/integrations/providers/apiClients.js +39 -0
  182. package/dist/plus/integrations/providers/apiClients.js.map +1 -0
  183. package/dist/plus/integrations/providers/azure/azure.d.ts +47 -0
  184. package/dist/plus/integrations/providers/azure/azure.d.ts.map +1 -0
  185. package/dist/plus/integrations/providers/azure/azure.js +444 -0
  186. package/dist/plus/integrations/providers/azure/azure.js.map +1 -0
  187. package/dist/plus/integrations/providers/azure/models.d.ts +286 -0
  188. package/dist/plus/integrations/providers/azure/models.d.ts.map +1 -0
  189. package/dist/plus/integrations/providers/azure/models.js +203 -0
  190. package/dist/plus/integrations/providers/azure/models.js.map +1 -0
  191. package/dist/plus/integrations/providers/azureDevOps.d.ts +95 -0
  192. package/dist/plus/integrations/providers/azureDevOps.d.ts.map +1 -0
  193. package/dist/plus/integrations/providers/azureDevOps.js +432 -0
  194. package/dist/plus/integrations/providers/azureDevOps.js.map +1 -0
  195. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts +42 -0
  196. package/dist/plus/integrations/providers/bitbucket/bitbucket.d.ts.map +1 -0
  197. package/dist/plus/integrations/providers/bitbucket/bitbucket.js +513 -0
  198. package/dist/plus/integrations/providers/bitbucket/bitbucket.js.map +1 -0
  199. package/dist/plus/integrations/providers/bitbucket/models.d.ts +222 -0
  200. package/dist/plus/integrations/providers/bitbucket/models.d.ts.map +1 -0
  201. package/dist/plus/integrations/providers/bitbucket/models.js +158 -0
  202. package/dist/plus/integrations/providers/bitbucket/models.js.map +1 -0
  203. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts +120 -0
  204. package/dist/plus/integrations/providers/bitbucket-server/models.d.ts.map +1 -0
  205. package/dist/plus/integrations/providers/bitbucket-server/models.js +111 -0
  206. package/dist/plus/integrations/providers/bitbucket-server/models.js.map +1 -0
  207. package/dist/plus/integrations/providers/bitbucket-server.d.ts +60 -0
  208. package/dist/plus/integrations/providers/bitbucket-server.d.ts.map +1 -0
  209. package/dist/plus/integrations/providers/bitbucket-server.js +138 -0
  210. package/dist/plus/integrations/providers/bitbucket-server.js.map +1 -0
  211. package/dist/plus/integrations/providers/bitbucket.d.ts +50 -0
  212. package/dist/plus/integrations/providers/bitbucket.d.ts.map +1 -0
  213. package/dist/plus/integrations/providers/bitbucket.js +181 -0
  214. package/dist/plus/integrations/providers/bitbucket.js.map +1 -0
  215. package/dist/plus/integrations/providers/github/github.d.ts +5 -0
  216. package/dist/plus/integrations/providers/github/github.d.ts.map +1 -0
  217. package/dist/plus/integrations/providers/github/github.js +47 -0
  218. package/dist/plus/integrations/providers/github/github.js.map +1 -0
  219. package/dist/plus/integrations/providers/github/github.utils.d.ts +11 -0
  220. package/dist/plus/integrations/providers/github/github.utils.d.ts.map +1 -0
  221. package/dist/plus/integrations/providers/github/github.utils.js +6 -0
  222. package/dist/plus/integrations/providers/github/github.utils.js.map +1 -0
  223. package/dist/plus/integrations/providers/github/models.d.ts +3 -0
  224. package/dist/plus/integrations/providers/github/models.d.ts.map +1 -0
  225. package/dist/plus/integrations/providers/github/models.js +2 -0
  226. package/dist/plus/integrations/providers/github/models.js.map +1 -0
  227. package/dist/plus/integrations/providers/github.d.ts +73 -0
  228. package/dist/plus/integrations/providers/github.d.ts.map +1 -0
  229. package/dist/plus/integrations/providers/github.js +160 -0
  230. package/dist/plus/integrations/providers/github.js.map +1 -0
  231. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts +63 -0
  232. package/dist/plus/integrations/providers/gitlab/gitlab.d.ts.map +1 -0
  233. package/dist/plus/integrations/providers/gitlab/gitlab.js +828 -0
  234. package/dist/plus/integrations/providers/gitlab/gitlab.js.map +1 -0
  235. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts +21 -0
  236. package/dist/plus/integrations/providers/gitlab/gitlab.utils.d.ts.map +1 -0
  237. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js +45 -0
  238. package/dist/plus/integrations/providers/gitlab/gitlab.utils.js.map +1 -0
  239. package/dist/plus/integrations/providers/gitlab/models.d.ts +128 -0
  240. package/dist/plus/integrations/providers/gitlab/models.d.ts.map +1 -0
  241. package/dist/plus/integrations/providers/gitlab/models.js +96 -0
  242. package/dist/plus/integrations/providers/gitlab/models.js.map +1 -0
  243. package/dist/plus/integrations/providers/gitlab.d.ts +79 -0
  244. package/dist/plus/integrations/providers/gitlab.d.ts.map +1 -0
  245. package/dist/plus/integrations/providers/gitlab.js +253 -0
  246. package/dist/plus/integrations/providers/gitlab.js.map +1 -0
  247. package/dist/plus/integrations/providers/jira.d.ts +46 -0
  248. package/dist/plus/integrations/providers/jira.d.ts.map +1 -0
  249. package/dist/plus/integrations/providers/jira.js +255 -0
  250. package/dist/plus/integrations/providers/jira.js.map +1 -0
  251. package/dist/plus/integrations/providers/linear.d.ts +47 -0
  252. package/dist/plus/integrations/providers/linear.d.ts.map +1 -0
  253. package/dist/plus/integrations/providers/linear.js +198 -0
  254. package/dist/plus/integrations/providers/linear.js.map +1 -0
  255. package/dist/plus/integrations/providers/models.d.ts +433 -0
  256. package/dist/plus/integrations/providers/models.d.ts.map +1 -0
  257. package/dist/plus/integrations/providers/models.js +602 -0
  258. package/dist/plus/integrations/providers/models.js.map +1 -0
  259. package/dist/plus/integrations/providers/providersApi.d.ts +129 -0
  260. package/dist/plus/integrations/providers/providersApi.d.ts.map +1 -0
  261. package/dist/plus/integrations/providers/providersApi.js +602 -0
  262. package/dist/plus/integrations/providers/providersApi.js.map +1 -0
  263. package/dist/plus/integrations/providers/utils.d.ts +54 -0
  264. package/dist/plus/integrations/providers/utils.d.ts.map +1 -0
  265. package/dist/plus/integrations/providers/utils.js +262 -0
  266. package/dist/plus/integrations/providers/utils.js.map +1 -0
  267. package/dist/plus/integrations/telemetry.d.ts +26 -0
  268. package/dist/plus/integrations/telemetry.d.ts.map +1 -0
  269. package/dist/plus/integrations/telemetry.js +11 -0
  270. package/dist/plus/integrations/telemetry.js.map +1 -0
  271. package/dist/plus/integrations/utils/integration.utils.d.ts +14 -0
  272. package/dist/plus/integrations/utils/integration.utils.d.ts.map +1 -0
  273. package/dist/plus/integrations/utils/integration.utils.js +111 -0
  274. package/dist/plus/integrations/utils/integration.utils.js.map +1 -0
  275. package/dist/utils/date.d.ts.map +1 -1
  276. package/dist/utils/date.js +6 -0
  277. package/dist/utils/date.js.map +1 -1
  278. package/dist/utils/debounce.js +1 -1
  279. package/dist/utils/disposable.d.ts +15 -2
  280. package/dist/utils/disposable.d.ts.map +1 -1
  281. package/dist/utils/disposable.js.map +1 -1
  282. package/dist/utils/iterable.d.ts +7 -1
  283. package/dist/utils/iterable.d.ts.map +1 -1
  284. package/dist/utils/iterable.js +12 -4
  285. package/dist/utils/iterable.js.map +1 -1
  286. package/dist/utils/object.d.ts +22 -1
  287. package/dist/utils/object.d.ts.map +1 -1
  288. package/dist/utils/object.js +56 -3
  289. package/dist/utils/object.js.map +1 -1
  290. package/dist/utils/paging.js +14 -15
  291. package/dist/utils/paging.js.map +1 -1
  292. package/dist/utils/promiseCache.d.ts.map +1 -1
  293. package/dist/utils/promiseCache.js +12 -4
  294. package/dist/utils/promiseCache.js.map +1 -1
  295. package/dist/utils/string.js +1 -1
  296. package/package.json +43 -2
  297. package/src/git/cache.ts +58 -70
  298. package/src/git/context.ts +25 -3
  299. package/src/git/features.ts +2 -0
  300. package/src/git/models/graph.ts +97 -0
  301. package/src/git/models/remoteProvider.ts +1 -0
  302. package/src/git/models/repository.ts +84 -93
  303. package/src/git/models/statusFile.ts +12 -0
  304. package/src/git/providers/commits.ts +4 -0
  305. package/src/git/providers/config.ts +1 -5
  306. package/src/git/providers/operations.ts +42 -22
  307. package/src/git/providers/worktrees.ts +14 -2
  308. package/src/git/remotes/custom.ts +23 -0
  309. package/src/git/utils/conflictResolution.utils.ts +126 -0
  310. package/src/git/utils/contributor.utils.ts +24 -0
  311. package/src/git/utils/reachability.utils.ts +109 -0
  312. package/src/git/watching/watchService.ts +9 -4
  313. package/src/git/watching/watchSession.ts +61 -55
  314. package/src/git-cli/providers/branches.ts +1 -0
  315. package/src/git-cli/providers/commits.ts +24 -0
  316. package/src/git-cli/providers/config.ts +63 -49
  317. package/src/git-cli/providers/diff.ts +2 -1
  318. package/src/git-cli/providers/graph.ts +145 -14
  319. package/src/git-cli/providers/operations.ts +138 -130
  320. package/src/git-cli/providers/stash.ts +20 -2
  321. package/src/git-cli/providers/status.ts +11 -3
  322. package/src/git-cli/providers/worktrees.ts +17 -2
  323. package/src/ipc/discovery.ts +132 -2
  324. package/src/plus/agents/providers/claudeCodeProvider.ts +430 -90
  325. package/src/plus/agents/types.ts +59 -11
  326. package/src/plus/ai/models/model.ts +1 -0
  327. package/src/plus/ai/models/provider.ts +7 -1
  328. package/src/plus/ai/providers/gitkrakenProvider.ts +4 -0
  329. package/src/plus/ai/providers/openAICompatibleProviderBase.ts +21 -4
  330. package/src/plus/ai/utils/ai.utils.ts +6 -4
  331. package/src/plus/git-github/api/github.ts +131 -31
  332. package/src/plus/git-github/providers/github/refs.ts +1 -1
  333. package/src/plus/integrations/authentication/cloudIntegrationService.ts +120 -0
  334. package/src/plus/integrations/authentication/configuredIntegrationService.ts +414 -0
  335. package/src/plus/integrations/authentication/integrationAuthenticationProvider.ts +289 -0
  336. package/src/plus/integrations/authentication/integrationAuthenticationService.ts +144 -0
  337. package/src/plus/integrations/authentication/manualTokenProvider.ts +72 -0
  338. package/src/plus/integrations/authentication/models.ts +168 -0
  339. package/src/plus/integrations/constants.ts +169 -0
  340. package/src/plus/integrations/context.ts +383 -0
  341. package/src/plus/integrations/errors.ts +35 -0
  342. package/src/plus/integrations/index.ts +119 -0
  343. package/src/plus/integrations/integrationService.ts +924 -0
  344. package/src/plus/integrations/models/gitHostIntegration.ts +738 -0
  345. package/src/plus/integrations/models/integration.ts +657 -0
  346. package/src/plus/integrations/models/issuesIntegration.ts +124 -0
  347. package/src/plus/integrations/providers/apiClients.ts +72 -0
  348. package/src/plus/integrations/providers/azure/azure.ts +691 -0
  349. package/src/plus/integrations/providers/azure/models.ts +605 -0
  350. package/src/plus/integrations/providers/azureDevOps.ts +677 -0
  351. package/src/plus/integrations/providers/bitbucket/bitbucket.ts +774 -0
  352. package/src/plus/integrations/providers/bitbucket/models.ts +445 -0
  353. package/src/plus/integrations/providers/bitbucket-server/models.ts +252 -0
  354. package/src/plus/integrations/providers/bitbucket-server.ts +282 -0
  355. package/src/plus/integrations/providers/bitbucket.ts +350 -0
  356. package/src/plus/integrations/providers/github/github.ts +64 -0
  357. package/src/plus/integrations/providers/github/github.utils.ts +23 -0
  358. package/src/plus/integrations/providers/github/models.ts +29 -0
  359. package/src/plus/integrations/providers/github.ts +366 -0
  360. package/src/plus/integrations/providers/gitlab/gitlab.ts +1210 -0
  361. package/src/plus/integrations/providers/gitlab/gitlab.utils.ts +71 -0
  362. package/src/plus/integrations/providers/gitlab/models.ts +257 -0
  363. package/src/plus/integrations/providers/gitlab.ts +473 -0
  364. package/src/plus/integrations/providers/jira.ts +359 -0
  365. package/src/plus/integrations/providers/linear.ts +275 -0
  366. package/src/plus/integrations/providers/models.ts +1114 -0
  367. package/src/plus/integrations/providers/providersApi.ts +1126 -0
  368. package/src/plus/integrations/providers/utils.ts +359 -0
  369. package/src/plus/integrations/telemetry.ts +29 -0
  370. package/src/plus/integrations/utils/integration.utils.ts +138 -0
  371. package/src/utils/date.ts +5 -0
  372. package/src/utils/debounce.ts +1 -1
  373. package/src/utils/disposable.ts +15 -2
  374. package/src/utils/iterable.ts +14 -3
  375. package/src/utils/object.ts +55 -4
  376. package/src/utils/paging.ts +14 -14
  377. package/src/utils/promiseCache.ts +24 -16
  378. package/src/utils/string.ts +1 -1
@@ -0,0 +1,738 @@
1
+ import type { Account, UnidentifiedAuthor } from '../../../git/models/author.js';
2
+ import type { DefaultBranch } from '../../../git/models/defaultBranch.js';
3
+ import type { IssueOrPullRequestState as PullRequestState } from '../../../git/models/issueOrPullRequest.js';
4
+ import type { PullRequest, PullRequestMergeMethod } from '../../../git/models/pullRequest.js';
5
+ import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
6
+ import type { ResourceDescriptor } from '../../../git/models/resourceDescriptor.js';
7
+ import type { PullRequestUrlIdentity } from '../../../git/utils/pullRequest.utils.js';
8
+ import { gate } from '../../../utils/decorators/gate.js';
9
+ import { trace } from '../../../utils/decorators/log.js';
10
+ import { first } from '../../../utils/iterable.js';
11
+ import { Logger } from '../../../utils/logger.js';
12
+ import { getScopedLogger } from '../../../utils/logger.scoped.js';
13
+ import type { PagedResult } from '../../../utils/paging.js';
14
+ import type { ProviderAuthenticationSession } from '../authentication/models.js';
15
+ import type { IntegrationIds } from '../constants.js';
16
+ import { GitCloudHostIntegrationId } from '../constants.js';
17
+ import type {
18
+ GetIssuesOptions,
19
+ GetPullRequestsOptions,
20
+ PagedProjectInput,
21
+ PagedRepoInput,
22
+ ProviderAccount,
23
+ ProviderIssue,
24
+ ProviderPullRequest,
25
+ ProviderRepoInput,
26
+ ProviderReposInput,
27
+ ProviderRepository,
28
+ } from '../providers/models.js';
29
+ import { IssueFilter, PagingMode, PullRequestFilter } from '../providers/models.js';
30
+ import type { IntegrationResult, IntegrationType } from './integration.js';
31
+ import { IntegrationBase } from './integration.js';
32
+
33
+ export abstract class GitHostIntegration<
34
+ ID extends IntegrationIds = IntegrationIds,
35
+ T extends ResourceDescriptor = ResourceDescriptor,
36
+ > extends IntegrationBase<ID> {
37
+ readonly type: IntegrationType = 'git';
38
+
39
+ @gate()
40
+ @trace()
41
+ async getAccountForEmail(repo: T, email: string, options?: { avatarSize?: number }): Promise<Account | undefined> {
42
+ const scope = getScopedLogger();
43
+
44
+ const connected = this.maybeConnected ?? (await this.isConnected());
45
+ if (!connected) return undefined;
46
+
47
+ await this.refreshSessionIfExpired(scope);
48
+
49
+ try {
50
+ const author = await this.getProviderAccountForEmail(this._session!, repo, email, options);
51
+ this.resetRequestExceptionCount('getAccountForEmail');
52
+ return author;
53
+ } catch (ex) {
54
+ this.handleProviderException('getAccountForEmail', ex, { scope: scope });
55
+ return undefined;
56
+ }
57
+ }
58
+
59
+ protected abstract getProviderAccountForEmail(
60
+ session: ProviderAuthenticationSession,
61
+ repo: T,
62
+ email: string,
63
+ options?: { avatarSize?: number },
64
+ ): Promise<Account | undefined>;
65
+
66
+ @gate()
67
+ @trace()
68
+ async getAccountForCommit(
69
+ repo: T,
70
+ rev: string,
71
+ options?: { avatarSize?: number },
72
+ ): Promise<Account | UnidentifiedAuthor | undefined> {
73
+ const scope = getScopedLogger();
74
+
75
+ const connected = this.maybeConnected ?? (await this.isConnected());
76
+ if (!connected) return undefined;
77
+
78
+ await this.refreshSessionIfExpired(scope);
79
+
80
+ try {
81
+ const author = await this.getProviderAccountForCommit(this._session!, repo, rev, options);
82
+ this.resetRequestExceptionCount('getAccountForCommit');
83
+ return author;
84
+ } catch (ex) {
85
+ this.handleProviderException('getAccountForCommit', ex, { scope: scope });
86
+ return undefined;
87
+ }
88
+ }
89
+
90
+ protected abstract getProviderAccountForCommit(
91
+ session: ProviderAuthenticationSession,
92
+ repo: T,
93
+ rev: string,
94
+ options?: { avatarSize?: number },
95
+ ): Promise<Account | UnidentifiedAuthor | undefined>;
96
+
97
+ @trace()
98
+ async getDefaultBranch(
99
+ repo: T,
100
+ options?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },
101
+ ): Promise<DefaultBranch | undefined> {
102
+ const scope = getScopedLogger();
103
+
104
+ const connected = this.maybeConnected ?? (await this.isConnected());
105
+ if (!connected) return undefined;
106
+
107
+ await this.refreshSessionIfExpired(scope);
108
+
109
+ const defaultBranch = this.ctx.cache.getRepositoryDefaultBranch(
110
+ repo,
111
+ this,
112
+ () => ({
113
+ value: (async () => {
114
+ try {
115
+ const result = await this.getProviderDefaultBranch(this._session!, repo, options?.cancellation);
116
+ this.resetRequestExceptionCount('getDefaultBranch');
117
+ return result;
118
+ } catch (ex) {
119
+ this.handleProviderException('getDefaultBranch', ex, { scope: scope });
120
+ return undefined;
121
+ }
122
+ })(),
123
+ }),
124
+ { expiryOverride: options?.expiryOverride },
125
+ );
126
+ return defaultBranch;
127
+ }
128
+
129
+ getRepoInfo?(repo: { owner: string; name: string; project?: string }): Promise<ProviderRepository | undefined>;
130
+
131
+ protected abstract getProviderDefaultBranch(
132
+ { accessToken }: ProviderAuthenticationSession,
133
+ repo: T,
134
+ cancellation?: AbortSignal,
135
+ ): Promise<DefaultBranch | undefined>;
136
+
137
+ @trace()
138
+ async getRepositoryMetadata(
139
+ repo: T,
140
+ options?: { cancellation?: AbortSignal; expiryOverride?: boolean | number },
141
+ ): Promise<RepositoryMetadata | undefined> {
142
+ const scope = getScopedLogger();
143
+
144
+ const connected = this.maybeConnected ?? (await this.isConnected());
145
+ if (!connected) return undefined;
146
+
147
+ await this.refreshSessionIfExpired(scope);
148
+
149
+ const metadata = this.ctx.cache.getRepositoryMetadata(
150
+ repo,
151
+ this,
152
+ () => ({
153
+ value: (async () => {
154
+ try {
155
+ const result = await this.getProviderRepositoryMetadata(
156
+ this._session!,
157
+ repo,
158
+ options?.cancellation,
159
+ );
160
+ this.resetRequestExceptionCount('getRepositoryMetadata');
161
+ return result;
162
+ } catch (ex) {
163
+ this.handleProviderException('getRepositoryMetadata', ex, { scope: scope });
164
+ return undefined;
165
+ }
166
+ })(),
167
+ }),
168
+ { expiryOverride: options?.expiryOverride },
169
+ );
170
+ return metadata;
171
+ }
172
+
173
+ protected abstract getProviderRepositoryMetadata(
174
+ session: ProviderAuthenticationSession,
175
+ repo: T,
176
+ cancellation?: AbortSignal,
177
+ ): Promise<RepositoryMetadata | undefined>;
178
+
179
+ async mergePullRequest(pr: PullRequest, options?: { mergeMethod?: PullRequestMergeMethod }): Promise<boolean> {
180
+ const scope = getScopedLogger();
181
+
182
+ const connected = this.maybeConnected ?? (await this.isConnected());
183
+ if (!connected) return false;
184
+
185
+ await this.refreshSessionIfExpired(scope);
186
+
187
+ try {
188
+ const result = await this.mergeProviderPullRequest(this._session!, pr, options);
189
+ this.resetRequestExceptionCount('mergePullRequest');
190
+ return result;
191
+ } catch (ex) {
192
+ this.handleProviderException('mergePullRequest', ex, { scope: scope });
193
+ return false;
194
+ }
195
+ }
196
+
197
+ protected abstract mergeProviderPullRequest(
198
+ session: ProviderAuthenticationSession,
199
+ pr: PullRequest,
200
+ options?: { mergeMethod?: PullRequestMergeMethod },
201
+ ): Promise<boolean>;
202
+
203
+ @trace()
204
+ async getPullRequestForBranch(
205
+ repo: T,
206
+ branch: string,
207
+ options?: { avatarSize?: number; expiryOverride?: boolean | number; include?: PullRequestState[] },
208
+ ): Promise<PullRequest | undefined> {
209
+ const scope = getScopedLogger();
210
+
211
+ const connected = this.maybeConnected ?? (await this.isConnected());
212
+ if (!connected) return undefined;
213
+
214
+ await this.refreshSessionIfExpired(scope);
215
+
216
+ const { expiryOverride, ...opts } = options ?? {};
217
+
218
+ const pr = this.ctx.cache.getPullRequestForBranch(
219
+ branch,
220
+ repo,
221
+ this,
222
+ () => ({
223
+ value: (async () => {
224
+ try {
225
+ const result = await this.getProviderPullRequestForBranch(this._session!, repo, branch, opts);
226
+ this.resetRequestExceptionCount('getPullRequestForBranch');
227
+ return result;
228
+ } catch (ex) {
229
+ this.handleProviderException('getPullRequestForBranch', ex, { scope: scope });
230
+ return undefined;
231
+ }
232
+ })(),
233
+ }),
234
+ { expiryOverride: expiryOverride },
235
+ );
236
+ return pr;
237
+ }
238
+
239
+ protected abstract getProviderPullRequestForBranch(
240
+ session: ProviderAuthenticationSession,
241
+ repo: T,
242
+ branch: string,
243
+ options?: { avatarSize?: number; include?: PullRequestState[] },
244
+ ): Promise<PullRequest | undefined>;
245
+
246
+ @trace()
247
+ async getPullRequestForCommit(
248
+ repo: T,
249
+ rev: string,
250
+ options?: { expiryOverride?: boolean | number },
251
+ ): Promise<PullRequest | undefined> {
252
+ const scope = getScopedLogger();
253
+
254
+ const connected = this.maybeConnected ?? (await this.isConnected());
255
+ if (!connected) return undefined;
256
+
257
+ await this.refreshSessionIfExpired(scope);
258
+
259
+ const pr = this.ctx.cache.getPullRequestForSha(
260
+ rev,
261
+ repo,
262
+ this,
263
+ () => ({
264
+ value: (async () => {
265
+ try {
266
+ const result = await this.getProviderPullRequestForCommit(this._session!, repo, rev);
267
+ this.resetRequestExceptionCount('getPullRequestForCommit');
268
+ return result;
269
+ } catch (ex) {
270
+ this.handleProviderException('getPullRequestForCommit', ex, { scope: scope });
271
+ return undefined;
272
+ }
273
+ })(),
274
+ }),
275
+ options,
276
+ );
277
+ return pr;
278
+ }
279
+
280
+ protected abstract getProviderPullRequestForCommit(
281
+ session: ProviderAuthenticationSession,
282
+ repo: T,
283
+ rev: string,
284
+ ): Promise<PullRequest | undefined>;
285
+
286
+ async getMyIssuesForRepos(
287
+ reposOrRepoIds: ProviderReposInput,
288
+ options?: { filters?: IssueFilter[]; cursor?: string; customUrl?: string },
289
+ ): Promise<PagedResult<ProviderIssue> | undefined> {
290
+ const scope = getScopedLogger();
291
+ const providerId = this.authProvider.id;
292
+ const connected = this.maybeConnected ?? (await this.isConnected());
293
+ if (!connected) return undefined;
294
+
295
+ await this.refreshSessionIfExpired(scope);
296
+
297
+ const api = await this.getProvidersApi();
298
+ if (
299
+ providerId !== GitCloudHostIntegrationId.GitLab &&
300
+ (api.isRepoIdsInput(reposOrRepoIds) ||
301
+ (providerId === GitCloudHostIntegrationId.AzureDevOps &&
302
+ !reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))
303
+ ) {
304
+ Logger.warn(`Unsupported input for provider ${providerId}`, 'getIssuesForRepos');
305
+ return undefined;
306
+ }
307
+
308
+ let getIssuesOptions: GetIssuesOptions | undefined;
309
+ if (providerId === GitCloudHostIntegrationId.AzureDevOps) {
310
+ const organizations = new Set<string>();
311
+ const projects = new Set<string>();
312
+ for (const repo of reposOrRepoIds as ProviderRepoInput[]) {
313
+ organizations.add(repo.namespace);
314
+ projects.add(repo.project!);
315
+ }
316
+
317
+ if (organizations.size > 1) {
318
+ Logger.warn(`Multiple organizations not supported for provider ${providerId}`, 'getIssuesForRepos');
319
+ return undefined;
320
+ } else if (organizations.size === 0) {
321
+ Logger.warn(`No organizations found for provider ${providerId}`, 'getIssuesForRepos');
322
+ return undefined;
323
+ }
324
+
325
+ const organization: string = first(organizations.values())!;
326
+
327
+ if (options?.filters != null) {
328
+ if (!api.providerSupportsIssueFilters(providerId, options.filters)) {
329
+ Logger.warn(`Unsupported filters for provider ${providerId}`, 'getIssuesForRepos');
330
+ return undefined;
331
+ }
332
+
333
+ let userAccount: ProviderAccount | undefined;
334
+ try {
335
+ userAccount = await api.getCurrentUserForInstance({ providerId: providerId }, organization);
336
+ } catch (ex) {
337
+ Logger.error(ex, 'getIssuesForRepos');
338
+ return undefined;
339
+ }
340
+
341
+ if (userAccount == null) {
342
+ Logger.warn(`Unable to get current user for ${providerId}`, 'getIssuesForRepos');
343
+ return undefined;
344
+ }
345
+
346
+ const userFilterProperty = userAccount.name;
347
+
348
+ if (userFilterProperty == null) {
349
+ Logger.warn(`Unable to get user property for filter for ${providerId}`, 'getIssuesForRepos');
350
+ return undefined;
351
+ }
352
+
353
+ getIssuesOptions = {
354
+ authorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,
355
+ assigneeLogins: options.filters.includes(IssueFilter.Assignee) ? [userFilterProperty] : undefined,
356
+ mentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,
357
+ };
358
+ }
359
+
360
+ const cursorInfo = JSON.parse(options?.cursor ?? '{}');
361
+ const cursors: PagedProjectInput[] = cursorInfo.cursors ?? [];
362
+ let projectInputs: PagedProjectInput[] = Array.from(projects.values(), project => ({
363
+ namespace: organization,
364
+ project: project,
365
+ cursor: undefined,
366
+ }));
367
+ if (cursors.length > 0) {
368
+ projectInputs = cursors;
369
+ }
370
+
371
+ try {
372
+ const cursor: { cursors: PagedProjectInput[] } = { cursors: [] };
373
+ let hasMore = false;
374
+ const data: ProviderIssue[] = [];
375
+ await Promise.all(
376
+ projectInputs.map(async projectInput => {
377
+ const results = await api.getIssuesForAzureProject(
378
+ { providerId: providerId },
379
+ projectInput.namespace,
380
+ projectInput.project,
381
+ {
382
+ ...getIssuesOptions,
383
+ cursor: projectInput.cursor,
384
+ },
385
+ );
386
+ data.push(...results.values);
387
+ if (results.paging?.more) {
388
+ hasMore = true;
389
+ cursor.cursors.push({
390
+ namespace: projectInput.namespace,
391
+ project: projectInput.project,
392
+ cursor: results.paging.cursor,
393
+ });
394
+ }
395
+ }),
396
+ );
397
+
398
+ return {
399
+ values: data,
400
+ paging: {
401
+ more: hasMore,
402
+ cursor: JSON.stringify(cursor),
403
+ },
404
+ };
405
+ } catch (ex) {
406
+ Logger.error(ex, 'getIssuesForRepos');
407
+ return undefined;
408
+ }
409
+ }
410
+ if (options?.filters != null) {
411
+ let userAccount: ProviderAccount | undefined;
412
+ try {
413
+ userAccount = await api.getCurrentUser({ providerId: providerId });
414
+ } catch (ex) {
415
+ Logger.error(ex, 'getIssuesForRepos');
416
+ return undefined;
417
+ }
418
+
419
+ if (userAccount == null) {
420
+ Logger.warn(`Unable to get current user for ${providerId}`, 'getIssuesForRepos');
421
+ return undefined;
422
+ }
423
+
424
+ const userFilterProperty = userAccount.username;
425
+ if (userFilterProperty == null) {
426
+ Logger.warn(`Unable to get user property for filter for ${providerId}`, 'getIssuesForRepos');
427
+ return undefined;
428
+ }
429
+
430
+ getIssuesOptions = {
431
+ authorLogin: options.filters.includes(IssueFilter.Author) ? userFilterProperty : undefined,
432
+ assigneeLogins: options.filters.includes(IssueFilter.Assignee) ? [userFilterProperty] : undefined,
433
+ mentionLogin: options.filters.includes(IssueFilter.Mention) ? userFilterProperty : undefined,
434
+ };
435
+ }
436
+
437
+ if (api.getProviderIssuesPagingMode(providerId) === PagingMode.Repo && !api.isRepoIdsInput(reposOrRepoIds)) {
438
+ const cursorInfo = JSON.parse(options?.cursor ?? '{}');
439
+ const cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];
440
+ let repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));
441
+ if (cursors.length > 0) {
442
+ repoInputs = cursors;
443
+ }
444
+
445
+ try {
446
+ const cursor: { cursors: PagedRepoInput[] } = { cursors: [] };
447
+ let hasMore = false;
448
+ const data: ProviderIssue[] = [];
449
+ await Promise.all(
450
+ repoInputs.map(async repoInput => {
451
+ const results = await api.getIssuesForRepo({ providerId: providerId }, repoInput.repo, {
452
+ ...getIssuesOptions,
453
+ cursor: repoInput.cursor,
454
+ baseUrl: options?.customUrl,
455
+ });
456
+ data.push(...results.values);
457
+ if (results.paging?.more) {
458
+ hasMore = true;
459
+ cursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });
460
+ }
461
+ }),
462
+ );
463
+
464
+ return {
465
+ values: data,
466
+ paging: {
467
+ more: hasMore,
468
+ cursor: JSON.stringify(cursor),
469
+ },
470
+ };
471
+ } catch (ex) {
472
+ Logger.error(ex, 'getIssuesForRepos');
473
+ return undefined;
474
+ }
475
+ }
476
+
477
+ try {
478
+ return await api.getIssuesForRepos({ providerId: providerId }, reposOrRepoIds, {
479
+ ...getIssuesOptions,
480
+ cursor: options?.cursor,
481
+ baseUrl: options?.customUrl,
482
+ });
483
+ } catch (ex) {
484
+ Logger.error(ex, 'getIssuesForRepos');
485
+ return undefined;
486
+ }
487
+ }
488
+
489
+ async getMyPullRequestsForRepos(
490
+ reposOrRepoIds: ProviderReposInput,
491
+ options?: { filters?: PullRequestFilter[]; cursor?: string; customUrl?: string },
492
+ ): Promise<PagedResult<ProviderPullRequest> | undefined> {
493
+ const scope = getScopedLogger();
494
+ const providerId = this.authProvider.id;
495
+ const connected = this.maybeConnected ?? (await this.isConnected());
496
+ if (!connected) return undefined;
497
+
498
+ await this.refreshSessionIfExpired(scope);
499
+
500
+ const api = await this.getProvidersApi();
501
+ if (
502
+ providerId !== GitCloudHostIntegrationId.GitLab &&
503
+ (api.isRepoIdsInput(reposOrRepoIds) ||
504
+ (providerId === GitCloudHostIntegrationId.AzureDevOps &&
505
+ !reposOrRepoIds.every(repo => repo.project != null && repo.namespace != null)))
506
+ ) {
507
+ Logger.warn(`Unsupported input for provider ${providerId}`);
508
+ return undefined;
509
+ }
510
+
511
+ let getPullRequestsOptions: GetPullRequestsOptions | undefined;
512
+ if (options?.filters != null) {
513
+ if (!api.providerSupportsPullRequestFilters(providerId, options.filters)) {
514
+ Logger.warn(`Unsupported filters for provider ${providerId}`, 'getPullRequestsForRepos');
515
+ return undefined;
516
+ }
517
+
518
+ let userAccount: ProviderAccount | undefined;
519
+ if (providerId === GitCloudHostIntegrationId.AzureDevOps) {
520
+ const organizations = new Set<string>();
521
+ for (const repo of reposOrRepoIds as ProviderRepoInput[]) {
522
+ organizations.add(repo.namespace);
523
+ }
524
+
525
+ if (organizations.size > 1) {
526
+ Logger.warn(
527
+ `Multiple organizations not supported for provider ${providerId}`,
528
+ 'getPullRequestsForRepos',
529
+ );
530
+ return undefined;
531
+ } else if (organizations.size === 0) {
532
+ Logger.warn(`No organizations found for provider ${providerId}`, 'getPullRequestsForRepos');
533
+ return undefined;
534
+ }
535
+
536
+ const organization: string = first(organizations.values())!;
537
+ try {
538
+ userAccount = await api.getCurrentUserForInstance({ providerId: providerId }, organization);
539
+ } catch (ex) {
540
+ Logger.error(ex, 'getPullRequestsForRepos');
541
+ return undefined;
542
+ }
543
+ } else {
544
+ try {
545
+ userAccount = await api.getCurrentUser({ providerId: providerId });
546
+ } catch (ex) {
547
+ Logger.error(ex, 'getPullRequestsForRepos');
548
+ return undefined;
549
+ }
550
+ }
551
+
552
+ if (userAccount == null) {
553
+ Logger.warn(`Unable to get current user for ${providerId}`, 'getPullRequestsForRepos');
554
+ return undefined;
555
+ }
556
+
557
+ let userFilterProperty: string | null;
558
+ switch (providerId) {
559
+ case GitCloudHostIntegrationId.Bitbucket:
560
+ case GitCloudHostIntegrationId.AzureDevOps:
561
+ userFilterProperty = userAccount.id;
562
+ break;
563
+ default:
564
+ userFilterProperty = userAccount.username;
565
+ break;
566
+ }
567
+
568
+ if (userFilterProperty == null) {
569
+ Logger.warn(`Unable to get user property for filter for ${providerId}`, 'getPullRequestsForRepos');
570
+ return undefined;
571
+ }
572
+
573
+ getPullRequestsOptions = {
574
+ authorLogin: options.filters.includes(PullRequestFilter.Author) ? userFilterProperty : undefined,
575
+ assigneeLogins: options.filters.includes(PullRequestFilter.Assignee) ? [userFilterProperty] : undefined,
576
+ reviewRequestedLogin: options.filters.includes(PullRequestFilter.ReviewRequested)
577
+ ? userFilterProperty
578
+ : undefined,
579
+ mentionLogin: options.filters.includes(PullRequestFilter.Mention) ? userFilterProperty : undefined,
580
+ };
581
+ }
582
+
583
+ if (
584
+ api.getProviderPullRequestsPagingMode(providerId) === PagingMode.Repo &&
585
+ !api.isRepoIdsInput(reposOrRepoIds)
586
+ ) {
587
+ const cursorInfo = JSON.parse(options?.cursor ?? '{}');
588
+ const cursors: PagedRepoInput[] = cursorInfo.cursors ?? [];
589
+ let repoInputs: PagedRepoInput[] = reposOrRepoIds.map(repo => ({ repo: repo, cursor: undefined }));
590
+ if (cursors.length > 0) {
591
+ repoInputs = cursors;
592
+ }
593
+
594
+ try {
595
+ const cursor: { cursors: PagedRepoInput[] } = { cursors: [] };
596
+ let hasMore = false;
597
+ const data: ProviderPullRequest[] = [];
598
+ await Promise.all(
599
+ repoInputs.map(async repoInput => {
600
+ const results = await api.getPullRequestsForRepo({ providerId: providerId }, repoInput.repo, {
601
+ ...getPullRequestsOptions,
602
+ cursor: repoInput.cursor,
603
+ baseUrl: options?.customUrl,
604
+ });
605
+ data.push(...results.values);
606
+ if (results.paging?.more) {
607
+ hasMore = true;
608
+ cursor.cursors.push({ repo: repoInput.repo, cursor: results.paging.cursor });
609
+ }
610
+ }),
611
+ );
612
+
613
+ return {
614
+ values: data,
615
+ paging: {
616
+ more: hasMore,
617
+ cursor: JSON.stringify(cursor),
618
+ },
619
+ };
620
+ } catch (ex) {
621
+ Logger.error(ex, 'getPullRequestsForRepos');
622
+ return undefined;
623
+ }
624
+ }
625
+
626
+ try {
627
+ return await api.getPullRequestsForRepos({ providerId: providerId }, reposOrRepoIds, {
628
+ ...getPullRequestsOptions,
629
+ cursor: options?.cursor,
630
+ baseUrl: options?.customUrl,
631
+ });
632
+ } catch (ex) {
633
+ Logger.error(ex, 'getPullRequestsForRepos');
634
+ return undefined;
635
+ }
636
+ }
637
+
638
+ async searchMyPullRequests(
639
+ repo?: T,
640
+ cancellation?: AbortSignal,
641
+ silent?: boolean,
642
+ ): Promise<IntegrationResult<PullRequest[] | undefined>>;
643
+ async searchMyPullRequests(
644
+ repos?: T[],
645
+ cancellation?: AbortSignal,
646
+ silent?: boolean,
647
+ ): Promise<IntegrationResult<PullRequest[] | undefined>>;
648
+ @trace()
649
+ async searchMyPullRequests(
650
+ repos?: T | T[],
651
+ cancellation?: AbortSignal,
652
+ silent?: boolean,
653
+ ): Promise<IntegrationResult<PullRequest[] | undefined>> {
654
+ const scope = getScopedLogger();
655
+ const connected = this.maybeConnected ?? (await this.isConnected());
656
+ if (!connected) return undefined;
657
+
658
+ await this.refreshSessionIfExpired(scope);
659
+
660
+ const start = performance.now();
661
+ try {
662
+ const pullRequests = await this.searchProviderMyPullRequests(
663
+ this._session!,
664
+ repos != null ? (Array.isArray(repos) ? repos : [repos]) : undefined,
665
+ cancellation,
666
+ silent,
667
+ );
668
+ this.resetRequestExceptionCount('searchMyPullRequests');
669
+ return { value: pullRequests, duration: performance.now() - start };
670
+ } catch (ex) {
671
+ this.handleProviderException('searchMyPullRequests', ex, {
672
+ scope: scope,
673
+ silent: true,
674
+ });
675
+ return {
676
+ error: ex,
677
+ duration: performance.now() - start,
678
+ };
679
+ }
680
+ }
681
+
682
+ protected abstract searchProviderMyPullRequests(
683
+ session: ProviderAuthenticationSession,
684
+ repos?: T[],
685
+ cancellation?: AbortSignal,
686
+ silent?: boolean,
687
+ ): Promise<PullRequest[] | undefined>;
688
+
689
+ async searchPullRequests(
690
+ searchQuery: string,
691
+ repo?: T,
692
+ cancellation?: AbortSignal,
693
+ ): Promise<PullRequest[] | undefined>;
694
+ async searchPullRequests(
695
+ searchQuery: string,
696
+ repos?: T[],
697
+ cancellation?: AbortSignal,
698
+ ): Promise<PullRequest[] | undefined>;
699
+ @trace()
700
+ async searchPullRequests(
701
+ searchQuery: string,
702
+ repos?: T | T[],
703
+ cancellation?: AbortSignal,
704
+ ): Promise<PullRequest[] | undefined> {
705
+ const scope = getScopedLogger();
706
+ const connected = this.maybeConnected ?? (await this.isConnected());
707
+ if (!connected) return undefined;
708
+
709
+ await this.refreshSessionIfExpired(scope);
710
+
711
+ try {
712
+ const prs = await this.searchProviderPullRequests?.(
713
+ this._session!,
714
+ searchQuery,
715
+ repos != null ? (Array.isArray(repos) ? repos : [repos]) : undefined,
716
+ cancellation,
717
+ );
718
+ this.resetRequestExceptionCount('searchPullRequests');
719
+ return prs;
720
+ } catch (ex) {
721
+ this.handleProviderException('searchPullRequests', ex, { scope: scope });
722
+ return undefined;
723
+ }
724
+ }
725
+
726
+ protected searchProviderPullRequests?(
727
+ session: ProviderAuthenticationSession,
728
+ searchQuery: string,
729
+ repos?: T[],
730
+ cancellation?: AbortSignal,
731
+ ): Promise<PullRequest[] | undefined>;
732
+
733
+ getPullRequestIdentityFromMaybeUrl(search: string): PullRequestUrlIdentity | undefined {
734
+ return this.getProviderPullRequestIdentityFromMaybeUrl?.(search);
735
+ }
736
+
737
+ protected getProviderPullRequestIdentityFromMaybeUrl?(search: string): PullRequestUrlIdentity | undefined;
738
+ }