@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,282 @@
1
+ import type { Account, UnidentifiedAuthor } from '../../../git/models/author.js';
2
+ import type { DefaultBranch } from '../../../git/models/defaultBranch.js';
3
+ import type { Issue, IssueShape } from '../../../git/models/issue.js';
4
+ import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../../git/models/issueOrPullRequest.js';
5
+ import type { PullRequest, PullRequestMergeMethod, PullRequestState } from '../../../git/models/pullRequest.js';
6
+ import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
7
+ import { md5 } from '../../../utils/crypto.js';
8
+ import type { Emitter } from '../../../utils/event.js';
9
+ import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
10
+ import type { IntegrationAuthenticationService } from '../authentication/integrationAuthenticationService.js';
11
+ import type { IntegrationServiceContext } from '../context.js';
12
+ import type {
13
+ AuthenticationSessionLike as AuthenticationSession,
14
+ ProviderAuthenticationSession,
15
+ } from '../authentication/models.js';
16
+ import { toTokenWithInfo } from '../authentication/models.js';
17
+ import { GitSelfManagedHostIntegrationId } from '../constants.js';
18
+ import type { IntegrationConnectionChangeEvent } from '../integrationService.js';
19
+ import { GitHostIntegration } from '../models/gitHostIntegration.js';
20
+ import type { IntegrationKey } from '../models/integration.js';
21
+ import type { BitbucketRepositoryDescriptor } from './bitbucket/models.js';
22
+ import type { ProviderRepository } from './models.js';
23
+ import { fromProviderPullRequest, providersMetadata } from './models.js';
24
+ import type { ProvidersApi } from './providersApi.js';
25
+
26
+ const metadata = providersMetadata[GitSelfManagedHostIntegrationId.BitbucketServer];
27
+ const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
28
+
29
+ export class BitbucketServerIntegration extends GitHostIntegration<
30
+ GitSelfManagedHostIntegrationId.BitbucketServer,
31
+ BitbucketRepositoryDescriptor
32
+ > {
33
+ readonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;
34
+ readonly id = GitSelfManagedHostIntegrationId.BitbucketServer;
35
+ protected readonly key =
36
+ `${this.id}:${this.domain}` satisfies IntegrationKey<GitSelfManagedHostIntegrationId.BitbucketServer>;
37
+ readonly name: string = 'Bitbucket Data Center';
38
+
39
+ constructor(
40
+ ctx: IntegrationServiceContext,
41
+ authenticationService: IntegrationAuthenticationService,
42
+ getProvidersApi: () => Promise<ProvidersApi>,
43
+ didChangeConnection: Emitter<IntegrationConnectionChangeEvent>,
44
+ private readonly _domain: string,
45
+ ) {
46
+ super(ctx, authenticationService, getProvidersApi, didChangeConnection);
47
+ }
48
+
49
+ get domain(): string {
50
+ return this._domain;
51
+ }
52
+
53
+ protected get apiBaseUrl(): string {
54
+ const protocol = this._session?.protocol ?? 'https:';
55
+ return `${protocol}//${this.domain}/rest/api/1.0`;
56
+ }
57
+
58
+ protected override async mergeProviderPullRequest(
59
+ session: ProviderAuthenticationSession,
60
+ pr: PullRequest,
61
+ options?: {
62
+ mergeMethod?: PullRequestMergeMethod;
63
+ },
64
+ ): Promise<boolean> {
65
+ const api = await this.getProvidersApi();
66
+ return api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {
67
+ mergeMethod: options?.mergeMethod,
68
+ baseUrl: this.apiBaseUrl,
69
+ });
70
+ }
71
+
72
+ protected override async getProviderAccountForCommit(
73
+ session: ProviderAuthenticationSession,
74
+ repo: BitbucketRepositoryDescriptor,
75
+ rev: string,
76
+ options?: {
77
+ avatarSize?: number;
78
+ },
79
+ ): Promise<Account | UnidentifiedAuthor | undefined> {
80
+ return (await this.authenticationService.apis.bitbucket)?.getServerAccountForCommit(
81
+ this,
82
+ toTokenWithInfo(this.id, session),
83
+ repo.owner,
84
+ repo.name,
85
+ rev,
86
+ this.apiBaseUrl,
87
+ {
88
+ avatarSize: options?.avatarSize,
89
+ },
90
+ );
91
+ }
92
+
93
+ protected override async getProviderAccountForEmail(
94
+ _session: AuthenticationSession,
95
+ _repo: BitbucketRepositoryDescriptor,
96
+ _email: string,
97
+ _options?: {
98
+ avatarSize?: number;
99
+ },
100
+ ): Promise<Account | undefined> {
101
+ return Promise.resolve(undefined);
102
+ }
103
+
104
+ protected override async getProviderDefaultBranch(
105
+ _session: AuthenticationSession,
106
+ _repo: BitbucketRepositoryDescriptor,
107
+ ): Promise<DefaultBranch | undefined> {
108
+ return Promise.resolve(undefined);
109
+ }
110
+
111
+ protected override async getProviderLinkedIssueOrPullRequest(
112
+ session: ProviderAuthenticationSession,
113
+ repo: BitbucketRepositoryDescriptor,
114
+ { id }: { id: string; key: string },
115
+ type: undefined | IssueOrPullRequestType,
116
+ ): Promise<IssueOrPullRequest | undefined> {
117
+ if (type === 'issue') {
118
+ return undefined;
119
+ }
120
+ return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestById(
121
+ this,
122
+ toTokenWithInfo(this.id, session),
123
+ repo.owner,
124
+ repo.name,
125
+ id,
126
+ this.apiBaseUrl,
127
+ );
128
+ }
129
+
130
+ protected override async getProviderIssue(
131
+ _session: AuthenticationSession,
132
+ _repo: BitbucketRepositoryDescriptor,
133
+ _id: string,
134
+ ): Promise<Issue | undefined> {
135
+ return Promise.resolve(undefined);
136
+ }
137
+
138
+ protected override async getProviderPullRequestForBranch(
139
+ session: ProviderAuthenticationSession,
140
+ repo: BitbucketRepositoryDescriptor,
141
+ branch: string,
142
+ _options?: {
143
+ avatarSize?: number;
144
+ include?: PullRequestState[];
145
+ },
146
+ ): Promise<PullRequest | undefined> {
147
+ return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForBranch(
148
+ this,
149
+ toTokenWithInfo(this.id, session),
150
+ repo.owner,
151
+ repo.name,
152
+ branch,
153
+ this.apiBaseUrl,
154
+ );
155
+ }
156
+
157
+ protected override async getProviderPullRequestForCommit(
158
+ session: ProviderAuthenticationSession,
159
+ repo: BitbucketRepositoryDescriptor,
160
+ rev: string,
161
+ ): Promise<PullRequest | undefined> {
162
+ return (await this.authenticationService.apis.bitbucket)?.getServerPullRequestForCommit(
163
+ this,
164
+ toTokenWithInfo(this.id, session),
165
+ repo.owner,
166
+ repo.name,
167
+ rev,
168
+ this.apiBaseUrl,
169
+ );
170
+ }
171
+
172
+ public override async getRepoInfo(repo: { owner: string; name: string }): Promise<ProviderRepository | undefined> {
173
+ const api = await this.getProvidersApi();
174
+ const tokenOptInfo = this._session ? toTokenWithInfo(this.id, this._session) : { providerId: this.id };
175
+ return api.getRepo(tokenOptInfo, repo.owner, repo.name, undefined, {
176
+ baseUrl: this.apiBaseUrl,
177
+ });
178
+ }
179
+
180
+ protected override async getProviderRepositoryMetadata(
181
+ _session: AuthenticationSession,
182
+ _repo: BitbucketRepositoryDescriptor,
183
+ _cancellation?: AbortSignal,
184
+ ): Promise<RepositoryMetadata | undefined> {
185
+ return Promise.resolve(undefined);
186
+ }
187
+
188
+ private _accounts: Map<string, Account | undefined> | undefined;
189
+ protected override async getProviderCurrentAccount(
190
+ session: ProviderAuthenticationSession,
191
+ ): Promise<Account | undefined> {
192
+ const { accessToken } = session;
193
+ this._accounts ??= new Map<string, Account | undefined>();
194
+
195
+ const cachedAccount = this._accounts.get(accessToken);
196
+ if (cachedAccount == null) {
197
+ const api = await this.getProvidersApi();
198
+ const user = await api.getCurrentUser(toTokenWithInfo(this.id, session), {
199
+ baseUrl: this.apiBaseUrl,
200
+ });
201
+ this._accounts.set(
202
+ accessToken,
203
+ user
204
+ ? {
205
+ provider: this,
206
+ id: user.id,
207
+ name: user.name ?? undefined,
208
+ email: user.email ?? undefined,
209
+ avatarUrl: user.avatarUrl ?? undefined,
210
+ username: user.username ?? undefined,
211
+ }
212
+ : undefined,
213
+ );
214
+ }
215
+
216
+ return this._accounts.get(accessToken);
217
+ }
218
+
219
+ protected override async searchProviderMyPullRequests(
220
+ session: ProviderAuthenticationSession,
221
+ repos?: BitbucketRepositoryDescriptor[],
222
+ ): Promise<PullRequest[] | undefined> {
223
+ if (repos != null) {
224
+ // TODO: implement repos version
225
+ return undefined;
226
+ }
227
+
228
+ const api = await this.getProvidersApi();
229
+ if (!api) {
230
+ return undefined;
231
+ }
232
+
233
+ const prs = await api.getBitbucketServerPullRequestsForCurrentUser(
234
+ toTokenWithInfo(this.id, session),
235
+ this.apiBaseUrl,
236
+ );
237
+ return prs?.map(pr => fromProviderPullRequest(pr, this));
238
+ }
239
+
240
+ protected override async searchProviderMyIssues(
241
+ _session: AuthenticationSession,
242
+ _repos?: BitbucketRepositoryDescriptor[],
243
+ ): Promise<IssueShape[] | undefined> {
244
+ return Promise.resolve(undefined);
245
+ }
246
+
247
+ private readonly storagePrefix = 'bitbucket-server';
248
+ protected override async providerOnConnect(): Promise<void> {
249
+ if (this._session == null) return;
250
+
251
+ const accountStorageKey = md5(this._session.accessToken);
252
+
253
+ const storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);
254
+
255
+ let account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;
256
+
257
+ if (storedAccount == null) {
258
+ account = await this.getProviderCurrentAccount(this._session);
259
+ if (account != null) {
260
+ // Clear all other stored workspaces and repositories and accounts when our session changes
261
+ await this.ctx.storage.deleteWithPrefix(this.storagePrefix);
262
+ await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {
263
+ v: 1,
264
+ timestamp: Date.now(),
265
+ data: {
266
+ id: account.id,
267
+ name: account.name,
268
+ email: account.email,
269
+ avatarUrl: account.avatarUrl,
270
+ username: account.username,
271
+ },
272
+ });
273
+ }
274
+ }
275
+ this._accounts ??= new Map<string, Account | undefined>();
276
+ this._accounts.set(this._session.accessToken, account);
277
+ }
278
+
279
+ protected override providerOnDisconnect(): void {
280
+ this._accounts = undefined;
281
+ }
282
+ }
@@ -0,0 +1,350 @@
1
+ import type { Account, UnidentifiedAuthor } from '../../../git/models/author.js';
2
+ import type { DefaultBranch } from '../../../git/models/defaultBranch.js';
3
+ import type { Issue, IssueShape } from '../../../git/models/issue.js';
4
+ import type { IssueOrPullRequest, IssueOrPullRequestType } from '../../../git/models/issueOrPullRequest.js';
5
+ import type { PullRequest, PullRequestMergeMethod, PullRequestState } from '../../../git/models/pullRequest.js';
6
+ import type { GitRemote } from '../../../git/models/remote.js';
7
+ import type { RepositoryMetadata } from '../../../git/models/repositoryMetadata.js';
8
+ import { md5 } from '../../../utils/crypto.js';
9
+ import { uniqueBy } from '../../../utils/iterable.js';
10
+ import { flatSettled, nonnullSettled } from '../../../utils/promise.js';
11
+ import type { IntegrationAuthenticationProviderDescriptor } from '../authentication/integrationAuthenticationProvider.js';
12
+ import type {
13
+ AuthenticationSessionLike as AuthenticationSession,
14
+ ProviderAuthenticationSession,
15
+ } from '../authentication/models.js';
16
+ import { toTokenWithInfo } from '../authentication/models.js';
17
+ import { GitCloudHostIntegrationId } from '../constants.js';
18
+ import { GitHostIntegration } from '../models/gitHostIntegration.js';
19
+ import type { BitbucketRepositoryDescriptor, BitbucketWorkspaceDescriptor } from './bitbucket/models.js';
20
+ import { fromProviderPullRequest, providersMetadata } from './models.js';
21
+
22
+ const metadata = providersMetadata[GitCloudHostIntegrationId.Bitbucket];
23
+ const authProvider = Object.freeze({ id: metadata.id, scopes: metadata.scopes });
24
+
25
+ export class BitbucketIntegration extends GitHostIntegration<
26
+ GitCloudHostIntegrationId.Bitbucket,
27
+ BitbucketRepositoryDescriptor
28
+ > {
29
+ readonly authProvider: IntegrationAuthenticationProviderDescriptor = authProvider;
30
+ readonly id = GitCloudHostIntegrationId.Bitbucket;
31
+ protected readonly key = this.id;
32
+ readonly name: string = 'Bitbucket';
33
+ get domain(): string {
34
+ return metadata.domain;
35
+ }
36
+
37
+ protected get apiBaseUrl(): string {
38
+ return 'https://api.bitbucket.org/2.0';
39
+ }
40
+
41
+ protected override async mergeProviderPullRequest(
42
+ session: ProviderAuthenticationSession,
43
+ pr: PullRequest,
44
+ options?: {
45
+ mergeMethod?: PullRequestMergeMethod;
46
+ },
47
+ ): Promise<boolean> {
48
+ const api = await this.getProvidersApi();
49
+ return api.mergePullRequest(toTokenWithInfo(this.id, session), pr, {
50
+ mergeMethod: options?.mergeMethod,
51
+ });
52
+ }
53
+
54
+ protected override async getProviderAccountForCommit(
55
+ session: ProviderAuthenticationSession,
56
+ repo: BitbucketRepositoryDescriptor,
57
+ rev: string,
58
+ options?: {
59
+ avatarSize?: number;
60
+ },
61
+ ): Promise<Account | UnidentifiedAuthor | undefined> {
62
+ return (await this.authenticationService.apis.bitbucket)?.getAccountForCommit(
63
+ this,
64
+ toTokenWithInfo(this.id, session),
65
+ repo.owner,
66
+ repo.name,
67
+ rev,
68
+ this.apiBaseUrl,
69
+ {
70
+ avatarSize: options?.avatarSize,
71
+ },
72
+ );
73
+ }
74
+
75
+ protected override async getProviderAccountForEmail(
76
+ _session: AuthenticationSession,
77
+ _repo: BitbucketRepositoryDescriptor,
78
+ _email: string,
79
+ _options?: {
80
+ avatarSize?: number;
81
+ },
82
+ ): Promise<Account | undefined> {
83
+ return Promise.resolve(undefined);
84
+ }
85
+
86
+ protected override async getProviderDefaultBranch(
87
+ _session: AuthenticationSession,
88
+ _repo: BitbucketRepositoryDescriptor,
89
+ ): Promise<DefaultBranch | undefined> {
90
+ return Promise.resolve(undefined);
91
+ }
92
+
93
+ protected override async getProviderLinkedIssueOrPullRequest(
94
+ session: ProviderAuthenticationSession,
95
+ repo: BitbucketRepositoryDescriptor,
96
+ { id }: { id: string; key: string },
97
+ type: undefined | IssueOrPullRequestType,
98
+ ): Promise<IssueOrPullRequest | undefined> {
99
+ return (await this.authenticationService.apis.bitbucket)?.getIssueOrPullRequest(
100
+ this,
101
+ toTokenWithInfo(this.id, session),
102
+ repo.owner,
103
+ repo.name,
104
+ id,
105
+ this.apiBaseUrl,
106
+ {
107
+ type: type,
108
+ },
109
+ );
110
+ }
111
+
112
+ protected override async getProviderIssue(
113
+ session: ProviderAuthenticationSession,
114
+ repo: BitbucketRepositoryDescriptor,
115
+ id: string,
116
+ ): Promise<Issue | undefined> {
117
+ return (await this.authenticationService.apis.bitbucket)?.getIssue(
118
+ this,
119
+ toTokenWithInfo(this.id, session),
120
+ repo.owner,
121
+ repo.name,
122
+ id,
123
+ this.apiBaseUrl,
124
+ );
125
+ }
126
+
127
+ protected override async getProviderPullRequestForBranch(
128
+ session: ProviderAuthenticationSession,
129
+ repo: BitbucketRepositoryDescriptor,
130
+ branch: string,
131
+ _options?: {
132
+ avatarSize?: number;
133
+ include?: PullRequestState[];
134
+ },
135
+ ): Promise<PullRequest | undefined> {
136
+ return (await this.authenticationService.apis.bitbucket)?.getPullRequestForBranch(
137
+ this,
138
+ toTokenWithInfo(this.id, session),
139
+ repo.owner,
140
+ repo.name,
141
+ branch,
142
+ this.apiBaseUrl,
143
+ );
144
+ }
145
+
146
+ protected override async getProviderPullRequestForCommit(
147
+ session: ProviderAuthenticationSession,
148
+ repo: BitbucketRepositoryDescriptor,
149
+ rev: string,
150
+ ): Promise<PullRequest | undefined> {
151
+ return (await this.authenticationService.apis.bitbucket)?.getPullRequestForCommit(
152
+ this,
153
+ toTokenWithInfo(this.id, session),
154
+ repo.owner,
155
+ repo.name,
156
+ rev,
157
+ this.apiBaseUrl,
158
+ );
159
+ }
160
+
161
+ protected override async getProviderRepositoryMetadata(
162
+ _session: AuthenticationSession,
163
+ _repo: BitbucketRepositoryDescriptor,
164
+ _cancellation?: AbortSignal,
165
+ ): Promise<RepositoryMetadata | undefined> {
166
+ return Promise.resolve(undefined);
167
+ }
168
+
169
+ private _accounts: Map<string, Account | undefined> | undefined;
170
+ protected override async getProviderCurrentAccount(
171
+ session: ProviderAuthenticationSession,
172
+ ): Promise<Account | undefined> {
173
+ const { accessToken } = session;
174
+ this._accounts ??= new Map<string, Account | undefined>();
175
+
176
+ const cachedAccount = this._accounts.get(accessToken);
177
+ if (cachedAccount == null) {
178
+ const api = await this.getProvidersApi();
179
+ const user = await api.getCurrentUser(toTokenWithInfo(this.id, session));
180
+ this._accounts.set(
181
+ accessToken,
182
+ user
183
+ ? {
184
+ provider: this,
185
+ id: user.id,
186
+ name: user.name ?? undefined,
187
+ email: user.email ?? undefined,
188
+ avatarUrl: user.avatarUrl ?? undefined,
189
+ username: user.username ?? undefined,
190
+ }
191
+ : undefined,
192
+ );
193
+ }
194
+
195
+ return this._accounts.get(accessToken);
196
+ }
197
+
198
+ private _workspaces: Map<string, BitbucketWorkspaceDescriptor[] | undefined> | undefined;
199
+ private async getProviderResourcesForCurrentUser(
200
+ session: ProviderAuthenticationSession,
201
+ force: boolean = false,
202
+ ): Promise<BitbucketWorkspaceDescriptor[] | undefined> {
203
+ this._workspaces ??= new Map<string, BitbucketWorkspaceDescriptor[] | undefined>();
204
+ const { accessToken } = session;
205
+ const cachedResources = this._workspaces.get(accessToken);
206
+
207
+ if (cachedResources == null || force) {
208
+ const api = await this.getProvidersApi();
209
+
210
+ const resources = await api.getBitbucketResourcesForCurrentUser(toTokenWithInfo(this.id, session));
211
+ this._workspaces.set(
212
+ accessToken,
213
+ resources != null ? resources.map(r => ({ ...r, key: r.id, name: r.name ?? r.slug })) : undefined,
214
+ );
215
+ }
216
+
217
+ return this._workspaces.get(accessToken);
218
+ }
219
+
220
+ protected override async searchProviderMyPullRequests(
221
+ session: ProviderAuthenticationSession,
222
+ repos?: BitbucketRepositoryDescriptor[],
223
+ ): Promise<PullRequest[] | undefined> {
224
+ if (repos != null) {
225
+ // TODO: implement repos version
226
+ return undefined;
227
+ }
228
+
229
+ const api = await this.getProvidersApi();
230
+ if (!api) {
231
+ return undefined;
232
+ }
233
+
234
+ const remotes = await this.ctx.repositories.getOpenRemotes();
235
+ const workspaceRepos = await nonnullSettled(
236
+ remotes.map(async (r: GitRemote) => {
237
+ const integration = await this.authenticationService.getByRemote(r);
238
+ const [namespace, name] = r.path.split('/');
239
+ return integration?.id === this.id ? { name: name, namespace: namespace } : undefined;
240
+ }),
241
+ );
242
+
243
+ const user = await this.getProviderCurrentAccount(session);
244
+ if (user?.username == null) return undefined;
245
+
246
+ const workspaces = await this.getProviderResourcesForCurrentUser(session);
247
+ if (workspaces == null || workspaces.length === 0) return undefined;
248
+
249
+ const authoredPrs = workspaces.map(async ws => {
250
+ const prs = await api.getBitbucketPullRequestsAuthoredByUserForWorkspace(
251
+ toTokenWithInfo(this.id, session),
252
+ user.id,
253
+ ws.slug,
254
+ );
255
+ return prs?.map(pr => fromProviderPullRequest(pr, this));
256
+ });
257
+
258
+ const reviewingPrs = api
259
+ .getPullRequestsForRepos(toTokenWithInfo(this.id, session), workspaceRepos, {
260
+ query: `state="OPEN" AND reviewers.uuid="${user.id}"`,
261
+ })
262
+ .then(r => r.values?.map(pr => fromProviderPullRequest(pr, this)));
263
+
264
+ return [
265
+ ...uniqueBy(
266
+ await flatSettled([...authoredPrs, reviewingPrs]),
267
+ pr => pr.url,
268
+ (orig, _cur) => orig,
269
+ ),
270
+ ];
271
+ }
272
+
273
+ protected override async searchProviderMyIssues(
274
+ session: ProviderAuthenticationSession,
275
+ repos?: BitbucketRepositoryDescriptor[],
276
+ ): Promise<IssueShape[] | undefined> {
277
+ if (repos == null || repos.length === 0) return undefined;
278
+
279
+ const user = await this.getProviderCurrentAccount(session);
280
+ if (user?.username == null) return undefined;
281
+
282
+ const api = await this.authenticationService.apis.bitbucket;
283
+ if (!api) return undefined;
284
+
285
+ const issueResult = await flatSettled(
286
+ repos.map(repo => {
287
+ return api.getUsersIssuesForRepo(
288
+ this,
289
+ toTokenWithInfo(this.id, session),
290
+ user.id,
291
+ repo.owner,
292
+ repo.name,
293
+ this.apiBaseUrl,
294
+ );
295
+ }),
296
+ );
297
+ return issueResult;
298
+ }
299
+
300
+ private readonly storagePrefix = 'bitbucket';
301
+ protected override async providerOnConnect(): Promise<void> {
302
+ if (this._session == null) return;
303
+
304
+ const accountStorageKey = md5(this._session.accessToken);
305
+
306
+ const storedAccount = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:account`);
307
+ const storedWorkspaces = this.ctx.storage.get(`${this.storagePrefix}:${accountStorageKey}:workspaces`);
308
+
309
+ let account: Account | undefined = storedAccount?.data ? { ...storedAccount.data, provider: this } : undefined;
310
+
311
+ let workspaces = storedWorkspaces?.data?.map((o: BitbucketWorkspaceDescriptor) => ({ ...o }));
312
+
313
+ if (storedAccount == null) {
314
+ account = await this.getProviderCurrentAccount(this._session);
315
+ if (account != null) {
316
+ // Clear all other stored workspaces and repositories and accounts when our session changes
317
+ await this.ctx.storage.deleteWithPrefix(this.storagePrefix);
318
+ await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:account`, {
319
+ v: 1,
320
+ timestamp: Date.now(),
321
+ data: {
322
+ id: account.id,
323
+ name: account.name,
324
+ email: account.email,
325
+ avatarUrl: account.avatarUrl,
326
+ username: account.username,
327
+ },
328
+ });
329
+ }
330
+ }
331
+ this._accounts ??= new Map<string, Account | undefined>();
332
+ this._accounts.set(this._session.accessToken, account);
333
+
334
+ if (storedWorkspaces == null) {
335
+ workspaces = await this.getProviderResourcesForCurrentUser(this._session, true);
336
+ await this.ctx.storage.store(`${this.storagePrefix}:${accountStorageKey}:workspaces`, {
337
+ v: 1,
338
+ timestamp: Date.now(),
339
+ data: workspaces,
340
+ });
341
+ }
342
+ this._workspaces ??= new Map<string, BitbucketWorkspaceDescriptor[] | undefined>();
343
+ this._workspaces.set(this._session.accessToken, workspaces);
344
+ }
345
+
346
+ protected override providerOnDisconnect(): void {
347
+ this._accounts = undefined;
348
+ this._workspaces = undefined;
349
+ }
350
+ }
@@ -0,0 +1,64 @@
1
+ import { AuthenticationErrorReason } from '../../../../git/errors.js';
2
+ import type { Provider } from '../../../../git/models/remoteProvider.js';
3
+ import type { GitHubApiConfig } from '../../../git-github/api/config.js';
4
+ import { GitHubApi } from '../../../git-github/api/github.js';
5
+ import type { IntegrationServiceContext } from '../../context.js';
6
+
7
+ export { GitHubApi } from '../../../git-github/api/github.js';
8
+
9
+ export function createGitHubApi(ctx: IntegrationServiceContext): GitHubApi {
10
+ const launchpad = () => ctx.config.getLaunchpadOptions();
11
+
12
+ const config: GitHubApiConfig = {
13
+ isWeb: ctx.http.isWeb,
14
+ fetch: ctx.http.fetch.bind(ctx.http),
15
+ wrapForForcedInsecureSSL: ctx.http.wrapForForcedInsecureSSL.bind(ctx.http),
16
+
17
+ onConfigChanged: (listener: () => void) =>
18
+ ctx.config.onDidChange(e => {
19
+ if (e.httpProxy) {
20
+ listener();
21
+ }
22
+ }),
23
+
24
+ onAuthenticationFailure: async (error, provider: Provider | undefined) => {
25
+ if (
26
+ error.reason === AuthenticationErrorReason.Unauthorized ||
27
+ error.reason === AuthenticationErrorReason.Forbidden
28
+ ) {
29
+ const reauthenticate = await ctx.hooks?.onReauthenticationRequired?.(
30
+ `${error.message}. Would you like to try reauthenticating${
31
+ error.reason === AuthenticationErrorReason.Forbidden ? ' to provide additional access' : ''
32
+ }?`,
33
+ );
34
+
35
+ if (reauthenticate) {
36
+ await provider?.reauthenticate();
37
+ return true;
38
+ }
39
+ } else {
40
+ ctx.hooks?.ui?.onError?.(error.message);
41
+ }
42
+ return false;
43
+ },
44
+
45
+ onRequestError: (provider: Provider | undefined, message: string) => {
46
+ if (message.includes('timeout')) {
47
+ ctx.hooks?.ui?.onRequestTimedOut?.(provider?.name ?? 'GitHub');
48
+ } else {
49
+ ctx.hooks?.ui?.onRequestFailed?.(message);
50
+ }
51
+ },
52
+
53
+ onDebugError: (message: string) => {
54
+ ctx.hooks?.ui?.onError?.(message);
55
+ },
56
+
57
+ getLaunchpadQueryLimit: () => launchpad().queryLimit ?? 100,
58
+ getLaunchpadIgnoredRepositories: () => [...(launchpad().ignoredRepositories ?? [])],
59
+ getLaunchpadIncludedOrganizations: () => [...(launchpad().includedOrganizations ?? [])],
60
+ getLaunchpadIgnoredOrganizations: () => [...(launchpad().ignoredOrganizations ?? [])],
61
+ };
62
+
63
+ return new GitHubApi(config);
64
+ }