@cat-factory/integrations 0.6.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 (242) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +68 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +84 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/modules/datadog/DatadogClient.d.ts +54 -0
  7. package/dist/modules/datadog/DatadogClient.d.ts.map +1 -0
  8. package/dist/modules/datadog/DatadogClient.js +132 -0
  9. package/dist/modules/datadog/DatadogClient.js.map +1 -0
  10. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts +30 -0
  11. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts.map +1 -0
  12. package/dist/modules/datadog/DatadogReleaseHealthProvider.js +101 -0
  13. package/dist/modules/datadog/DatadogReleaseHealthProvider.js.map +1 -0
  14. package/dist/modules/datadog/datadog.logic.d.ts +37 -0
  15. package/dist/modules/datadog/datadog.logic.d.ts.map +1 -0
  16. package/dist/modules/datadog/datadog.logic.js +90 -0
  17. package/dist/modules/datadog/datadog.logic.js.map +1 -0
  18. package/dist/modules/documents/ConfluenceProvider.d.ts +29 -0
  19. package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -0
  20. package/dist/modules/documents/ConfluenceProvider.js +180 -0
  21. package/dist/modules/documents/ConfluenceProvider.js.map +1 -0
  22. package/dist/modules/documents/DocumentConnectionService.d.ts +30 -0
  23. package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -0
  24. package/dist/modules/documents/DocumentConnectionService.js +69 -0
  25. package/dist/modules/documents/DocumentConnectionService.js.map +1 -0
  26. package/dist/modules/documents/DocumentImportService.d.ts +34 -0
  27. package/dist/modules/documents/DocumentImportService.d.ts.map +1 -0
  28. package/dist/modules/documents/DocumentImportService.js +83 -0
  29. package/dist/modules/documents/DocumentImportService.js.map +1 -0
  30. package/dist/modules/documents/DocumentLinkService.d.ts +31 -0
  31. package/dist/modules/documents/DocumentLinkService.d.ts.map +1 -0
  32. package/dist/modules/documents/DocumentLinkService.js +75 -0
  33. package/dist/modules/documents/DocumentLinkService.js.map +1 -0
  34. package/dist/modules/documents/DocumentPlannerService.d.ts +23 -0
  35. package/dist/modules/documents/DocumentPlannerService.d.ts.map +1 -0
  36. package/dist/modules/documents/DocumentPlannerService.js +96 -0
  37. package/dist/modules/documents/DocumentPlannerService.js.map +1 -0
  38. package/dist/modules/documents/GitHubDocsProvider.d.ts +42 -0
  39. package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -0
  40. package/dist/modules/documents/GitHubDocsProvider.js +86 -0
  41. package/dist/modules/documents/GitHubDocsProvider.js.map +1 -0
  42. package/dist/modules/documents/NotionProvider.d.ts +32 -0
  43. package/dist/modules/documents/NotionProvider.d.ts.map +1 -0
  44. package/dist/modules/documents/NotionProvider.js +221 -0
  45. package/dist/modules/documents/NotionProvider.js.map +1 -0
  46. package/dist/modules/documents/confluence.logic.d.ts +37 -0
  47. package/dist/modules/documents/confluence.logic.d.ts.map +1 -0
  48. package/dist/modules/documents/confluence.logic.js +133 -0
  49. package/dist/modules/documents/confluence.logic.js.map +1 -0
  50. package/dist/modules/documents/documents.logic.d.ts +22 -0
  51. package/dist/modules/documents/documents.logic.d.ts.map +1 -0
  52. package/dist/modules/documents/documents.logic.js +138 -0
  53. package/dist/modules/documents/documents.logic.js.map +1 -0
  54. package/dist/modules/documents/github-docs.logic.d.ts +52 -0
  55. package/dist/modules/documents/github-docs.logic.d.ts.map +1 -0
  56. package/dist/modules/documents/github-docs.logic.js +94 -0
  57. package/dist/modules/documents/github-docs.logic.js.map +1 -0
  58. package/dist/modules/documents/notion.logic.d.ts +31 -0
  59. package/dist/modules/documents/notion.logic.d.ts.map +1 -0
  60. package/dist/modules/documents/notion.logic.js +142 -0
  61. package/dist/modules/documents/notion.logic.js.map +1 -0
  62. package/dist/modules/email/EmailConnectionService.d.ts +34 -0
  63. package/dist/modules/email/EmailConnectionService.d.ts.map +1 -0
  64. package/dist/modules/email/EmailConnectionService.js +82 -0
  65. package/dist/modules/email/EmailConnectionService.js.map +1 -0
  66. package/dist/modules/email/adapters.d.ts +39 -0
  67. package/dist/modules/email/adapters.d.ts.map +1 -0
  68. package/dist/modules/email/adapters.js +79 -0
  69. package/dist/modules/email/adapters.js.map +1 -0
  70. package/dist/modules/environments/EnvironmentConnectionService.d.ts +42 -0
  71. package/dist/modules/environments/EnvironmentConnectionService.d.ts.map +1 -0
  72. package/dist/modules/environments/EnvironmentConnectionService.js +120 -0
  73. package/dist/modules/environments/EnvironmentConnectionService.js.map +1 -0
  74. package/dist/modules/environments/EnvironmentProvisioningService.d.ts +56 -0
  75. package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -0
  76. package/dist/modules/environments/EnvironmentProvisioningService.js +153 -0
  77. package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -0
  78. package/dist/modules/environments/EnvironmentTeardownService.d.ts +24 -0
  79. package/dist/modules/environments/EnvironmentTeardownService.d.ts.map +1 -0
  80. package/dist/modules/environments/EnvironmentTeardownService.js +54 -0
  81. package/dist/modules/environments/EnvironmentTeardownService.js.map +1 -0
  82. package/dist/modules/environments/HttpEnvironmentProvider.d.ts +30 -0
  83. package/dist/modules/environments/HttpEnvironmentProvider.d.ts.map +1 -0
  84. package/dist/modules/environments/HttpEnvironmentProvider.js +316 -0
  85. package/dist/modules/environments/HttpEnvironmentProvider.js.map +1 -0
  86. package/dist/modules/environments/environments.logic.d.ts +50 -0
  87. package/dist/modules/environments/environments.logic.d.ts.map +1 -0
  88. package/dist/modules/environments/environments.logic.js +257 -0
  89. package/dist/modules/environments/environments.logic.js.map +1 -0
  90. package/dist/modules/github/GitHubInstallationService.d.ts +66 -0
  91. package/dist/modules/github/GitHubInstallationService.d.ts.map +1 -0
  92. package/dist/modules/github/GitHubInstallationService.js +143 -0
  93. package/dist/modules/github/GitHubInstallationService.js.map +1 -0
  94. package/dist/modules/github/GitHubService.d.ts +29 -0
  95. package/dist/modules/github/GitHubService.d.ts.map +1 -0
  96. package/dist/modules/github/GitHubService.js +61 -0
  97. package/dist/modules/github/GitHubService.js.map +1 -0
  98. package/dist/modules/github/GitHubSyncService.d.ts +97 -0
  99. package/dist/modules/github/GitHubSyncService.d.ts.map +1 -0
  100. package/dist/modules/github/GitHubSyncService.js +241 -0
  101. package/dist/modules/github/GitHubSyncService.js.map +1 -0
  102. package/dist/modules/github/RepoProvisioningService.d.ts +26 -0
  103. package/dist/modules/github/RepoProvisioningService.d.ts.map +1 -0
  104. package/dist/modules/github/RepoProvisioningService.js +36 -0
  105. package/dist/modules/github/RepoProvisioningService.js.map +1 -0
  106. package/dist/modules/github/WebhookService.d.ts +28 -0
  107. package/dist/modules/github/WebhookService.d.ts.map +1 -0
  108. package/dist/modules/github/WebhookService.js +156 -0
  109. package/dist/modules/github/WebhookService.js.map +1 -0
  110. package/dist/modules/github/projection.logic.d.ts +95 -0
  111. package/dist/modules/github/projection.logic.d.ts.map +1 -0
  112. package/dist/modules/github/projection.logic.js +94 -0
  113. package/dist/modules/github/projection.logic.js.map +1 -0
  114. package/dist/modules/github/provisioning.logic.d.ts +11 -0
  115. package/dist/modules/github/provisioning.logic.d.ts.map +1 -0
  116. package/dist/modules/github/provisioning.logic.js +18 -0
  117. package/dist/modules/github/provisioning.logic.js.map +1 -0
  118. package/dist/modules/incident/incident.logic.d.ts +16 -0
  119. package/dist/modules/incident/incident.logic.d.ts.map +1 -0
  120. package/dist/modules/incident/incident.logic.js +23 -0
  121. package/dist/modules/incident/incident.logic.js.map +1 -0
  122. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts +26 -0
  123. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts.map +1 -0
  124. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js +84 -0
  125. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js.map +1 -0
  126. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts +27 -0
  127. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts.map +1 -0
  128. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js +65 -0
  129. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js.map +1 -0
  130. package/dist/modules/providers/ApiKeyService.d.ts +73 -0
  131. package/dist/modules/providers/ApiKeyService.d.ts.map +1 -0
  132. package/dist/modules/providers/ApiKeyService.js +122 -0
  133. package/dist/modules/providers/ApiKeyService.js.map +1 -0
  134. package/dist/modules/providers/LocalModelEndpointService.d.ts +52 -0
  135. package/dist/modules/providers/LocalModelEndpointService.d.ts.map +1 -0
  136. package/dist/modules/providers/LocalModelEndpointService.js +131 -0
  137. package/dist/modules/providers/LocalModelEndpointService.js.map +1 -0
  138. package/dist/modules/providers/PersonalSubscriptionService.d.ts +94 -0
  139. package/dist/modules/providers/PersonalSubscriptionService.d.ts.map +1 -0
  140. package/dist/modules/providers/PersonalSubscriptionService.js +218 -0
  141. package/dist/modules/providers/PersonalSubscriptionService.js.map +1 -0
  142. package/dist/modules/providers/ProviderSubscriptionService.d.ts +75 -0
  143. package/dist/modules/providers/ProviderSubscriptionService.d.ts.map +1 -0
  144. package/dist/modules/providers/ProviderSubscriptionService.js +130 -0
  145. package/dist/modules/providers/ProviderSubscriptionService.js.map +1 -0
  146. package/dist/modules/providers/localModelUrl.d.ts +7 -0
  147. package/dist/modules/providers/localModelUrl.d.ts.map +1 -0
  148. package/dist/modules/providers/localModelUrl.js +67 -0
  149. package/dist/modules/providers/localModelUrl.js.map +1 -0
  150. package/dist/modules/providers/providers.logic.d.ts +23 -0
  151. package/dist/modules/providers/providers.logic.d.ts.map +1 -0
  152. package/dist/modules/providers/providers.logic.js +46 -0
  153. package/dist/modules/providers/providers.logic.js.map +1 -0
  154. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts +51 -0
  155. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
  156. package/dist/modules/runners/HttpRunnerPoolProvider.js +304 -0
  157. package/dist/modules/runners/HttpRunnerPoolProvider.js.map +1 -0
  158. package/dist/modules/runners/RunnerPoolConnectionService.d.ts +47 -0
  159. package/dist/modules/runners/RunnerPoolConnectionService.d.ts.map +1 -0
  160. package/dist/modules/runners/RunnerPoolConnectionService.js +98 -0
  161. package/dist/modules/runners/RunnerPoolConnectionService.js.map +1 -0
  162. package/dist/modules/runners/RunnerPoolTransport.d.ts +11 -0
  163. package/dist/modules/runners/RunnerPoolTransport.d.ts.map +1 -0
  164. package/dist/modules/runners/RunnerPoolTransport.js +61 -0
  165. package/dist/modules/runners/RunnerPoolTransport.js.map +1 -0
  166. package/dist/modules/runners/runners.logic.d.ts +16 -0
  167. package/dist/modules/runners/runners.logic.d.ts.map +1 -0
  168. package/dist/modules/runners/runners.logic.js +52 -0
  169. package/dist/modules/runners/runners.logic.js.map +1 -0
  170. package/dist/modules/slack/SlackApiClient.d.ts +67 -0
  171. package/dist/modules/slack/SlackApiClient.d.ts.map +1 -0
  172. package/dist/modules/slack/SlackApiClient.js +132 -0
  173. package/dist/modules/slack/SlackApiClient.js.map +1 -0
  174. package/dist/modules/slack/SlackConnectionService.d.ts +41 -0
  175. package/dist/modules/slack/SlackConnectionService.d.ts.map +1 -0
  176. package/dist/modules/slack/SlackConnectionService.js +136 -0
  177. package/dist/modules/slack/SlackConnectionService.js.map +1 -0
  178. package/dist/modules/slack/SlackMemberMappingService.d.ts +17 -0
  179. package/dist/modules/slack/SlackMemberMappingService.d.ts.map +1 -0
  180. package/dist/modules/slack/SlackMemberMappingService.js +28 -0
  181. package/dist/modules/slack/SlackMemberMappingService.js.map +1 -0
  182. package/dist/modules/slack/SlackNotificationChannel.d.ts +45 -0
  183. package/dist/modules/slack/SlackNotificationChannel.d.ts.map +1 -0
  184. package/dist/modules/slack/SlackNotificationChannel.js +84 -0
  185. package/dist/modules/slack/SlackNotificationChannel.js.map +1 -0
  186. package/dist/modules/slack/SlackSettingsService.d.ts +16 -0
  187. package/dist/modules/slack/SlackSettingsService.d.ts.map +1 -0
  188. package/dist/modules/slack/SlackSettingsService.js +41 -0
  189. package/dist/modules/slack/SlackSettingsService.js.map +1 -0
  190. package/dist/modules/slack/slack.logic.d.ts +55 -0
  191. package/dist/modules/slack/slack.logic.d.ts.map +1 -0
  192. package/dist/modules/slack/slack.logic.js +149 -0
  193. package/dist/modules/slack/slack.logic.js.map +1 -0
  194. package/dist/modules/tasks/GitHubIssuesProvider.d.ts +50 -0
  195. package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -0
  196. package/dist/modules/tasks/GitHubIssuesProvider.js +92 -0
  197. package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -0
  198. package/dist/modules/tasks/JiraProvider.d.ts +29 -0
  199. package/dist/modules/tasks/JiraProvider.d.ts.map +1 -0
  200. package/dist/modules/tasks/JiraProvider.js +114 -0
  201. package/dist/modules/tasks/JiraProvider.js.map +1 -0
  202. package/dist/modules/tasks/TaskConnectionService.d.ts +30 -0
  203. package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -0
  204. package/dist/modules/tasks/TaskConnectionService.js +69 -0
  205. package/dist/modules/tasks/TaskConnectionService.js.map +1 -0
  206. package/dist/modules/tasks/TaskImportService.d.ts +34 -0
  207. package/dist/modules/tasks/TaskImportService.d.ts.map +1 -0
  208. package/dist/modules/tasks/TaskImportService.js +96 -0
  209. package/dist/modules/tasks/TaskImportService.js.map +1 -0
  210. package/dist/modules/tasks/TaskLinkService.d.ts +30 -0
  211. package/dist/modules/tasks/TaskLinkService.d.ts.map +1 -0
  212. package/dist/modules/tasks/TaskLinkService.js +56 -0
  213. package/dist/modules/tasks/TaskLinkService.js.map +1 -0
  214. package/dist/modules/tasks/github-issues.logic.d.ts +35 -0
  215. package/dist/modules/tasks/github-issues.logic.d.ts.map +1 -0
  216. package/dist/modules/tasks/github-issues.logic.js +67 -0
  217. package/dist/modules/tasks/github-issues.logic.js.map +1 -0
  218. package/dist/modules/tasks/jira.logic.d.ts +28 -0
  219. package/dist/modules/tasks/jira.logic.d.ts.map +1 -0
  220. package/dist/modules/tasks/jira.logic.js +151 -0
  221. package/dist/modules/tasks/jira.logic.js.map +1 -0
  222. package/dist/modules/tasks/tasks.logic.d.ts +12 -0
  223. package/dist/modules/tasks/tasks.logic.d.ts.map +1 -0
  224. package/dist/modules/tasks/tasks.logic.js +17 -0
  225. package/dist/modules/tasks/tasks.logic.js.map +1 -0
  226. package/dist/modules/tracker/TicketTrackerService.d.ts +45 -0
  227. package/dist/modules/tracker/TicketTrackerService.d.ts.map +1 -0
  228. package/dist/modules/tracker/TicketTrackerService.js +52 -0
  229. package/dist/modules/tracker/TicketTrackerService.js.map +1 -0
  230. package/dist/modules/tracker/base64.d.ts +2 -0
  231. package/dist/modules/tracker/base64.d.ts.map +1 -0
  232. package/dist/modules/tracker/base64.js +18 -0
  233. package/dist/modules/tracker/base64.js.map +1 -0
  234. package/dist/modules/tracker/github.create.logic.d.ts +16 -0
  235. package/dist/modules/tracker/github.create.logic.d.ts.map +1 -0
  236. package/dist/modules/tracker/github.create.logic.js +25 -0
  237. package/dist/modules/tracker/github.create.logic.js.map +1 -0
  238. package/dist/modules/tracker/jira.create.logic.d.ts +31 -0
  239. package/dist/modules/tracker/jira.create.logic.d.ts.map +1 -0
  240. package/dist/modules/tracker/jira.create.logic.js +59 -0
  241. package/dist/modules/tracker/jira.create.logic.js.map +1 -0
  242. package/package.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubService.js","sourceRoot":"","sources":["../../../src/modules/github/GitHubService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import type { Clock } from '@cat-factory/kernel';
2
+ import type { GitHubClient } from '@cat-factory/kernel';
3
+ import type { BranchProjectionRepository, CheckRunProjectionRepository, CommitProjectionRepository, GitHubInstallationRepository, IssueProjectionRepository, PullRequestProjectionRepository, RepoProjectionRepository } from '@cat-factory/kernel';
4
+ import type { GitHubAvailableRepo, GitHubRepo, RepoTreeEntry } from '@cat-factory/kernel';
5
+ export interface GitHubSyncServiceDependencies {
6
+ githubClient: GitHubClient;
7
+ githubInstallationRepository: GitHubInstallationRepository;
8
+ repoProjectionRepository: RepoProjectionRepository;
9
+ branchProjectionRepository: BranchProjectionRepository;
10
+ pullRequestProjectionRepository: PullRequestProjectionRepository;
11
+ issueProjectionRepository: IssueProjectionRepository;
12
+ commitProjectionRepository: CommitProjectionRepository;
13
+ checkRunProjectionRepository: CheckRunProjectionRepository;
14
+ clock: Clock;
15
+ /**
16
+ * Bounds the initial commit backfill: when a repo has no commit cursor yet
17
+ * (its first sync), commits are listed only from `now - commitBackfillHorizonMs`
18
+ * rather than from the dawn of the repo. This keeps a large/monorepo connect
19
+ * from inserting its entire history in one step. Subsequent syncs use the
20
+ * (more recent) cursor. Undefined means backfill the full history (legacy).
21
+ */
22
+ commitBackfillHorizonMs?: number;
23
+ }
24
+ export declare class GitHubSyncService {
25
+ private readonly deps;
26
+ constructor(deps: GitHubSyncServiceDependencies);
27
+ /**
28
+ * The repos the workspace's installation can access, annotated with whether
29
+ * this workspace currently links each one. Repos are linked *explicitly* per
30
+ * workspace, so the connect UI lists these and the user picks a subset.
31
+ */
32
+ listAvailableRepos(workspaceId: string): Promise<GitHubAvailableRepo[]>;
33
+ /**
34
+ * Mark (or unmark) a repo as a monorepo (hosting several services, each pinned
35
+ * to a subdirectory). The flag is board-owned state on the projection. Lazily
36
+ * links the repo first if the workspace doesn't track it yet — the "add an
37
+ * existing repo as a service" flow flips this toggle before the repo is added,
38
+ * so it may not be linked. Throws only if the repo isn't accessible to the
39
+ * installation (the App hasn't been granted it).
40
+ */
41
+ setRepoMonorepo(workspaceId: string, repoGithubId: number, isMonorepo: boolean): Promise<GitHubRepo>;
42
+ /**
43
+ * List the entries of a directory (one level) in a tracked repo, on its default
44
+ * branch, so the monorepo service picker can browse the repo and pin a service to a
45
+ * subdirectory. `path` is repo-root-relative ('' = the root). Directories are
46
+ * returned first (the picker navigates into those), then files for context.
47
+ */
48
+ listRepoDirectory(workspaceId: string, repoGithubId: number, path?: string): Promise<RepoTreeEntry[]>;
49
+ /**
50
+ * Link a single repo into this workspace without disturbing the rest (unlike
51
+ * {@link setLinkedRepos}, which sets the exact set and tombstones the others).
52
+ * Projects + deep-syncs the repo the first time it's seen, and is a no-op that
53
+ * returns the live row when it's already tracked. Returns null when the repo is
54
+ * not accessible to the installation (the App hasn't been granted it yet) — the
55
+ * caller surfaces a "grant the App access" hint. Backs the "add an existing
56
+ * repo as a board service" flow, where the workspace may not link the repo yet.
57
+ */
58
+ linkRepo(workspaceId: string, repoGithubId: number): Promise<GitHubRepo | null>;
59
+ /**
60
+ * Set the exact set of repos this workspace links. Projects the newly selected
61
+ * repos (from those the installation can access), tombstones any deselected
62
+ * repo, then deep-syncs each linked repo. Returns the workspace's live repos.
63
+ */
64
+ setLinkedRepos(workspaceId: string, repoGithubIds: number[]): Promise<GitHubRepo[]>;
65
+ /**
66
+ * Run one incremental fetch→upsert→cursor cycle for a single resource kind.
67
+ * Reads the prior cursor, fetches (conditionally, via the prior ETag/`since`),
68
+ * upserts when there's anything new, then advances the cursor. The differences
69
+ * between resources (how the request is shaped and how the next cursor is
70
+ * derived) are supplied by the callbacks; the cursor bookkeeping is shared.
71
+ */
72
+ private syncResource;
73
+ /** Every workspace in the installation's org that actually links this repo. */
74
+ private linkedWorkspaces;
75
+ /**
76
+ * Incrementally resync one repo's branches, PRs, issues, commits and checks. The repo
77
+ * is fetched from GitHub ONCE (installation-scoped cursor) and each projection is fanned
78
+ * out to every workspace in the org that links it, so two teams sharing a repo cost one
79
+ * API round-trip, not two. Pass `full` (at link time) to bypass the shared cursor and
80
+ * fully populate a freshly-linked workspace.
81
+ */
82
+ syncRepo(repo: GitHubRepo, options?: {
83
+ full?: boolean;
84
+ }): Promise<void>;
85
+ /** Resync a single tracked repo by its GitHub id (used by the queue consumer). */
86
+ syncRepoById(workspaceId: string, repoGithubId: number): Promise<void>;
87
+ /** Incremental resync of every repo this workspace links. */
88
+ resyncWorkspace(workspaceId: string): Promise<void>;
89
+ /**
90
+ * Full backfill for an installation: deep-sync the linked repos of every
91
+ * workspace it backs (the connector workspace plus all workspaces in its
92
+ * account). Repos are linked explicitly, so backfill refreshes what's linked
93
+ * rather than rediscovering the whole installation.
94
+ */
95
+ backfillInstallation(installationId: number): Promise<void>;
96
+ }
97
+ //# sourceMappingURL=GitHubSyncService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubSyncService.d.ts","sourceRoot":"","sources":["../../../src/modules/github/GitHubSyncService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAiB,MAAM,qBAAqB,CAAA;AACtE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,+BAA+B,EAC/B,wBAAwB,EAGzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAczF,MAAM,WAAW,6BAA6B;IAC5C,YAAY,EAAE,YAAY,CAAA;IAC1B,4BAA4B,EAAE,4BAA4B,CAAA;IAC1D,wBAAwB,EAAE,wBAAwB,CAAA;IAClD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD,+BAA+B,EAAE,+BAA+B,CAAA;IAChE,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD,4BAA4B,EAAE,4BAA4B,CAAA;IAC1D,KAAK,EAAE,KAAK,CAAA;IACZ;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,6BAA6B,EAAI;IAEpE;;;;OAIG;IACG,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAkB5E;IAED;;;;;;;OAOG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,UAAU,CAAC,CAOrB;IAED;;;;;OAKG;IACG,iBAAiB,CACrB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,SAAK,GACR,OAAO,CAAC,aAAa,EAAE,CAAC,CAyB1B;IAED;;;;;;;;OAQG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAepF;IAED;;;;OAIG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAuBxF;IAED;;;;;;OAMG;YACW,YAAY;IA+B1B,+EAA+E;YACjE,gBAAgB;IAO9B;;;;;;OAMG;IACG,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsGhF;IAED,kFAAkF;IAC5E,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG3E;IAED,6DAA6D;IACvD,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxD;IAED;;;;;OAKG;IACG,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;CACF"}
@@ -0,0 +1,241 @@
1
+ export class GitHubSyncService {
2
+ deps;
3
+ constructor(deps) {
4
+ this.deps = deps;
5
+ }
6
+ /**
7
+ * The repos the workspace's installation can access, annotated with whether
8
+ * this workspace currently links each one. Repos are linked *explicitly* per
9
+ * workspace, so the connect UI lists these and the user picks a subset.
10
+ */
11
+ async listAvailableRepos(workspaceId) {
12
+ const installation = await this.deps.githubInstallationRepository.getByWorkspace(workspaceId);
13
+ if (!installation || installation.deletedAt)
14
+ return [];
15
+ const { items } = await this.deps.githubClient.listInstallationRepos(installation.installationId);
16
+ const tracked = new Map((await this.deps.repoProjectionRepository.list(workspaceId)).map((r) => [r.githubId, r]));
17
+ return items.map((r) => ({
18
+ githubId: r.githubId,
19
+ owner: r.owner,
20
+ name: r.name,
21
+ defaultBranch: r.defaultBranch,
22
+ private: r.private,
23
+ linked: tracked.has(r.githubId),
24
+ isMonorepo: tracked.get(r.githubId)?.isMonorepo ?? false,
25
+ }));
26
+ }
27
+ /**
28
+ * Mark (or unmark) a repo as a monorepo (hosting several services, each pinned
29
+ * to a subdirectory). The flag is board-owned state on the projection. Lazily
30
+ * links the repo first if the workspace doesn't track it yet — the "add an
31
+ * existing repo as a service" flow flips this toggle before the repo is added,
32
+ * so it may not be linked. Throws only if the repo isn't accessible to the
33
+ * installation (the App hasn't been granted it).
34
+ */
35
+ async setRepoMonorepo(workspaceId, repoGithubId, isMonorepo) {
36
+ const existing = await this.linkRepo(workspaceId, repoGithubId);
37
+ if (!existing) {
38
+ throw new Error(`Repo ${repoGithubId} is not accessible to workspace '${workspaceId}'`);
39
+ }
40
+ await this.deps.repoProjectionRepository.setMonorepo(workspaceId, repoGithubId, isMonorepo);
41
+ return { ...existing, isMonorepo };
42
+ }
43
+ /**
44
+ * List the entries of a directory (one level) in a tracked repo, on its default
45
+ * branch, so the monorepo service picker can browse the repo and pin a service to a
46
+ * subdirectory. `path` is repo-root-relative ('' = the root). Directories are
47
+ * returned first (the picker navigates into those), then files for context.
48
+ */
49
+ async listRepoDirectory(workspaceId, repoGithubId, path = '') {
50
+ const installation = await this.deps.githubInstallationRepository.getByWorkspace(workspaceId);
51
+ if (!installation || installation.deletedAt)
52
+ return [];
53
+ // Lazily link the repo if the workspace doesn't track it yet (the add-service
54
+ // flow browses the tree before the repo is added), same as setRepoMonorepo.
55
+ const repo = await this.linkRepo(workspaceId, repoGithubId);
56
+ if (!repo) {
57
+ throw new Error(`Repo ${repoGithubId} is not accessible to workspace '${workspaceId}'`);
58
+ }
59
+ const entries = await this.deps.githubClient.listDirectory(installation.installationId, { owner: repo.owner, repo: repo.name }, path.replace(/^\/+|\/+$/g, ''), repo.defaultBranch ?? undefined);
60
+ const mapped = entries.map((e) => ({
61
+ path: e.path,
62
+ name: e.name,
63
+ type: e.type,
64
+ }));
65
+ return mapped.sort((a, b) => {
66
+ if (a.type === 'dir' && b.type !== 'dir')
67
+ return -1;
68
+ if (a.type !== 'dir' && b.type === 'dir')
69
+ return 1;
70
+ return a.name.localeCompare(b.name);
71
+ });
72
+ }
73
+ /**
74
+ * Link a single repo into this workspace without disturbing the rest (unlike
75
+ * {@link setLinkedRepos}, which sets the exact set and tombstones the others).
76
+ * Projects + deep-syncs the repo the first time it's seen, and is a no-op that
77
+ * returns the live row when it's already tracked. Returns null when the repo is
78
+ * not accessible to the installation (the App hasn't been granted it yet) — the
79
+ * caller surfaces a "grant the App access" hint. Backs the "add an existing
80
+ * repo as a board service" flow, where the workspace may not link the repo yet.
81
+ */
82
+ async linkRepo(workspaceId, repoGithubId) {
83
+ const existing = await this.deps.repoProjectionRepository.get(workspaceId, repoGithubId);
84
+ if (existing)
85
+ return existing;
86
+ const installation = await this.deps.githubInstallationRepository.getByWorkspace(workspaceId);
87
+ if (!installation || installation.deletedAt)
88
+ return null;
89
+ const installationId = installation.installationId;
90
+ const { items } = await this.deps.githubClient.listInstallationRepos(installationId);
91
+ const match = items.find((r) => r.githubId === repoGithubId);
92
+ if (!match)
93
+ return null;
94
+ const repo = { ...match, installationId, syncedAt: this.deps.clock.now() };
95
+ await this.deps.repoProjectionRepository.upsertMany(workspaceId, [repo]);
96
+ // Full pass: the org cursor may already be advanced, so bypass it to populate this
97
+ // newly-linked workspace.
98
+ await this.syncRepo(repo, { full: true });
99
+ return this.deps.repoProjectionRepository.get(workspaceId, repoGithubId);
100
+ }
101
+ /**
102
+ * Set the exact set of repos this workspace links. Projects the newly selected
103
+ * repos (from those the installation can access), tombstones any deselected
104
+ * repo, then deep-syncs each linked repo. Returns the workspace's live repos.
105
+ */
106
+ async setLinkedRepos(workspaceId, repoGithubIds) {
107
+ const installation = await this.deps.githubInstallationRepository.getByWorkspace(workspaceId);
108
+ if (!installation || installation.deletedAt)
109
+ return [];
110
+ const installationId = installation.installationId;
111
+ const wanted = new Set(repoGithubIds);
112
+ const { items } = await this.deps.githubClient.listInstallationRepos(installationId);
113
+ const selected = items
114
+ .filter((r) => wanted.has(r.githubId))
115
+ .map((r) => ({ ...r, installationId, syncedAt: this.deps.clock.now() }));
116
+ if (selected.length > 0) {
117
+ await this.deps.repoProjectionRepository.upsertMany(workspaceId, selected);
118
+ }
119
+ // Tombstone every previously-linked repo for this installation that is no
120
+ // longer selected (the "seen" set is exactly the new selection).
121
+ await this.deps.repoProjectionRepository.tombstoneMissing(workspaceId, installationId, selected.map((r) => r.githubId), this.deps.clock.now());
122
+ for (const repo of selected)
123
+ await this.syncRepo(repo, { full: true });
124
+ return this.deps.repoProjectionRepository.list(workspaceId);
125
+ }
126
+ /**
127
+ * Run one incremental fetch→upsert→cursor cycle for a single resource kind.
128
+ * Reads the prior cursor, fetches (conditionally, via the prior ETag/`since`),
129
+ * upserts when there's anything new, then advances the cursor. The differences
130
+ * between resources (how the request is shaped and how the next cursor is
131
+ * derived) are supplied by the callbacks; the cursor bookkeeping is shared.
132
+ */
133
+ async syncResource(installationId, repoGithubId, kind, full, fetch, upsert, nextCursor) {
134
+ const repos = this.deps.repoProjectionRepository;
135
+ // The cursor is installation-scoped (shared across the org's workspaces). A `full`
136
+ // pass ignores it (treats it as empty) so a newly-linked workspace gets fully
137
+ // populated even though the org's cursor is already advanced.
138
+ const cursor = full ? null : await repos.getCursor(installationId, repoGithubId, kind);
139
+ const res = await fetch(cursor);
140
+ if (!res.notModified && res.items.length > 0)
141
+ await upsert(res.items);
142
+ await repos.setCursor(installationId, repoGithubId, kind, nextCursor(cursor, res.etag, this.deps.clock.now()));
143
+ return res;
144
+ }
145
+ /** Every workspace in the installation's org that actually links this repo. */
146
+ async linkedWorkspaces(installationId, repoGithubId) {
147
+ const all = await this.deps.githubInstallationRepository.listWorkspacesForInstallation(installationId);
148
+ // One batched query for the whole org, instead of a `get` per workspace.
149
+ return this.deps.repoProjectionRepository.linkedWorkspaces(repoGithubId, all);
150
+ }
151
+ /**
152
+ * Incrementally resync one repo's branches, PRs, issues, commits and checks. The repo
153
+ * is fetched from GitHub ONCE (installation-scoped cursor) and each projection is fanned
154
+ * out to every workspace in the org that links it, so two teams sharing a repo cost one
155
+ * API round-trip, not two. Pass `full` (at link time) to bypass the shared cursor and
156
+ * fully populate a freshly-linked workspace.
157
+ */
158
+ async syncRepo(repo, options = {}) {
159
+ const full = options.full ?? false;
160
+ const ref = { owner: repo.owner, repo: repo.name };
161
+ const id = repo.githubId;
162
+ const installationId = repo.installationId;
163
+ const client = this.deps.githubClient;
164
+ const workspaces = await this.linkedWorkspaces(installationId, id);
165
+ const fanOut = async (apply) => {
166
+ for (const ws of workspaces)
167
+ await apply(ws);
168
+ };
169
+ // ETag-conditional cursor: carry the prior ETag forward when the fetch
170
+ // returns none. PRs/issues (`stampSince`) additionally record a fresh
171
+ // `sinceIso` lower bound for the next delta; branches don't paginate by date.
172
+ const etagCursor = (stampSince) => (prev, etag, now) => ({
173
+ etag: etag ?? prev?.etag ?? null,
174
+ lastSyncedAt: now,
175
+ sinceIso: stampSince ? new Date(now).toISOString() : null,
176
+ });
177
+ // Branches — conditional GET via ETag.
178
+ const branches = await this.syncResource(installationId, id, 'branches', full, (cursor) => client.listBranches(installationId, ref, cursor?.etag ?? undefined), (items) => fanOut((ws) => this.deps.branchProjectionRepository.upsertMany(ws, items)), etagCursor(false));
179
+ const defaultBranchSha = branches.items.find((b) => b.name === repo.defaultBranch)?.headSha ?? null;
180
+ // Pull requests — delta by `since` (GitHub's updated_at lower bound).
181
+ await this.syncResource(installationId, id, 'pulls', full, (cursor) => client.listPullRequests(installationId, ref, {
182
+ since: cursor?.sinceIso ?? undefined,
183
+ etag: cursor?.etag ?? undefined,
184
+ }), (items) => fanOut((ws) => this.deps.pullRequestProjectionRepository.upsertMany(ws, items)), etagCursor(true));
185
+ // Issues — delta by `since`.
186
+ await this.syncResource(installationId, id, 'issues', full, (cursor) => client.listIssues(installationId, ref, {
187
+ since: cursor?.sinceIso ?? undefined,
188
+ etag: cursor?.etag ?? undefined,
189
+ }), (items) => fanOut((ws) => this.deps.issueProjectionRepository.upsertMany(ws, items)), etagCursor(true));
190
+ // Commits — delta by `since` on the default branch. On the first sync there
191
+ // is no cursor, so fall back to the backfill horizon (if configured) instead
192
+ // of fetching the repo's entire commit history in one step.
193
+ const commitBackfillSince = this.deps.commitBackfillHorizonMs !== undefined
194
+ ? new Date(this.deps.clock.now() - this.deps.commitBackfillHorizonMs).toISOString()
195
+ : undefined;
196
+ await this.syncResource(installationId, id, 'commits', full, (cursor) => client.listCommits(installationId, ref, {
197
+ since: cursor?.sinceIso ?? commitBackfillSince,
198
+ }), (items) => fanOut((ws) => this.deps.commitProjectionRepository.upsertMany(ws, items)), (_prev, _etag, now) => ({
199
+ etag: null,
200
+ lastSyncedAt: now,
201
+ sinceIso: new Date(now).toISOString(),
202
+ }));
203
+ // Check runs for the default-branch head (CI gating signal). Not cursor-based.
204
+ if (defaultBranchSha) {
205
+ const checks = await client.listCheckRuns(installationId, ref, defaultBranchSha);
206
+ if (checks.items.length > 0) {
207
+ await fanOut((ws) => this.deps.checkRunProjectionRepository.upsertMany(ws, checks.items));
208
+ }
209
+ }
210
+ // Stamp the repo row as freshly synced for every workspace that links it.
211
+ const now = this.deps.clock.now();
212
+ await fanOut((ws) => this.deps.repoProjectionRepository.upsertMany(ws, [{ ...repo, syncedAt: now }]));
213
+ }
214
+ /** Resync a single tracked repo by its GitHub id (used by the queue consumer). */
215
+ async syncRepoById(workspaceId, repoGithubId) {
216
+ const repo = await this.deps.repoProjectionRepository.get(workspaceId, repoGithubId);
217
+ if (repo)
218
+ await this.syncRepo(repo);
219
+ }
220
+ /** Incremental resync of every repo this workspace links. */
221
+ async resyncWorkspace(workspaceId) {
222
+ const repos = await this.deps.repoProjectionRepository.list(workspaceId);
223
+ for (const repo of repos)
224
+ await this.syncRepo(repo);
225
+ }
226
+ /**
227
+ * Full backfill for an installation: deep-sync the linked repos of every
228
+ * workspace it backs (the connector workspace plus all workspaces in its
229
+ * account). Repos are linked explicitly, so backfill refreshes what's linked
230
+ * rather than rediscovering the whole installation.
231
+ */
232
+ async backfillInstallation(installationId) {
233
+ const installation = await this.deps.githubInstallationRepository.getByInstallationId(installationId);
234
+ if (!installation || installation.deletedAt)
235
+ return;
236
+ const workspaceIds = await this.deps.githubInstallationRepository.listWorkspacesForInstallation(installationId);
237
+ for (const ws of workspaceIds)
238
+ await this.resyncWorkspace(ws);
239
+ }
240
+ }
241
+ //# sourceMappingURL=GitHubSyncService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubSyncService.js","sourceRoot":"","sources":["../../../src/modules/github/GitHubSyncService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { CreateRepoInput, GitHubProvisioningClient, ProvisionedRepo } from '@cat-factory/kernel';
2
+ /** Why a repo wasn't created directly (informational; the caller delegates regardless). */
3
+ export type DelegationReason = 'insufficient_permissions' | 'forbidden' | 'already_exists';
4
+ export type ProvisionResult = {
5
+ status: 'created';
6
+ repo: ProvisionedRepo;
7
+ } | {
8
+ status: 'delegated';
9
+ reason: DelegationReason;
10
+ };
11
+ export interface RepoProvisioningServiceDependencies {
12
+ /** Mints tokens for the installation's owning App (the registry resolver). */
13
+ client: GitHubProvisioningClient;
14
+ }
15
+ export declare class RepoProvisioningService {
16
+ private readonly deps;
17
+ constructor(deps: RepoProvisioningServiceDependencies);
18
+ /**
19
+ * Create `input.name` under `input.org` using `installationId`'s credentials.
20
+ * Guards proactively on the installation's *granted* permissions (skips a
21
+ * guaranteed-403 round trip); a live 403 or a 422 "already exists" also resolve
22
+ * to `delegated` so the caller's manual/existing-repo path takes over.
23
+ */
24
+ provision(installationId: number, input: CreateRepoInput): Promise<ProvisionResult>;
25
+ }
26
+ //# sourceMappingURL=RepoProvisioningService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoProvisioningService.d.ts","sourceRoot":"","sources":["../../../src/modules/github/RepoProvisioningService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAU5B,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GACxB,0BAA0B,GAC1B,WAAW,GACX,gBAAgB,CAAA;AAEpB,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAErD,MAAM,WAAW,mCAAmC;IAClD,8EAA8E;IAC9E,MAAM,EAAE,wBAAwB,CAAA;CACjC;AAOD,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,mCAAmC,EAAI;IAE1E;;;;;OAKG;IACG,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAexF;CACF"}
@@ -0,0 +1,36 @@
1
+ import { canCreateRepo } from './provisioning.logic.js';
2
+ /** Sniff an HTTP status without coupling to a specific error class. */
3
+ function statusOf(err) {
4
+ return err?.status;
5
+ }
6
+ export class RepoProvisioningService {
7
+ deps;
8
+ constructor(deps) {
9
+ this.deps = deps;
10
+ }
11
+ /**
12
+ * Create `input.name` under `input.org` using `installationId`'s credentials.
13
+ * Guards proactively on the installation's *granted* permissions (skips a
14
+ * guaranteed-403 round trip); a live 403 or a 422 "already exists" also resolve
15
+ * to `delegated` so the caller's manual/existing-repo path takes over.
16
+ */
17
+ async provision(installationId, input) {
18
+ const permissions = await this.deps.client.getGrantedPermissions(installationId);
19
+ if (!canCreateRepo(permissions)) {
20
+ return { status: 'delegated', reason: 'insufficient_permissions' };
21
+ }
22
+ try {
23
+ const repo = await this.deps.client.createRepoInOrg(installationId, input);
24
+ return { status: 'created', repo };
25
+ }
26
+ catch (err) {
27
+ const status = statusOf(err);
28
+ if (status === 403)
29
+ return { status: 'delegated', reason: 'forbidden' };
30
+ if (status === 422)
31
+ return { status: 'delegated', reason: 'already_exists' };
32
+ throw err;
33
+ }
34
+ }
35
+ }
36
+ //# sourceMappingURL=RepoProvisioningService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RepoProvisioningService.js","sourceRoot":"","sources":["../../../src/modules/github/RepoProvisioningService.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAwBvD,uEAAuE;AACvE,SAAS,QAAQ,CAAC,GAAY;IAC5B,OAAQ,GAAkC,EAAE,MAAM,CAAA;AACpD,CAAC;AAED,MAAM,OAAO,uBAAuB;IACL,IAAI;IAAjC,YAA6B,IAAyC;oBAAzC,IAAI;IAAwC,CAAC;IAE1E;;;;;OAKG;IACH,KAAK,CAAC,SAAS,CAAC,cAAsB,EAAE,KAAsB;QAC5D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAA;QAChF,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAA;QACpE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,cAAc,EAAE,KAAK,CAAC,CAAA;YAC1E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;YACvE,IAAI,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAA;YAC5E,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import type { Clock } from '@cat-factory/kernel';
2
+ import type { BranchProjectionRepository, CheckRunProjectionRepository, CommitProjectionRepository, GitHubInstallationRepository, IssueProjectionRepository, PullRequestProjectionRepository, RepoProjectionRepository } from '@cat-factory/kernel';
3
+ export interface WebhookServiceDependencies {
4
+ githubInstallationRepository: GitHubInstallationRepository;
5
+ repoProjectionRepository: RepoProjectionRepository;
6
+ branchProjectionRepository: BranchProjectionRepository;
7
+ pullRequestProjectionRepository: PullRequestProjectionRepository;
8
+ issueProjectionRepository: IssueProjectionRepository;
9
+ commitProjectionRepository: CommitProjectionRepository;
10
+ checkRunProjectionRepository: CheckRunProjectionRepository;
11
+ clock: Clock;
12
+ }
13
+ export declare class WebhookService {
14
+ private readonly deps;
15
+ constructor(deps: WebhookServiceDependencies);
16
+ /** Apply a verified webhook delivery to the local projections. */
17
+ handle(eventName: string, payload: unknown): Promise<void>;
18
+ /**
19
+ * Apply `project` to every workspace backed by this installation that actually
20
+ * links the affected repo. Since repos are linked explicitly per workspace, an
21
+ * event for a repo only updates the boards that chose to track it.
22
+ */
23
+ private forEachLinkedWorkspace;
24
+ private handleInstallation;
25
+ private installationIdOf;
26
+ private repoIdOf;
27
+ }
28
+ //# sourceMappingURL=WebhookService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebhookService.d.ts","sourceRoot":"","sources":["../../../src/modules/github/WebhookService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAyB5B,MAAM,WAAW,0BAA0B;IACzC,4BAA4B,EAAE,4BAA4B,CAAA;IAC1D,wBAAwB,EAAE,wBAAwB,CAAA;IAClD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD,+BAA+B,EAAE,+BAA+B,CAAA;IAChE,yBAAyB,EAAE,yBAAyB,CAAA;IACpD,0BAA0B,EAAE,0BAA0B,CAAA;IACtD,4BAA4B,EAAE,4BAA4B,CAAA;IAC1D,KAAK,EAAE,KAAK,CAAA;CACb;AAQD,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,0BAA0B,EAAI;IAEjE,kEAAkE;IAC5D,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF/D;IAED;;;;OAIG;YACW,sBAAsB;YAatB,kBAAkB;IAgDhC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,QAAQ;CAKjB"}
@@ -0,0 +1,156 @@
1
+ import { pullRepoGithubId, toCheckRunProjection, toCommitProjection, toIssueProjection, toPullRequestProjection, } from './projection.logic.js';
2
+ function asObject(value) {
3
+ return typeof value === 'object' && value !== null ? value : null;
4
+ }
5
+ export class WebhookService {
6
+ deps;
7
+ constructor(deps) {
8
+ this.deps = deps;
9
+ }
10
+ /** Apply a verified webhook delivery to the local projections. */
11
+ async handle(eventName, payload) {
12
+ const root = asObject(payload);
13
+ if (!root)
14
+ return;
15
+ if (eventName === 'installation' || eventName === 'installation_repositories') {
16
+ await this.handleInstallation(eventName, root);
17
+ return;
18
+ }
19
+ const installationId = this.installationIdOf(root);
20
+ if (installationId === null)
21
+ return;
22
+ const installation = await this.deps.githubInstallationRepository.getByInstallationId(installationId);
23
+ if (!installation || installation.deletedAt)
24
+ return;
25
+ const now = this.deps.clock.now();
26
+ switch (eventName) {
27
+ case 'pull_request': {
28
+ const pr = asObject(root.pull_request);
29
+ if (!pr)
30
+ return;
31
+ const repoId = pullRepoGithubId(pr) ?? this.repoIdOf(root);
32
+ if (repoId === null)
33
+ return;
34
+ await this.forEachLinkedWorkspace(installationId, repoId, (ws) => this.deps.pullRequestProjectionRepository.upsertMany(ws, [
35
+ toPullRequestProjection(pr, repoId, now),
36
+ ]));
37
+ return;
38
+ }
39
+ case 'issues': {
40
+ const issue = asObject(root.issue);
41
+ const repoId = this.repoIdOf(root);
42
+ if (!issue || repoId === null)
43
+ return;
44
+ await this.forEachLinkedWorkspace(installationId, repoId, (ws) => this.deps.issueProjectionRepository.upsertMany(ws, [
45
+ toIssueProjection(issue, repoId, now),
46
+ ]));
47
+ return;
48
+ }
49
+ case 'push': {
50
+ const repoId = this.repoIdOf(root);
51
+ if (repoId === null)
52
+ return;
53
+ // Update the pushed branch head and project the new commits.
54
+ const ref = typeof root.ref === 'string' ? root.ref : '';
55
+ const after = typeof root.after === 'string' ? root.after : '';
56
+ const commits = Array.isArray(root.commits) ? root.commits : [];
57
+ await this.forEachLinkedWorkspace(installationId, repoId, async (ws) => {
58
+ if (ref.startsWith('refs/heads/') && after) {
59
+ await this.deps.branchProjectionRepository.upsertMany(ws, [
60
+ {
61
+ repoGithubId: repoId,
62
+ name: ref.slice('refs/heads/'.length),
63
+ headSha: after,
64
+ protected: false,
65
+ syncedAt: now,
66
+ },
67
+ ]);
68
+ }
69
+ if (commits.length > 0) {
70
+ await this.deps.commitProjectionRepository.upsertMany(ws, commits.map((c) => toCommitProjection(c, repoId, now)));
71
+ }
72
+ });
73
+ return;
74
+ }
75
+ case 'check_run': {
76
+ const check = asObject(root.check_run);
77
+ const repoId = this.repoIdOf(root);
78
+ if (!check || repoId === null)
79
+ return;
80
+ await this.forEachLinkedWorkspace(installationId, repoId, (ws) => this.deps.checkRunProjectionRepository.upsertMany(ws, [
81
+ toCheckRunProjection(check, repoId, now),
82
+ ]));
83
+ return;
84
+ }
85
+ default:
86
+ // Unhandled event kind: nothing to project incrementally.
87
+ return;
88
+ }
89
+ }
90
+ /**
91
+ * Apply `project` to every workspace backed by this installation that actually
92
+ * links the affected repo. Since repos are linked explicitly per workspace, an
93
+ * event for a repo only updates the boards that chose to track it.
94
+ */
95
+ async forEachLinkedWorkspace(installationId, repoGithubId, project) {
96
+ const workspaceIds = await this.deps.githubInstallationRepository.listWorkspacesForInstallation(installationId);
97
+ for (const ws of workspaceIds) {
98
+ const repo = await this.deps.repoProjectionRepository.get(ws, repoGithubId);
99
+ if (repo)
100
+ await project(ws);
101
+ }
102
+ }
103
+ async handleInstallation(eventName, root) {
104
+ const installationId = this.installationIdOf(root);
105
+ if (installationId === null)
106
+ return;
107
+ const installation = await this.deps.githubInstallationRepository.getByInstallationId(installationId);
108
+ if (!installation)
109
+ return;
110
+ const now = this.deps.clock.now();
111
+ const action = typeof root.action === 'string' ? root.action : '';
112
+ // Lifecycle: suspend/uninstall tombstones the binding (account-wide, since the
113
+ // installation is shared); unsuspend revives it. Repos are NOT auto-projected
114
+ // here — they are linked explicitly per workspace.
115
+ if (eventName === 'installation') {
116
+ if (action === 'deleted' || action === 'suspend') {
117
+ await this.deps.githubInstallationRepository.softDelete(installationId, now);
118
+ }
119
+ else if (action === 'unsuspend') {
120
+ await this.deps.githubInstallationRepository.upsert({ ...installation, deletedAt: null });
121
+ }
122
+ return;
123
+ }
124
+ // installation_repositories: a removed repo is no longer accessible, so
125
+ // tombstone it in every workspace that linked it. Added repos just become
126
+ // available — the user links them explicitly, so we don't project them here.
127
+ const removed = Array.isArray(root.repositories_removed)
128
+ ? root.repositories_removed
129
+ : [];
130
+ if (removed.length === 0)
131
+ return;
132
+ const workspaceIds = await this.deps.githubInstallationRepository.listWorkspacesForInstallation(installationId);
133
+ for (const ws of workspaceIds) {
134
+ const tracked = await this.deps.repoProjectionRepository.list(ws);
135
+ const removedIds = new Set(removed.map((r) => r.id));
136
+ const remaining = tracked
137
+ .filter((repo) => repo.installationId === installationId && !removedIds.has(repo.githubId))
138
+ .map((repo) => repo.githubId);
139
+ // Only rewrite when this workspace actually tracks one of the removed repos.
140
+ if (remaining.length !== tracked.filter((r) => r.installationId === installationId).length) {
141
+ await this.deps.repoProjectionRepository.tombstoneMissing(ws, installationId, remaining, now);
142
+ }
143
+ }
144
+ }
145
+ installationIdOf(root) {
146
+ const inst = asObject(root.installation);
147
+ const id = inst?.id;
148
+ return typeof id === 'number' ? id : null;
149
+ }
150
+ repoIdOf(root) {
151
+ const repo = asObject(root.repository);
152
+ const id = repo?.id;
153
+ return typeof id === 'number' ? id : null;
154
+ }
155
+ }
156
+ //# sourceMappingURL=WebhookService.js.map