@mastra/factory 0.2.2-alpha.0 → 0.2.2-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/auth.d.ts +2 -2
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +401 -314
  5. package/dist/auth.js.map +1 -1
  6. package/dist/capabilities/connection.js +1 -1
  7. package/dist/capabilities/intake.js +1 -1
  8. package/dist/capabilities/version-control.js +1 -1
  9. package/dist/factory.d.ts.map +1 -1
  10. package/dist/factory.js +441 -39455
  11. package/dist/factory.js.map +1 -1
  12. package/dist/index.js +2 -39466
  13. package/dist/integrations/base.js +1 -1
  14. package/dist/integrations/github/config.js +36 -22
  15. package/dist/integrations/github/config.js.map +1 -1
  16. package/dist/integrations/github/factory-session.js +33 -37
  17. package/dist/integrations/github/factory-session.js.map +1 -1
  18. package/dist/integrations/github/integration.js +1037 -3624
  19. package/dist/integrations/github/integration.js.map +1 -1
  20. package/dist/integrations/github/issue-triage.js +71 -71
  21. package/dist/integrations/github/issue-triage.js.map +1 -1
  22. package/dist/integrations/github/pat.js +47 -36
  23. package/dist/integrations/github/pat.js.map +1 -1
  24. package/dist/integrations/github/provenance.js +72 -101
  25. package/dist/integrations/github/provenance.js.map +1 -1
  26. package/dist/integrations/github/routes.d.ts.map +1 -1
  27. package/dist/integrations/github/routes.js +1272 -1833
  28. package/dist/integrations/github/routes.js.map +1 -1
  29. package/dist/integrations/github/rules.js +203 -471
  30. package/dist/integrations/github/rules.js.map +1 -1
  31. package/dist/integrations/github/sandbox.d.ts +2 -0
  32. package/dist/integrations/github/sandbox.d.ts.map +1 -1
  33. package/dist/integrations/github/sandbox.js +401 -326
  34. package/dist/integrations/github/sandbox.js.map +1 -1
  35. package/dist/integrations/github/session-subscriptions.js +165 -223
  36. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  37. package/dist/integrations/github/subscriptions.js +43 -51
  38. package/dist/integrations/github/subscriptions.js.map +1 -1
  39. package/dist/integrations/github/token-refresh.js +15 -18
  40. package/dist/integrations/github/token-refresh.js.map +1 -1
  41. package/dist/integrations/github/webhook.js +359 -343
  42. package/dist/integrations/github/webhook.js.map +1 -1
  43. package/dist/integrations/linear/agent-tools.js +77 -100
  44. package/dist/integrations/linear/agent-tools.js.map +1 -1
  45. package/dist/integrations/linear/integration.js +611 -1309
  46. package/dist/integrations/linear/integration.js.map +1 -1
  47. package/dist/integrations/linear/routes.js +227 -230
  48. package/dist/integrations/linear/routes.js.map +1 -1
  49. package/dist/integrations/linear/rules.js +126 -346
  50. package/dist/integrations/linear/rules.js.map +1 -1
  51. package/dist/integrations/linear/storage.js +1 -1
  52. package/dist/integrations/platform/api-client.js +131 -135
  53. package/dist/integrations/platform/api-client.js.map +1 -1
  54. package/dist/integrations/platform/github/event-worker.js +275 -573
  55. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  56. package/dist/integrations/platform/github/integration.d.ts.map +1 -1
  57. package/dist/integrations/platform/github/integration.js +845 -3942
  58. package/dist/integrations/platform/github/integration.js.map +1 -1
  59. package/dist/integrations/platform/linear/integration.js +457 -1309
  60. package/dist/integrations/platform/linear/integration.js.map +1 -1
  61. package/dist/integrations/workos/integration.js +80 -85
  62. package/dist/integrations/workos/integration.js.map +1 -1
  63. package/dist/routes/config.d.ts.map +1 -1
  64. package/dist/routes/config.js +933 -915
  65. package/dist/routes/config.js.map +1 -1
  66. package/dist/routes/custom-provider-source.js +110 -93
  67. package/dist/routes/custom-provider-source.js.map +1 -1
  68. package/dist/routes/fs.js +401 -349
  69. package/dist/routes/fs.js.map +1 -1
  70. package/dist/routes/intake.js +165 -165
  71. package/dist/routes/intake.js.map +1 -1
  72. package/dist/routes/oauth.js +447 -25166
  73. package/dist/routes/oauth.js.map +1 -1
  74. package/dist/routes/projects.js +437 -376
  75. package/dist/routes/projects.js.map +1 -1
  76. package/dist/routes/provider-credentials.js +76 -58
  77. package/dist/routes/provider-credentials.js.map +1 -1
  78. package/dist/routes/route.js +12 -8
  79. package/dist/routes/route.js.map +1 -1
  80. package/dist/routes/skills.js +160 -173
  81. package/dist/routes/skills.js.map +1 -1
  82. package/dist/routes/surface.js +250 -28618
  83. package/dist/routes/surface.js.map +1 -1
  84. package/dist/routes/tenant-credentials.js +141 -166
  85. package/dist/routes/tenant-credentials.js.map +1 -1
  86. package/dist/routes/work-items.js +654 -862
  87. package/dist/routes/work-items.js.map +1 -1
  88. package/dist/rules/binding-context.js +23 -35
  89. package/dist/rules/binding-context.js.map +1 -1
  90. package/dist/rules/defaults.js +200 -309
  91. package/dist/rules/defaults.js.map +1 -1
  92. package/dist/rules/dispatcher.d.ts.map +1 -1
  93. package/dist/rules/dispatcher.js +438 -677
  94. package/dist/rules/dispatcher.js.map +1 -1
  95. package/dist/rules/index.js +5 -599
  96. package/dist/rules/processor.js +344 -596
  97. package/dist/rules/processor.js.map +1 -1
  98. package/dist/rules/resolve.js +21 -18
  99. package/dist/rules/resolve.js.map +1 -1
  100. package/dist/rules/start-coordinator.js +168 -157
  101. package/dist/rules/start-coordinator.js.map +1 -1
  102. package/dist/rules/tools.js +50 -85
  103. package/dist/rules/tools.js.map +1 -1
  104. package/dist/rules/transition-service.js +183 -454
  105. package/dist/rules/transition-service.js.map +1 -1
  106. package/dist/rules/types.js +33 -29
  107. package/dist/rules/types.js.map +1 -1
  108. package/dist/rules/validation.js +266 -281
  109. package/dist/rules/validation.js.map +1 -1
  110. package/dist/sandbox/fleet.js +272 -250
  111. package/dist/sandbox/fleet.js.map +1 -1
  112. package/dist/sandbox/reattach.js +13 -6
  113. package/dist/sandbox/reattach.js.map +1 -1
  114. package/dist/server-error.js +12 -16
  115. package/dist/server-error.js.map +1 -1
  116. package/dist/skills/service.js +30 -35
  117. package/dist/skills/service.js.map +1 -1
  118. package/dist/spa-static.d.ts.map +1 -1
  119. package/dist/spa-static.js +91 -64
  120. package/dist/spa-static.js.map +1 -1
  121. package/dist/state-signing.js +73 -44
  122. package/dist/state-signing.js.map +1 -1
  123. package/dist/storage/domains/audit/agent-audit.js +60 -59
  124. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  125. package/dist/storage/domains/audit/base.js +169 -112
  126. package/dist/storage/domains/audit/base.js.map +1 -1
  127. package/dist/storage/domains/audit/domain.js +155 -153
  128. package/dist/storage/domains/audit/domain.js.map +1 -1
  129. package/dist/storage/domains/credentials/base.js +259 -243
  130. package/dist/storage/domains/credentials/base.js.map +1 -1
  131. package/dist/storage/domains/custom-providers/base.js +138 -143
  132. package/dist/storage/domains/custom-providers/base.js.map +1 -1
  133. package/dist/storage/domains/intake/base.js +75 -57
  134. package/dist/storage/domains/intake/base.js.map +1 -1
  135. package/dist/storage/domains/integrations/base.js +310 -245
  136. package/dist/storage/domains/integrations/base.js.map +1 -1
  137. package/dist/storage/domains/memory-settings/base.js +117 -102
  138. package/dist/storage/domains/memory-settings/base.js.map +1 -1
  139. package/dist/storage/domains/model-packs/base.js +89 -88
  140. package/dist/storage/domains/model-packs/base.js.map +1 -1
  141. package/dist/storage/domains/projects/base.js +97 -92
  142. package/dist/storage/domains/projects/base.js.map +1 -1
  143. package/dist/storage/domains/queue-health/base.js +111 -76
  144. package/dist/storage/domains/queue-health/base.js.map +1 -1
  145. package/dist/storage/domains/source-control/base.d.ts +9 -0
  146. package/dist/storage/domains/source-control/base.d.ts.map +1 -1
  147. package/dist/storage/domains/source-control/base.js +777 -702
  148. package/dist/storage/domains/source-control/base.js.map +1 -1
  149. package/dist/storage/domains/source-control/inmemory.d.ts +4 -0
  150. package/dist/storage/domains/source-control/inmemory.d.ts.map +1 -1
  151. package/dist/storage/domains/source-control/inmemory.js +322 -344
  152. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  153. package/dist/storage/domains/work-items/base.d.ts.map +1 -1
  154. package/dist/storage/domains/work-items/base.js +1266 -1132
  155. package/dist/storage/domains/work-items/base.js.map +1 -1
  156. package/dist/storage/domains/work-items/metrics.js +202 -184
  157. package/dist/storage/domains/work-items/metrics.js.map +1 -1
  158. package/dist/timing.d.ts +15 -0
  159. package/dist/timing.d.ts.map +1 -0
  160. package/dist/timing.js +34 -0
  161. package/dist/timing.js.map +1 -0
  162. package/dist/workspace.d.ts +2 -3
  163. package/dist/workspace.d.ts.map +1 -1
  164. package/dist/workspace.js +236 -438
  165. package/dist/workspace.js.map +1 -1
  166. package/factory-skills/factory-review/SKILL.md +9 -2
  167. package/package.json +9 -9
  168. package/dist/capabilities/connection.js.map +0 -1
  169. package/dist/capabilities/intake.js.map +0 -1
  170. package/dist/capabilities/version-control.js.map +0 -1
  171. package/dist/index.js.map +0 -1
  172. package/dist/integrations/base.js.map +0 -1
  173. package/dist/integrations/linear/storage.js.map +0 -1
  174. package/dist/rules/index.js.map +0 -1
@@ -1,721 +1,796 @@
1
- // src/storage/domains/source-control/base.ts
2
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- var FACTORY_PROJECTS = "factory_projects";
4
- var INSTALLATIONS = "source_control_installations";
5
- var REPOSITORIES = "source_control_repositories";
6
- var CONNECTIONS = "factory_project_source_control_connections";
7
- var PROJECT_REPOSITORIES = "factory_project_repositories";
8
- var SANDBOXES = "source_control_project_repository_sandboxes";
9
- var WORKTREES = "source_control_worktrees";
10
- var SESSIONS = "source_control_sessions";
11
- var SOURCE_CONTROL_SCHEMAS = [
12
- {
13
- name: INSTALLATIONS,
14
- columns: {
15
- id: { type: "uuid-pk" },
16
- integration_id: { type: "text" },
17
- org_id: { type: "text" },
18
- connected_by_user_id: { type: "text" },
19
- external_id: { type: "text" },
20
- account_name: { type: "text", nullable: true },
21
- account_type: { type: "text", nullable: true },
22
- provider_metadata: { type: "json" },
23
- created_at: { type: "timestamp" }
24
- },
25
- uniqueIndexes: [
26
- {
27
- name: "source_control_installations_integration_org_external_unique",
28
- columns: ["integration_id", "org_id", "external_id"]
29
- }
30
- ]
31
- },
32
- {
33
- name: REPOSITORIES,
34
- columns: {
35
- id: { type: "uuid-pk" },
36
- installation_id: { type: "text" },
37
- external_id: { type: "text" },
38
- slug: { type: "text" },
39
- default_branch: { type: "text", default: "main" },
40
- provider_metadata: { type: "json" },
41
- created_at: { type: "timestamp" },
42
- updated_at: { type: "timestamp" }
43
- },
44
- uniqueIndexes: [
45
- {
46
- name: "source_control_repositories_installation_external_unique",
47
- columns: ["installation_id", "external_id"]
48
- }
49
- ],
50
- indexes: [
51
- {
52
- name: "source_control_repositories_installation_slug_idx",
53
- columns: ["installation_id", "slug"]
54
- }
55
- ]
56
- },
57
- {
58
- name: CONNECTIONS,
59
- columns: {
60
- id: { type: "uuid-pk" },
61
- factory_project_id: { type: "text" },
62
- integration_id: { type: "text" },
63
- installation_id: { type: "text" },
64
- created_by_user_id: { type: "text" },
65
- created_at: { type: "timestamp" }
66
- },
67
- uniqueIndexes: [
68
- {
69
- name: "factory_project_source_control_connections_project_integration_installation_unique",
70
- columns: ["factory_project_id", "integration_id", "installation_id"]
71
- }
72
- ],
73
- indexes: [
74
- {
75
- name: "factory_project_source_control_connections_project_idx",
76
- columns: ["factory_project_id"]
77
- }
78
- ]
79
- },
80
- {
81
- name: PROJECT_REPOSITORIES,
82
- columns: {
83
- id: { type: "uuid-pk" },
84
- connection_id: { type: "text" },
85
- repository_id: { type: "text" },
86
- created_by_user_id: { type: "text" },
87
- branch: { type: "text", nullable: true },
88
- sandbox_provider: { type: "text" },
89
- sandbox_workdir: { type: "text" },
90
- setup_command: { type: "text", nullable: true },
91
- created_at: { type: "timestamp" },
92
- updated_at: { type: "timestamp" }
93
- },
94
- uniqueIndexes: [
95
- {
96
- name: "factory_project_repositories_connection_repository_unique",
97
- columns: ["connection_id", "repository_id"]
98
- }
99
- ],
100
- indexes: [
101
- {
102
- name: "factory_project_repositories_connection_idx",
103
- columns: ["connection_id"]
104
- }
105
- ]
106
- },
107
- {
108
- name: SANDBOXES,
109
- columns: {
110
- id: { type: "uuid-pk" },
111
- project_repository_id: { type: "text" },
112
- user_id: { type: "text" },
113
- sandbox_id: { type: "text", nullable: true },
114
- sandbox_workdir: { type: "text" },
115
- materialized_at: { type: "timestamp", nullable: true },
116
- created_at: { type: "timestamp" }
117
- },
118
- uniqueIndexes: [
119
- {
120
- name: "source_control_project_repository_sandboxes_link_user_unique",
121
- columns: ["project_repository_id", "user_id"]
122
- }
123
- ]
124
- },
125
- {
126
- name: WORKTREES,
127
- columns: {
128
- id: { type: "uuid-pk" },
129
- project_repository_id: { type: "text" },
130
- user_id: { type: "text" },
131
- branch: { type: "text" },
132
- base_branch: { type: "text" },
133
- worktree_path: { type: "text" },
134
- created_at: { type: "timestamp" }
135
- },
136
- uniqueIndexes: [
137
- {
138
- name: "source_control_worktrees_project_repository_user_branch_unique",
139
- columns: ["project_repository_id", "user_id", "branch"]
140
- }
141
- ]
142
- },
143
- {
144
- name: SESSIONS,
145
- columns: {
146
- id: { type: "uuid-pk" },
147
- session_id: { type: "text" },
148
- project_repository_id: { type: "text" },
149
- org_id: { type: "text" },
150
- user_id: { type: "text" },
151
- branch: { type: "text" },
152
- base_branch: { type: "text" },
153
- sandbox_id: { type: "text", nullable: true },
154
- sandbox_workdir: { type: "text", nullable: true },
155
- materialized_at: { type: "timestamp", nullable: true },
156
- created_at: { type: "timestamp" },
157
- updated_at: { type: "timestamp" }
158
- },
159
- uniqueIndexes: [
160
- { name: "source_control_sessions_session_id_unique", columns: ["session_id"] },
161
- {
162
- name: "source_control_sessions_repository_user_branch_unique",
163
- columns: ["project_repository_id", "user_id", "branch"]
164
- }
165
- ]
166
- }
2
+ //#region src/storage/domains/source-control/base.ts
3
+ const FACTORY_PROJECTS = "factory_projects";
4
+ const INSTALLATIONS = "source_control_installations";
5
+ const REPOSITORIES = "source_control_repositories";
6
+ const CONNECTIONS = "factory_project_source_control_connections";
7
+ const PROJECT_REPOSITORIES = "factory_project_repositories";
8
+ const SANDBOXES = "source_control_project_repository_sandboxes";
9
+ const WORKTREES = "source_control_worktrees";
10
+ const SESSIONS = "source_control_sessions";
11
+ const SOURCE_CONTROL_SCHEMAS = [
12
+ {
13
+ name: INSTALLATIONS,
14
+ columns: {
15
+ id: { type: "uuid-pk" },
16
+ integration_id: { type: "text" },
17
+ org_id: { type: "text" },
18
+ connected_by_user_id: { type: "text" },
19
+ external_id: { type: "text" },
20
+ account_name: {
21
+ type: "text",
22
+ nullable: true
23
+ },
24
+ account_type: {
25
+ type: "text",
26
+ nullable: true
27
+ },
28
+ provider_metadata: { type: "json" },
29
+ created_at: { type: "timestamp" }
30
+ },
31
+ uniqueIndexes: [{
32
+ name: "source_control_installations_integration_org_external_unique",
33
+ columns: [
34
+ "integration_id",
35
+ "org_id",
36
+ "external_id"
37
+ ]
38
+ }]
39
+ },
40
+ {
41
+ name: REPOSITORIES,
42
+ columns: {
43
+ id: { type: "uuid-pk" },
44
+ installation_id: { type: "text" },
45
+ external_id: { type: "text" },
46
+ slug: { type: "text" },
47
+ default_branch: {
48
+ type: "text",
49
+ default: "main"
50
+ },
51
+ provider_metadata: { type: "json" },
52
+ created_at: { type: "timestamp" },
53
+ updated_at: { type: "timestamp" }
54
+ },
55
+ uniqueIndexes: [{
56
+ name: "source_control_repositories_installation_external_unique",
57
+ columns: ["installation_id", "external_id"]
58
+ }],
59
+ indexes: [{
60
+ name: "source_control_repositories_installation_slug_idx",
61
+ columns: ["installation_id", "slug"]
62
+ }]
63
+ },
64
+ {
65
+ name: CONNECTIONS,
66
+ columns: {
67
+ id: { type: "uuid-pk" },
68
+ factory_project_id: { type: "text" },
69
+ integration_id: { type: "text" },
70
+ installation_id: { type: "text" },
71
+ created_by_user_id: { type: "text" },
72
+ created_at: { type: "timestamp" }
73
+ },
74
+ uniqueIndexes: [{
75
+ name: "factory_project_source_control_connections_project_integration_installation_unique",
76
+ columns: [
77
+ "factory_project_id",
78
+ "integration_id",
79
+ "installation_id"
80
+ ]
81
+ }],
82
+ indexes: [{
83
+ name: "factory_project_source_control_connections_project_idx",
84
+ columns: ["factory_project_id"]
85
+ }]
86
+ },
87
+ {
88
+ name: PROJECT_REPOSITORIES,
89
+ columns: {
90
+ id: { type: "uuid-pk" },
91
+ connection_id: { type: "text" },
92
+ repository_id: { type: "text" },
93
+ created_by_user_id: { type: "text" },
94
+ branch: {
95
+ type: "text",
96
+ nullable: true
97
+ },
98
+ sandbox_provider: { type: "text" },
99
+ sandbox_workdir: { type: "text" },
100
+ setup_command: {
101
+ type: "text",
102
+ nullable: true
103
+ },
104
+ created_at: { type: "timestamp" },
105
+ updated_at: { type: "timestamp" }
106
+ },
107
+ uniqueIndexes: [{
108
+ name: "factory_project_repositories_connection_repository_unique",
109
+ columns: ["connection_id", "repository_id"]
110
+ }],
111
+ indexes: [{
112
+ name: "factory_project_repositories_connection_idx",
113
+ columns: ["connection_id"]
114
+ }]
115
+ },
116
+ {
117
+ name: SANDBOXES,
118
+ columns: {
119
+ id: { type: "uuid-pk" },
120
+ project_repository_id: { type: "text" },
121
+ user_id: { type: "text" },
122
+ sandbox_id: {
123
+ type: "text",
124
+ nullable: true
125
+ },
126
+ sandbox_workdir: { type: "text" },
127
+ materialized_at: {
128
+ type: "timestamp",
129
+ nullable: true
130
+ },
131
+ created_at: { type: "timestamp" }
132
+ },
133
+ uniqueIndexes: [{
134
+ name: "source_control_project_repository_sandboxes_link_user_unique",
135
+ columns: ["project_repository_id", "user_id"]
136
+ }]
137
+ },
138
+ {
139
+ name: WORKTREES,
140
+ columns: {
141
+ id: { type: "uuid-pk" },
142
+ project_repository_id: { type: "text" },
143
+ user_id: { type: "text" },
144
+ branch: { type: "text" },
145
+ base_branch: { type: "text" },
146
+ worktree_path: { type: "text" },
147
+ created_at: { type: "timestamp" }
148
+ },
149
+ uniqueIndexes: [{
150
+ name: "source_control_worktrees_project_repository_user_branch_unique",
151
+ columns: [
152
+ "project_repository_id",
153
+ "user_id",
154
+ "branch"
155
+ ]
156
+ }]
157
+ },
158
+ {
159
+ name: SESSIONS,
160
+ columns: {
161
+ id: { type: "uuid-pk" },
162
+ session_id: { type: "text" },
163
+ project_repository_id: { type: "text" },
164
+ org_id: { type: "text" },
165
+ user_id: { type: "text" },
166
+ branch: { type: "text" },
167
+ base_branch: { type: "text" },
168
+ sandbox_id: {
169
+ type: "text",
170
+ nullable: true
171
+ },
172
+ sandbox_workdir: {
173
+ type: "text",
174
+ nullable: true
175
+ },
176
+ materialized_at: {
177
+ type: "timestamp",
178
+ nullable: true
179
+ },
180
+ created_at: { type: "timestamp" },
181
+ updated_at: { type: "timestamp" }
182
+ },
183
+ uniqueIndexes: [{
184
+ name: "source_control_sessions_session_id_unique",
185
+ columns: ["session_id"]
186
+ }, {
187
+ name: "source_control_sessions_repository_user_branch_unique",
188
+ columns: [
189
+ "project_repository_id",
190
+ "user_id",
191
+ "branch"
192
+ ]
193
+ }]
194
+ }
167
195
  ];
168
196
  function toInstallation(row) {
169
- return {
170
- id: row.id,
171
- integrationId: row.integration_id,
172
- orgId: row.org_id,
173
- connectedByUserId: row.connected_by_user_id,
174
- externalId: row.external_id,
175
- accountName: row.account_name,
176
- accountType: row.account_type,
177
- providerMetadata: row.provider_metadata,
178
- createdAt: row.created_at
179
- };
197
+ return {
198
+ id: row.id,
199
+ integrationId: row.integration_id,
200
+ orgId: row.org_id,
201
+ connectedByUserId: row.connected_by_user_id,
202
+ externalId: row.external_id,
203
+ accountName: row.account_name,
204
+ accountType: row.account_type,
205
+ providerMetadata: row.provider_metadata,
206
+ createdAt: row.created_at
207
+ };
180
208
  }
181
209
  function toRepository(row) {
182
- return {
183
- id: row.id,
184
- installationId: row.installation_id,
185
- externalId: row.external_id,
186
- slug: row.slug,
187
- defaultBranch: row.default_branch,
188
- providerMetadata: row.provider_metadata,
189
- createdAt: row.created_at,
190
- updatedAt: row.updated_at
191
- };
210
+ return {
211
+ id: row.id,
212
+ installationId: row.installation_id,
213
+ externalId: row.external_id,
214
+ slug: row.slug,
215
+ defaultBranch: row.default_branch,
216
+ providerMetadata: row.provider_metadata,
217
+ createdAt: row.created_at,
218
+ updatedAt: row.updated_at
219
+ };
192
220
  }
193
221
  function toConnection(row) {
194
- return {
195
- id: row.id,
196
- factoryProjectId: row.factory_project_id,
197
- integrationId: row.integration_id,
198
- installationId: row.installation_id,
199
- createdByUserId: row.created_by_user_id,
200
- createdAt: row.created_at
201
- };
222
+ return {
223
+ id: row.id,
224
+ factoryProjectId: row.factory_project_id,
225
+ integrationId: row.integration_id,
226
+ installationId: row.installation_id,
227
+ createdByUserId: row.created_by_user_id,
228
+ createdAt: row.created_at
229
+ };
202
230
  }
203
231
  function toProjectRepository(row) {
204
- return {
205
- id: row.id,
206
- connectionId: row.connection_id,
207
- repositoryId: row.repository_id,
208
- createdByUserId: row.created_by_user_id,
209
- branch: row.branch,
210
- sandboxProvider: row.sandbox_provider,
211
- sandboxWorkdir: row.sandbox_workdir,
212
- setupCommand: row.setup_command,
213
- createdAt: row.created_at,
214
- updatedAt: row.updated_at
215
- };
232
+ return {
233
+ id: row.id,
234
+ connectionId: row.connection_id,
235
+ repositoryId: row.repository_id,
236
+ createdByUserId: row.created_by_user_id,
237
+ branch: row.branch,
238
+ sandboxProvider: row.sandbox_provider,
239
+ sandboxWorkdir: row.sandbox_workdir,
240
+ setupCommand: row.setup_command,
241
+ createdAt: row.created_at,
242
+ updatedAt: row.updated_at
243
+ };
216
244
  }
217
245
  function toSandbox(row) {
218
- return {
219
- id: row.id,
220
- projectRepositoryId: row.project_repository_id,
221
- userId: row.user_id,
222
- sandboxId: row.sandbox_id,
223
- sandboxWorkdir: row.sandbox_workdir,
224
- materializedAt: row.materialized_at,
225
- createdAt: row.created_at
226
- };
246
+ return {
247
+ id: row.id,
248
+ projectRepositoryId: row.project_repository_id,
249
+ userId: row.user_id,
250
+ sandboxId: row.sandbox_id,
251
+ sandboxWorkdir: row.sandbox_workdir,
252
+ materializedAt: row.materialized_at,
253
+ createdAt: row.created_at
254
+ };
227
255
  }
228
256
  function toWorktree(row) {
229
- return {
230
- id: row.id,
231
- projectRepositoryId: row.project_repository_id,
232
- userId: row.user_id,
233
- branch: row.branch,
234
- baseBranch: row.base_branch,
235
- worktreePath: row.worktree_path,
236
- createdAt: row.created_at
237
- };
257
+ return {
258
+ id: row.id,
259
+ projectRepositoryId: row.project_repository_id,
260
+ userId: row.user_id,
261
+ branch: row.branch,
262
+ baseBranch: row.base_branch,
263
+ worktreePath: row.worktree_path,
264
+ createdAt: row.created_at
265
+ };
238
266
  }
239
267
  function toSession(row) {
240
- return {
241
- id: row.id,
242
- sessionId: row.session_id,
243
- projectRepositoryId: row.project_repository_id,
244
- orgId: row.org_id,
245
- userId: row.user_id,
246
- branch: row.branch,
247
- baseBranch: row.base_branch,
248
- sandboxId: row.sandbox_id,
249
- sandboxWorkdir: row.sandbox_workdir,
250
- materializedAt: row.materialized_at,
251
- createdAt: row.created_at,
252
- updatedAt: row.updated_at
253
- };
268
+ return {
269
+ id: row.id,
270
+ sessionId: row.session_id,
271
+ projectRepositoryId: row.project_repository_id,
272
+ orgId: row.org_id,
273
+ userId: row.user_id,
274
+ branch: row.branch,
275
+ baseBranch: row.base_branch,
276
+ sandboxId: row.sandbox_id,
277
+ sandboxWorkdir: row.sandbox_workdir,
278
+ materializedAt: row.materialized_at,
279
+ createdAt: row.created_at,
280
+ updatedAt: row.updated_at
281
+ };
254
282
  }
255
283
  var SourceControlStorage = class extends FactoryStorageDomain {
256
- constructor() {
257
- super("source-control");
258
- }
259
- async init() {
260
- await this.ensureCollections(SOURCE_CONTROL_SCHEMAS);
261
- }
262
- async dangerouslyClearAll() {
263
- await this.ops.deleteMany(SESSIONS, {});
264
- await this.ops.deleteMany(WORKTREES, {});
265
- await this.ops.deleteMany(SANDBOXES, {});
266
- await this.ops.deleteMany(PROJECT_REPOSITORIES, {});
267
- await this.ops.deleteMany(CONNECTIONS, {});
268
- await this.ops.deleteMany(REPOSITORIES, {});
269
- await this.ops.deleteMany(INSTALLATIONS, {});
270
- }
271
- forIntegration(integrationId) {
272
- if (!integrationId.trim()) throw new Error("[SourceControlStorage] integrationId must not be empty.");
273
- const db = () => this.ops;
274
- const getInstallation = async (args) => {
275
- const row = await db().findOne(INSTALLATIONS, {
276
- id: args.id,
277
- integration_id: integrationId,
278
- org_id: args.orgId
279
- });
280
- return row ? toInstallation(row) : null;
281
- };
282
- const requireInstallation = async (args) => {
283
- const installation = await getInstallation(args);
284
- if (!installation)
285
- throw new Error("Source-control installation not found for this organization and integration.");
286
- return installation;
287
- };
288
- const getRepository = async (args) => {
289
- const row = await db().findOne(REPOSITORIES, { id: args.id });
290
- if (!row || !await getInstallation({ orgId: args.orgId, id: row.installation_id })) return null;
291
- return toRepository(row);
292
- };
293
- const requireRepository = async (args) => {
294
- const repository = await getRepository(args);
295
- if (!repository) throw new Error("Source-control repository not found for this organization and integration.");
296
- return repository;
297
- };
298
- const getConnection = async (args) => {
299
- const row = await db().findOne(CONNECTIONS, { id: args.id, integration_id: integrationId });
300
- if (!row) return null;
301
- const project = await db().findOne(FACTORY_PROJECTS, {
302
- id: row.factory_project_id,
303
- org_id: args.orgId
304
- });
305
- if (!project || !await getInstallation({ orgId: args.orgId, id: row.installation_id })) return null;
306
- return toConnection(row);
307
- };
308
- const requireConnection = async (args) => {
309
- const connection = await getConnection(args);
310
- if (!connection)
311
- throw new Error("Project source-control connection not found for this organization and integration.");
312
- return connection;
313
- };
314
- const getProjectRepository = async (args) => {
315
- const row = await db().findOne(PROJECT_REPOSITORIES, { id: args.id });
316
- if (!row || !await getConnection({ orgId: args.orgId, id: row.connection_id })) return null;
317
- return toProjectRepository(row);
318
- };
319
- const getProjectRepositoryById = async (id) => {
320
- const row = await db().findOne(PROJECT_REPOSITORIES, { id });
321
- if (!row) return null;
322
- const connection = await db().findOne(CONNECTIONS, {
323
- id: row.connection_id,
324
- integration_id: integrationId
325
- });
326
- return connection ? toProjectRepository(row) : null;
327
- };
328
- const requireProjectRepositoryById = async (id) => {
329
- const projectRepository = await getProjectRepositoryById(id);
330
- if (!projectRepository) throw new Error("Project repository not found for this integration.");
331
- return projectRepository;
332
- };
333
- const getSandbox = async (id) => {
334
- const row = await db().findOne(SANDBOXES, { id });
335
- if (!row || !await getProjectRepositoryById(row.project_repository_id)) return null;
336
- return toSandbox(row);
337
- };
338
- const requireSandbox = async (id) => {
339
- const sandbox = await getSandbox(id);
340
- if (!sandbox) throw new Error("Project-repository sandbox not found for this integration.");
341
- return sandbox;
342
- };
343
- return {
344
- integrationId,
345
- installations: {
346
- list: async ({ orgId }) => (await db().findMany(INSTALLATIONS, {
347
- integration_id: integrationId,
348
- org_id: orgId
349
- })).map(toInstallation),
350
- get: getInstallation,
351
- findByExternalId: async ({ orgId, externalId }) => {
352
- const row = await db().findOne(INSTALLATIONS, {
353
- integration_id: integrationId,
354
- org_id: orgId,
355
- external_id: externalId
356
- });
357
- return row ? toInstallation(row) : null;
358
- },
359
- upsert: async (input) => {
360
- const row = await db().upsertOne(
361
- INSTALLATIONS,
362
- ["integration_id", "org_id", "external_id"],
363
- {
364
- integration_id: integrationId,
365
- org_id: input.orgId,
366
- connected_by_user_id: input.connectedByUserId,
367
- external_id: input.externalId,
368
- account_name: input.accountName ?? null,
369
- account_type: input.accountType ?? null,
370
- provider_metadata: input.providerMetadata ?? {},
371
- created_at: /* @__PURE__ */ new Date()
372
- }
373
- );
374
- return toInstallation(row);
375
- },
376
- delete: async ({ orgId, id }) => {
377
- const installation = await getInstallation({ orgId, id });
378
- if (!installation) return false;
379
- await db().deleteMany(INSTALLATIONS, { id, integration_id: integrationId, org_id: orgId });
380
- return true;
381
- }
382
- },
383
- repositories: {
384
- list: async ({ orgId, installationId }) => {
385
- await requireInstallation({ orgId, id: installationId });
386
- return (await db().findMany(REPOSITORIES, { installation_id: installationId })).map(
387
- toRepository
388
- );
389
- },
390
- get: getRepository,
391
- findByExternalId: async ({ orgId, externalId }) => {
392
- const rows = await db().findMany(REPOSITORIES, { external_id: externalId });
393
- for (const row of rows) {
394
- if (await getInstallation({ orgId, id: row.installation_id })) return toRepository(row);
395
- }
396
- return null;
397
- },
398
- findBySlug: async ({ orgId, installationId, slug }) => {
399
- await requireInstallation({ orgId, id: installationId });
400
- const row = await db().findOne(REPOSITORIES, { installation_id: installationId, slug });
401
- return row ? toRepository(row) : null;
402
- },
403
- upsert: async ({ orgId, input }) => {
404
- await requireInstallation({ orgId, id: input.installationId });
405
- const now = /* @__PURE__ */ new Date();
406
- const row = await db().upsertOne(REPOSITORIES, ["installation_id", "external_id"], {
407
- installation_id: input.installationId,
408
- external_id: input.externalId,
409
- slug: input.slug,
410
- default_branch: input.defaultBranch,
411
- provider_metadata: input.providerMetadata ?? {},
412
- created_at: now,
413
- updated_at: now
414
- });
415
- return toRepository(row);
416
- }
417
- },
418
- connections: {
419
- list: async ({ orgId, factoryProjectId }) => {
420
- const project = await db().findOne(FACTORY_PROJECTS, {
421
- id: factoryProjectId,
422
- org_id: orgId
423
- });
424
- if (!project) return [];
425
- return (await db().findMany(CONNECTIONS, {
426
- factory_project_id: factoryProjectId,
427
- integration_id: integrationId
428
- })).map(toConnection);
429
- },
430
- get: getConnection,
431
- create: async (input) => {
432
- const project = await db().findOne(FACTORY_PROJECTS, {
433
- id: input.factoryProjectId,
434
- org_id: input.orgId
435
- });
436
- if (!project) throw new Error("Factory project not found for this organization.");
437
- await requireInstallation({ orgId: input.orgId, id: input.installationId });
438
- try {
439
- const row = await db().insertOne(CONNECTIONS, {
440
- factory_project_id: input.factoryProjectId,
441
- integration_id: integrationId,
442
- installation_id: input.installationId,
443
- created_by_user_id: input.createdByUserId,
444
- created_at: /* @__PURE__ */ new Date()
445
- });
446
- return toConnection(row);
447
- } catch (error) {
448
- if (!(error instanceof UniqueViolationError)) throw error;
449
- const row = await db().findOne(CONNECTIONS, {
450
- factory_project_id: input.factoryProjectId,
451
- integration_id: integrationId,
452
- installation_id: input.installationId
453
- });
454
- if (!row) throw error;
455
- return toConnection(row);
456
- }
457
- },
458
- delete: async ({ orgId, id }) => {
459
- const connection = await getConnection({ orgId, id });
460
- if (!connection) return false;
461
- const projectRepositories = await db().findMany(PROJECT_REPOSITORIES, {
462
- connection_id: id
463
- });
464
- for (const projectRepository of projectRepositories) {
465
- await db().deleteMany(SESSIONS, { project_repository_id: projectRepository.id });
466
- await db().deleteMany(WORKTREES, { project_repository_id: projectRepository.id });
467
- await db().deleteMany(SANDBOXES, { project_repository_id: projectRepository.id });
468
- }
469
- await db().deleteMany(PROJECT_REPOSITORIES, { connection_id: id });
470
- await db().deleteMany(CONNECTIONS, { id, integration_id: integrationId });
471
- return true;
472
- }
473
- },
474
- projectRepositories: {
475
- list: async ({ orgId, connectionId }) => {
476
- await requireConnection({ orgId, id: connectionId });
477
- return (await db().findMany(PROJECT_REPOSITORIES, { connection_id: connectionId })).map(toProjectRepository);
478
- },
479
- listByExternalRepository: async ({ installationExternalId, repositoryExternalId }) => {
480
- const targets = [];
481
- const installations = await db().findMany(INSTALLATIONS, {
482
- integration_id: integrationId,
483
- external_id: installationExternalId
484
- });
485
- for (const installation of installations) {
486
- const repository = await db().findOne(REPOSITORIES, {
487
- installation_id: installation.id,
488
- external_id: repositoryExternalId
489
- });
490
- if (!repository) continue;
491
- const links = await db().findMany(PROJECT_REPOSITORIES, {
492
- repository_id: repository.id
493
- });
494
- for (const link of links) {
495
- const connection = await db().findOne(CONNECTIONS, {
496
- id: link.connection_id,
497
- integration_id: integrationId,
498
- installation_id: installation.id
499
- });
500
- if (!connection) continue;
501
- const project = await db().findOne(FACTORY_PROJECTS, {
502
- id: connection.factory_project_id,
503
- org_id: installation.org_id
504
- });
505
- if (!project) continue;
506
- targets.push({
507
- orgId: installation.org_id,
508
- factoryProjectId: connection.factory_project_id,
509
- projectRepository: toProjectRepository(link)
510
- });
511
- }
512
- }
513
- return targets;
514
- },
515
- get: getProjectRepository,
516
- link: async (input) => {
517
- const connection = await requireConnection({ orgId: input.orgId, id: input.connectionId });
518
- const repository = await requireRepository({ orgId: input.orgId, id: input.repositoryId });
519
- if (repository.installationId !== connection.installationId) {
520
- throw new Error("Repository does not belong to the connection installation.");
521
- }
522
- const now = /* @__PURE__ */ new Date();
523
- const row = await db().upsertOne(
524
- PROJECT_REPOSITORIES,
525
- ["connection_id", "repository_id"],
526
- {
527
- connection_id: input.connectionId,
528
- repository_id: input.repositoryId,
529
- created_by_user_id: input.createdByUserId,
530
- branch: input.branch ?? null,
531
- sandbox_provider: input.sandboxProvider,
532
- sandbox_workdir: input.sandboxWorkdir,
533
- setup_command: input.setupCommand ?? null,
534
- created_at: now,
535
- updated_at: now
536
- }
537
- );
538
- return toProjectRepository(row);
539
- },
540
- update: async ({ orgId, id, input }) => {
541
- const existing = await getProjectRepository({ orgId, id });
542
- if (!existing) return null;
543
- const patch = { updated_at: /* @__PURE__ */ new Date() };
544
- if (input.branch !== void 0) patch.branch = input.branch;
545
- if (input.sandboxProvider !== void 0) patch.sandbox_provider = input.sandboxProvider;
546
- if (input.sandboxWorkdir !== void 0) patch.sandbox_workdir = input.sandboxWorkdir;
547
- if (input.setupCommand !== void 0) patch.setup_command = input.setupCommand;
548
- await db().updateMany(PROJECT_REPOSITORIES, { id }, patch);
549
- return getProjectRepository({ orgId, id });
550
- },
551
- unlink: async ({ orgId, id }) => {
552
- const existing = await getProjectRepository({ orgId, id });
553
- if (!existing) return false;
554
- await db().deleteMany(SESSIONS, { project_repository_id: id });
555
- await db().deleteMany(WORKTREES, { project_repository_id: id });
556
- await db().deleteMany(SANDBOXES, { project_repository_id: id });
557
- await db().deleteMany(PROJECT_REPOSITORIES, { id });
558
- return true;
559
- }
560
- },
561
- sandboxes: {
562
- getOrCreate: async ({ projectRepository, userId }) => {
563
- await requireProjectRepositoryById(projectRepository.id);
564
- const where = { project_repository_id: projectRepository.id, user_id: userId };
565
- const existing = await db().findOne(SANDBOXES, where);
566
- if (existing) return toSandbox(existing);
567
- try {
568
- const row = await db().insertOne(SANDBOXES, {
569
- ...where,
570
- sandbox_id: null,
571
- sandbox_workdir: projectRepository.sandboxWorkdir,
572
- materialized_at: null,
573
- created_at: /* @__PURE__ */ new Date()
574
- });
575
- return toSandbox(row);
576
- } catch (error) {
577
- if (!(error instanceof UniqueViolationError)) throw error;
578
- const row = await db().findOne(SANDBOXES, where);
579
- if (!row) throw error;
580
- return toSandbox(row);
581
- }
582
- },
583
- getById: ({ id }) => getSandbox(id),
584
- setSandboxId: async ({ id, sandboxId }) => {
585
- await requireSandbox(id);
586
- await db().updateMany(SANDBOXES, { id }, { sandbox_id: sandboxId });
587
- },
588
- clearBinding: async ({ id }) => {
589
- await requireSandbox(id);
590
- await db().updateMany(SANDBOXES, { id }, { sandbox_id: null, materialized_at: null });
591
- },
592
- markMaterialized: async ({ id }) => {
593
- await requireSandbox(id);
594
- await db().updateMany(SANDBOXES, { id }, { materialized_at: /* @__PURE__ */ new Date() });
595
- }
596
- },
597
- worktrees: {
598
- upsert: async (input) => {
599
- await requireProjectRepositoryById(input.projectRepositoryId);
600
- await db().upsertOne(WORKTREES, ["project_repository_id", "user_id", "branch"], {
601
- project_repository_id: input.projectRepositoryId,
602
- user_id: input.userId,
603
- branch: input.branch,
604
- base_branch: input.baseBranch,
605
- worktree_path: input.worktreePath,
606
- created_at: /* @__PURE__ */ new Date()
607
- });
608
- },
609
- list: async ({ projectRepositoryId, userId }) => {
610
- if (!await getProjectRepositoryById(projectRepositoryId)) return [];
611
- const rows = await db().findMany(WORKTREES, {
612
- project_repository_id: projectRepositoryId,
613
- user_id: userId
614
- });
615
- return rows.map(toWorktree);
616
- },
617
- get: async ({ projectRepositoryId, userId, branch }) => {
618
- if (!await getProjectRepositoryById(projectRepositoryId)) return null;
619
- const row = await db().findOne(WORKTREES, {
620
- project_repository_id: projectRepositoryId,
621
- user_id: userId,
622
- branch
623
- });
624
- return row ? toWorktree(row) : null;
625
- },
626
- findByPath: async ({ projectRepositoryId, userId, worktreePath }) => {
627
- if (!await getProjectRepositoryById(projectRepositoryId)) return null;
628
- const row = await db().findOne(WORKTREES, {
629
- project_repository_id: projectRepositoryId,
630
- user_id: userId,
631
- worktree_path: worktreePath
632
- });
633
- return row ? toWorktree(row) : null;
634
- },
635
- delete: async ({ projectRepositoryId, userId, branch }) => {
636
- await requireProjectRepositoryById(projectRepositoryId);
637
- await db().deleteMany(WORKTREES, {
638
- project_repository_id: projectRepositoryId,
639
- user_id: userId,
640
- branch
641
- });
642
- }
643
- },
644
- sessions: {
645
- list: async ({ projectRepositoryId, userId }) => {
646
- if (!await getProjectRepositoryById(projectRepositoryId)) return [];
647
- return (await db().findMany(SESSIONS, {
648
- project_repository_id: projectRepositoryId,
649
- user_id: userId
650
- })).map(toSession);
651
- },
652
- getBySessionId: async (sessionId) => {
653
- const row = await db().findOne(SESSIONS, { session_id: sessionId });
654
- return row && await getProjectRepositoryById(row.project_repository_id) ? toSession(row) : null;
655
- },
656
- getForBranch: async ({ projectRepositoryId, userId, branch }) => {
657
- if (!await getProjectRepositoryById(projectRepositoryId)) return null;
658
- const row = await db().findOne(SESSIONS, {
659
- project_repository_id: projectRepositoryId,
660
- user_id: userId,
661
- branch
662
- });
663
- return row ? toSession(row) : null;
664
- },
665
- create: async (input) => {
666
- await requireProjectRepositoryById(input.projectRepositoryId);
667
- const existing = await db().findOne(SESSIONS, {
668
- project_repository_id: input.projectRepositoryId,
669
- user_id: input.userId,
670
- branch: input.branch
671
- });
672
- if (existing) return toSession(existing);
673
- const now = /* @__PURE__ */ new Date();
674
- try {
675
- const row = await db().insertOne(SESSIONS, {
676
- session_id: input.sessionId,
677
- project_repository_id: input.projectRepositoryId,
678
- org_id: input.orgId,
679
- user_id: input.userId,
680
- branch: input.branch,
681
- base_branch: input.baseBranch,
682
- sandbox_id: null,
683
- sandbox_workdir: null,
684
- materialized_at: null,
685
- created_at: now,
686
- updated_at: now
687
- });
688
- return toSession(row);
689
- } catch (error) {
690
- if (!(error instanceof UniqueViolationError)) throw error;
691
- const row = await db().findOne(SESSIONS, {
692
- project_repository_id: input.projectRepositoryId,
693
- user_id: input.userId,
694
- branch: input.branch
695
- });
696
- if (!row) throw error;
697
- return toSession(row);
698
- }
699
- },
700
- setSandbox: async ({ id, sandboxId, sandboxWorkdir }) => {
701
- await db().updateMany(
702
- SESSIONS,
703
- { id },
704
- { sandbox_id: sandboxId, sandbox_workdir: sandboxWorkdir, updated_at: /* @__PURE__ */ new Date() }
705
- );
706
- },
707
- markMaterialized: async ({ id }) => {
708
- await db().updateMany(SESSIONS, { id }, { materialized_at: /* @__PURE__ */ new Date(), updated_at: /* @__PURE__ */ new Date() });
709
- },
710
- delete: async (id) => {
711
- await db().deleteMany(SESSIONS, { id });
712
- }
713
- }
714
- };
715
- }
716
- };
717
- export {
718
- SOURCE_CONTROL_SCHEMAS,
719
- SourceControlStorage
284
+ constructor() {
285
+ super("source-control");
286
+ }
287
+ async init() {
288
+ await this.ensureCollections(SOURCE_CONTROL_SCHEMAS);
289
+ }
290
+ async dangerouslyClearAll() {
291
+ await this.ops.deleteMany(SESSIONS, {});
292
+ await this.ops.deleteMany(WORKTREES, {});
293
+ await this.ops.deleteMany(SANDBOXES, {});
294
+ await this.ops.deleteMany(PROJECT_REPOSITORIES, {});
295
+ await this.ops.deleteMany(CONNECTIONS, {});
296
+ await this.ops.deleteMany(REPOSITORIES, {});
297
+ await this.ops.deleteMany(INSTALLATIONS, {});
298
+ }
299
+ forIntegration(integrationId) {
300
+ if (!integrationId.trim()) throw new Error("[SourceControlStorage] integrationId must not be empty.");
301
+ const db = () => this.ops;
302
+ const getInstallation = async (args) => {
303
+ const row = await db().findOne(INSTALLATIONS, {
304
+ id: args.id,
305
+ integration_id: integrationId,
306
+ org_id: args.orgId
307
+ });
308
+ return row ? toInstallation(row) : null;
309
+ };
310
+ const requireInstallation = async (args) => {
311
+ const installation = await getInstallation(args);
312
+ if (!installation) throw new Error("Source-control installation not found for this organization and integration.");
313
+ return installation;
314
+ };
315
+ const getRepository = async (args) => {
316
+ const row = await db().findOne(REPOSITORIES, { id: args.id });
317
+ if (!row || !await getInstallation({
318
+ orgId: args.orgId,
319
+ id: row.installation_id
320
+ })) return null;
321
+ return toRepository(row);
322
+ };
323
+ const requireRepository = async (args) => {
324
+ const repository = await getRepository(args);
325
+ if (!repository) throw new Error("Source-control repository not found for this organization and integration.");
326
+ return repository;
327
+ };
328
+ const getConnection = async (args) => {
329
+ const row = await db().findOne(CONNECTIONS, {
330
+ id: args.id,
331
+ integration_id: integrationId
332
+ });
333
+ if (!row) return null;
334
+ if (!await db().findOne(FACTORY_PROJECTS, {
335
+ id: row.factory_project_id,
336
+ org_id: args.orgId
337
+ }) || !await getInstallation({
338
+ orgId: args.orgId,
339
+ id: row.installation_id
340
+ })) return null;
341
+ return toConnection(row);
342
+ };
343
+ const requireConnection = async (args) => {
344
+ const connection = await getConnection(args);
345
+ if (!connection) throw new Error("Project source-control connection not found for this organization and integration.");
346
+ return connection;
347
+ };
348
+ const getProjectRepository = async (args) => {
349
+ const row = await db().findOne(PROJECT_REPOSITORIES, { id: args.id });
350
+ if (!row || !await getConnection({
351
+ orgId: args.orgId,
352
+ id: row.connection_id
353
+ })) return null;
354
+ return toProjectRepository(row);
355
+ };
356
+ const getProjectRepositoryById = async (id) => {
357
+ const row = await db().findOne(PROJECT_REPOSITORIES, { id });
358
+ if (!row) return null;
359
+ return await db().findOne(CONNECTIONS, {
360
+ id: row.connection_id,
361
+ integration_id: integrationId
362
+ }) ? toProjectRepository(row) : null;
363
+ };
364
+ const requireProjectRepositoryById = async (id) => {
365
+ const projectRepository = await getProjectRepositoryById(id);
366
+ if (!projectRepository) throw new Error("Project repository not found for this integration.");
367
+ return projectRepository;
368
+ };
369
+ const getSandbox = async (id) => {
370
+ const row = await db().findOne(SANDBOXES, { id });
371
+ if (!row || !await getProjectRepositoryById(row.project_repository_id)) return null;
372
+ return toSandbox(row);
373
+ };
374
+ const requireSandbox = async (id) => {
375
+ const sandbox = await getSandbox(id);
376
+ if (!sandbox) throw new Error("Project-repository sandbox not found for this integration.");
377
+ return sandbox;
378
+ };
379
+ return {
380
+ integrationId,
381
+ installations: {
382
+ list: async ({ orgId }) => (await db().findMany(INSTALLATIONS, {
383
+ integration_id: integrationId,
384
+ org_id: orgId
385
+ })).map(toInstallation),
386
+ get: getInstallation,
387
+ findByExternalId: async ({ orgId, externalId }) => {
388
+ const row = await db().findOne(INSTALLATIONS, {
389
+ integration_id: integrationId,
390
+ org_id: orgId,
391
+ external_id: externalId
392
+ });
393
+ return row ? toInstallation(row) : null;
394
+ },
395
+ upsert: async (input) => {
396
+ return toInstallation(await db().upsertOne(INSTALLATIONS, [
397
+ "integration_id",
398
+ "org_id",
399
+ "external_id"
400
+ ], {
401
+ integration_id: integrationId,
402
+ org_id: input.orgId,
403
+ connected_by_user_id: input.connectedByUserId,
404
+ external_id: input.externalId,
405
+ account_name: input.accountName ?? null,
406
+ account_type: input.accountType ?? null,
407
+ provider_metadata: input.providerMetadata ?? {},
408
+ created_at: /* @__PURE__ */ new Date()
409
+ }));
410
+ },
411
+ delete: async ({ orgId, id }) => {
412
+ if (!await getInstallation({
413
+ orgId,
414
+ id
415
+ })) return false;
416
+ await db().deleteMany(INSTALLATIONS, {
417
+ id,
418
+ integration_id: integrationId,
419
+ org_id: orgId
420
+ });
421
+ return true;
422
+ }
423
+ },
424
+ repositories: {
425
+ list: async ({ orgId, installationId }) => {
426
+ await requireInstallation({
427
+ orgId,
428
+ id: installationId
429
+ });
430
+ return (await db().findMany(REPOSITORIES, { installation_id: installationId })).map(toRepository);
431
+ },
432
+ get: getRepository,
433
+ findByExternalId: async ({ orgId, externalId }) => {
434
+ const rows = await db().findMany(REPOSITORIES, { external_id: externalId });
435
+ for (const row of rows) if (await getInstallation({
436
+ orgId,
437
+ id: row.installation_id
438
+ })) return toRepository(row);
439
+ return null;
440
+ },
441
+ findBySlug: async ({ orgId, installationId, slug }) => {
442
+ await requireInstallation({
443
+ orgId,
444
+ id: installationId
445
+ });
446
+ const row = await db().findOne(REPOSITORIES, {
447
+ installation_id: installationId,
448
+ slug
449
+ });
450
+ return row ? toRepository(row) : null;
451
+ },
452
+ upsert: async ({ orgId, input }) => {
453
+ await requireInstallation({
454
+ orgId,
455
+ id: input.installationId
456
+ });
457
+ const now = /* @__PURE__ */ new Date();
458
+ return toRepository(await db().upsertOne(REPOSITORIES, ["installation_id", "external_id"], {
459
+ installation_id: input.installationId,
460
+ external_id: input.externalId,
461
+ slug: input.slug,
462
+ default_branch: input.defaultBranch,
463
+ provider_metadata: input.providerMetadata ?? {},
464
+ created_at: now,
465
+ updated_at: now
466
+ }));
467
+ }
468
+ },
469
+ connections: {
470
+ list: async ({ orgId, factoryProjectId }) => {
471
+ if (!await db().findOne(FACTORY_PROJECTS, {
472
+ id: factoryProjectId,
473
+ org_id: orgId
474
+ })) return [];
475
+ return (await db().findMany(CONNECTIONS, {
476
+ factory_project_id: factoryProjectId,
477
+ integration_id: integrationId
478
+ })).map(toConnection);
479
+ },
480
+ get: getConnection,
481
+ create: async (input) => {
482
+ if (!await db().findOne(FACTORY_PROJECTS, {
483
+ id: input.factoryProjectId,
484
+ org_id: input.orgId
485
+ })) throw new Error("Factory project not found for this organization.");
486
+ await requireInstallation({
487
+ orgId: input.orgId,
488
+ id: input.installationId
489
+ });
490
+ try {
491
+ return toConnection(await db().insertOne(CONNECTIONS, {
492
+ factory_project_id: input.factoryProjectId,
493
+ integration_id: integrationId,
494
+ installation_id: input.installationId,
495
+ created_by_user_id: input.createdByUserId,
496
+ created_at: /* @__PURE__ */ new Date()
497
+ }));
498
+ } catch (error) {
499
+ if (!(error instanceof UniqueViolationError)) throw error;
500
+ const row = await db().findOne(CONNECTIONS, {
501
+ factory_project_id: input.factoryProjectId,
502
+ integration_id: integrationId,
503
+ installation_id: input.installationId
504
+ });
505
+ if (!row) throw error;
506
+ return toConnection(row);
507
+ }
508
+ },
509
+ delete: async ({ orgId, id }) => {
510
+ if (!await getConnection({
511
+ orgId,
512
+ id
513
+ })) return false;
514
+ const projectRepositories = await db().findMany(PROJECT_REPOSITORIES, { connection_id: id });
515
+ for (const projectRepository of projectRepositories) {
516
+ await db().deleteMany(SESSIONS, { project_repository_id: projectRepository.id });
517
+ await db().deleteMany(WORKTREES, { project_repository_id: projectRepository.id });
518
+ await db().deleteMany(SANDBOXES, { project_repository_id: projectRepository.id });
519
+ }
520
+ await db().deleteMany(PROJECT_REPOSITORIES, { connection_id: id });
521
+ await db().deleteMany(CONNECTIONS, {
522
+ id,
523
+ integration_id: integrationId
524
+ });
525
+ return true;
526
+ }
527
+ },
528
+ projectRepositories: {
529
+ list: async ({ orgId, connectionId }) => {
530
+ await requireConnection({
531
+ orgId,
532
+ id: connectionId
533
+ });
534
+ return (await db().findMany(PROJECT_REPOSITORIES, { connection_id: connectionId })).map(toProjectRepository);
535
+ },
536
+ listByExternalRepository: async ({ installationExternalId, repositoryExternalId }) => {
537
+ const targets = [];
538
+ const installations = await db().findMany(INSTALLATIONS, {
539
+ integration_id: integrationId,
540
+ external_id: installationExternalId
541
+ });
542
+ for (const installation of installations) {
543
+ const repository = await db().findOne(REPOSITORIES, {
544
+ installation_id: installation.id,
545
+ external_id: repositoryExternalId
546
+ });
547
+ if (!repository) continue;
548
+ const links = await db().findMany(PROJECT_REPOSITORIES, { repository_id: repository.id });
549
+ for (const link of links) {
550
+ const connection = await db().findOne(CONNECTIONS, {
551
+ id: link.connection_id,
552
+ integration_id: integrationId,
553
+ installation_id: installation.id
554
+ });
555
+ if (!connection) continue;
556
+ if (!await db().findOne(FACTORY_PROJECTS, {
557
+ id: connection.factory_project_id,
558
+ org_id: installation.org_id
559
+ })) continue;
560
+ targets.push({
561
+ orgId: installation.org_id,
562
+ factoryProjectId: connection.factory_project_id,
563
+ projectRepository: toProjectRepository(link)
564
+ });
565
+ }
566
+ }
567
+ return targets;
568
+ },
569
+ get: getProjectRepository,
570
+ link: async (input) => {
571
+ const connection = await requireConnection({
572
+ orgId: input.orgId,
573
+ id: input.connectionId
574
+ });
575
+ if ((await requireRepository({
576
+ orgId: input.orgId,
577
+ id: input.repositoryId
578
+ })).installationId !== connection.installationId) throw new Error("Repository does not belong to the connection installation.");
579
+ const now = /* @__PURE__ */ new Date();
580
+ return toProjectRepository(await db().upsertOne(PROJECT_REPOSITORIES, ["connection_id", "repository_id"], {
581
+ connection_id: input.connectionId,
582
+ repository_id: input.repositoryId,
583
+ created_by_user_id: input.createdByUserId,
584
+ branch: input.branch ?? null,
585
+ sandbox_provider: input.sandboxProvider,
586
+ sandbox_workdir: input.sandboxWorkdir,
587
+ setup_command: input.setupCommand ?? null,
588
+ created_at: now,
589
+ updated_at: now
590
+ }));
591
+ },
592
+ update: async ({ orgId, id, input }) => {
593
+ if (!await getProjectRepository({
594
+ orgId,
595
+ id
596
+ })) return null;
597
+ const patch = { updated_at: /* @__PURE__ */ new Date() };
598
+ if (input.branch !== void 0) patch.branch = input.branch;
599
+ if (input.sandboxProvider !== void 0) patch.sandbox_provider = input.sandboxProvider;
600
+ if (input.sandboxWorkdir !== void 0) patch.sandbox_workdir = input.sandboxWorkdir;
601
+ if (input.setupCommand !== void 0) patch.setup_command = input.setupCommand;
602
+ await db().updateMany(PROJECT_REPOSITORIES, { id }, patch);
603
+ return getProjectRepository({
604
+ orgId,
605
+ id
606
+ });
607
+ },
608
+ unlink: async ({ orgId, id }) => {
609
+ if (!await getProjectRepository({
610
+ orgId,
611
+ id
612
+ })) return false;
613
+ await db().deleteMany(SESSIONS, { project_repository_id: id });
614
+ await db().deleteMany(WORKTREES, { project_repository_id: id });
615
+ await db().deleteMany(SANDBOXES, { project_repository_id: id });
616
+ await db().deleteMany(PROJECT_REPOSITORIES, { id });
617
+ return true;
618
+ }
619
+ },
620
+ sandboxes: {
621
+ getOrCreate: async ({ projectRepository, userId }) => {
622
+ await requireProjectRepositoryById(projectRepository.id);
623
+ const where = {
624
+ project_repository_id: projectRepository.id,
625
+ user_id: userId
626
+ };
627
+ const existing = await db().findOne(SANDBOXES, where);
628
+ if (existing) return toSandbox(existing);
629
+ try {
630
+ return toSandbox(await db().insertOne(SANDBOXES, {
631
+ ...where,
632
+ sandbox_id: null,
633
+ sandbox_workdir: projectRepository.sandboxWorkdir,
634
+ materialized_at: null,
635
+ created_at: /* @__PURE__ */ new Date()
636
+ }));
637
+ } catch (error) {
638
+ if (!(error instanceof UniqueViolationError)) throw error;
639
+ const row = await db().findOne(SANDBOXES, where);
640
+ if (!row) throw error;
641
+ return toSandbox(row);
642
+ }
643
+ },
644
+ getById: ({ id }) => getSandbox(id),
645
+ setWorkdir: async ({ id, sandboxWorkdir }) => {
646
+ await requireSandbox(id);
647
+ await db().updateMany(SANDBOXES, { id }, {
648
+ sandbox_workdir: sandboxWorkdir,
649
+ materialized_at: null
650
+ });
651
+ },
652
+ setSandboxId: async ({ id, sandboxId }) => {
653
+ await requireSandbox(id);
654
+ await db().updateMany(SANDBOXES, { id }, { sandbox_id: sandboxId });
655
+ },
656
+ clearBinding: async ({ id }) => {
657
+ await requireSandbox(id);
658
+ await db().updateMany(SANDBOXES, { id }, {
659
+ sandbox_id: null,
660
+ materialized_at: null
661
+ });
662
+ },
663
+ markMaterialized: async ({ id }) => {
664
+ await requireSandbox(id);
665
+ await db().updateMany(SANDBOXES, { id }, { materialized_at: /* @__PURE__ */ new Date() });
666
+ }
667
+ },
668
+ worktrees: {
669
+ upsert: async (input) => {
670
+ await requireProjectRepositoryById(input.projectRepositoryId);
671
+ await db().upsertOne(WORKTREES, [
672
+ "project_repository_id",
673
+ "user_id",
674
+ "branch"
675
+ ], {
676
+ project_repository_id: input.projectRepositoryId,
677
+ user_id: input.userId,
678
+ branch: input.branch,
679
+ base_branch: input.baseBranch,
680
+ worktree_path: input.worktreePath,
681
+ created_at: /* @__PURE__ */ new Date()
682
+ });
683
+ },
684
+ list: async ({ projectRepositoryId, userId }) => {
685
+ if (!await getProjectRepositoryById(projectRepositoryId)) return [];
686
+ return (await db().findMany(WORKTREES, {
687
+ project_repository_id: projectRepositoryId,
688
+ user_id: userId
689
+ })).map(toWorktree);
690
+ },
691
+ get: async ({ projectRepositoryId, userId, branch }) => {
692
+ if (!await getProjectRepositoryById(projectRepositoryId)) return null;
693
+ const row = await db().findOne(WORKTREES, {
694
+ project_repository_id: projectRepositoryId,
695
+ user_id: userId,
696
+ branch
697
+ });
698
+ return row ? toWorktree(row) : null;
699
+ },
700
+ findByPath: async ({ projectRepositoryId, userId, worktreePath }) => {
701
+ if (!await getProjectRepositoryById(projectRepositoryId)) return null;
702
+ const row = await db().findOne(WORKTREES, {
703
+ project_repository_id: projectRepositoryId,
704
+ user_id: userId,
705
+ worktree_path: worktreePath
706
+ });
707
+ return row ? toWorktree(row) : null;
708
+ },
709
+ delete: async ({ projectRepositoryId, userId, branch }) => {
710
+ await requireProjectRepositoryById(projectRepositoryId);
711
+ await db().deleteMany(WORKTREES, {
712
+ project_repository_id: projectRepositoryId,
713
+ user_id: userId,
714
+ branch
715
+ });
716
+ }
717
+ },
718
+ sessions: {
719
+ list: async ({ projectRepositoryId, userId }) => {
720
+ if (!await getProjectRepositoryById(projectRepositoryId)) return [];
721
+ return (await db().findMany(SESSIONS, {
722
+ project_repository_id: projectRepositoryId,
723
+ user_id: userId
724
+ })).map(toSession);
725
+ },
726
+ getBySessionId: async (sessionId) => {
727
+ const row = await db().findOne(SESSIONS, { session_id: sessionId });
728
+ return row && await getProjectRepositoryById(row.project_repository_id) ? toSession(row) : null;
729
+ },
730
+ getForBranch: async ({ projectRepositoryId, userId, branch }) => {
731
+ if (!await getProjectRepositoryById(projectRepositoryId)) return null;
732
+ const row = await db().findOne(SESSIONS, {
733
+ project_repository_id: projectRepositoryId,
734
+ user_id: userId,
735
+ branch
736
+ });
737
+ return row ? toSession(row) : null;
738
+ },
739
+ create: async (input) => {
740
+ await requireProjectRepositoryById(input.projectRepositoryId);
741
+ const existing = await db().findOne(SESSIONS, {
742
+ project_repository_id: input.projectRepositoryId,
743
+ user_id: input.userId,
744
+ branch: input.branch
745
+ });
746
+ if (existing) return toSession(existing);
747
+ const now = /* @__PURE__ */ new Date();
748
+ try {
749
+ return toSession(await db().insertOne(SESSIONS, {
750
+ session_id: input.sessionId,
751
+ project_repository_id: input.projectRepositoryId,
752
+ org_id: input.orgId,
753
+ user_id: input.userId,
754
+ branch: input.branch,
755
+ base_branch: input.baseBranch,
756
+ sandbox_id: null,
757
+ sandbox_workdir: null,
758
+ materialized_at: null,
759
+ created_at: now,
760
+ updated_at: now
761
+ }));
762
+ } catch (error) {
763
+ if (!(error instanceof UniqueViolationError)) throw error;
764
+ const row = await db().findOne(SESSIONS, {
765
+ project_repository_id: input.projectRepositoryId,
766
+ user_id: input.userId,
767
+ branch: input.branch
768
+ });
769
+ if (!row) throw error;
770
+ return toSession(row);
771
+ }
772
+ },
773
+ setSandbox: async ({ id, sandboxId, sandboxWorkdir }) => {
774
+ await db().updateMany(SESSIONS, { id }, {
775
+ sandbox_id: sandboxId,
776
+ sandbox_workdir: sandboxWorkdir,
777
+ updated_at: /* @__PURE__ */ new Date()
778
+ });
779
+ },
780
+ markMaterialized: async ({ id }) => {
781
+ await db().updateMany(SESSIONS, { id }, {
782
+ materialized_at: /* @__PURE__ */ new Date(),
783
+ updated_at: /* @__PURE__ */ new Date()
784
+ });
785
+ },
786
+ delete: async (id) => {
787
+ await db().deleteMany(SESSIONS, { id });
788
+ }
789
+ }
790
+ };
791
+ }
720
792
  };
793
+ //#endregion
794
+ export { SOURCE_CONTROL_SCHEMAS, SourceControlStorage };
795
+
721
796
  //# sourceMappingURL=base.js.map