@mastra/factory 0.2.2-alpha.1 → 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 (155) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/auth.js +401 -334
  3. package/dist/auth.js.map +1 -1
  4. package/dist/capabilities/connection.js +1 -1
  5. package/dist/capabilities/intake.js +1 -1
  6. package/dist/capabilities/version-control.js +1 -1
  7. package/dist/factory.js +441 -39622
  8. package/dist/factory.js.map +1 -1
  9. package/dist/index.js +2 -39633
  10. package/dist/integrations/base.js +1 -1
  11. package/dist/integrations/github/config.js +36 -22
  12. package/dist/integrations/github/config.js.map +1 -1
  13. package/dist/integrations/github/factory-session.js +33 -37
  14. package/dist/integrations/github/factory-session.js.map +1 -1
  15. package/dist/integrations/github/integration.js +1037 -3672
  16. package/dist/integrations/github/integration.js.map +1 -1
  17. package/dist/integrations/github/issue-triage.js +71 -71
  18. package/dist/integrations/github/issue-triage.js.map +1 -1
  19. package/dist/integrations/github/pat.js +47 -36
  20. package/dist/integrations/github/pat.js.map +1 -1
  21. package/dist/integrations/github/provenance.js +72 -101
  22. package/dist/integrations/github/provenance.js.map +1 -1
  23. package/dist/integrations/github/routes.js +1272 -1881
  24. package/dist/integrations/github/routes.js.map +1 -1
  25. package/dist/integrations/github/rules.js +203 -471
  26. package/dist/integrations/github/rules.js.map +1 -1
  27. package/dist/integrations/github/sandbox.js +400 -345
  28. package/dist/integrations/github/sandbox.js.map +1 -1
  29. package/dist/integrations/github/session-subscriptions.js +165 -223
  30. package/dist/integrations/github/session-subscriptions.js.map +1 -1
  31. package/dist/integrations/github/subscriptions.js +43 -51
  32. package/dist/integrations/github/subscriptions.js.map +1 -1
  33. package/dist/integrations/github/token-refresh.js +15 -18
  34. package/dist/integrations/github/token-refresh.js.map +1 -1
  35. package/dist/integrations/github/webhook.js +359 -343
  36. package/dist/integrations/github/webhook.js.map +1 -1
  37. package/dist/integrations/linear/agent-tools.js +77 -100
  38. package/dist/integrations/linear/agent-tools.js.map +1 -1
  39. package/dist/integrations/linear/integration.js +611 -1309
  40. package/dist/integrations/linear/integration.js.map +1 -1
  41. package/dist/integrations/linear/routes.js +227 -230
  42. package/dist/integrations/linear/routes.js.map +1 -1
  43. package/dist/integrations/linear/rules.js +126 -346
  44. package/dist/integrations/linear/rules.js.map +1 -1
  45. package/dist/integrations/linear/storage.js +1 -1
  46. package/dist/integrations/platform/api-client.js +131 -135
  47. package/dist/integrations/platform/api-client.js.map +1 -1
  48. package/dist/integrations/platform/github/event-worker.js +275 -573
  49. package/dist/integrations/platform/github/event-worker.js.map +1 -1
  50. package/dist/integrations/platform/github/integration.js +845 -4022
  51. package/dist/integrations/platform/github/integration.js.map +1 -1
  52. package/dist/integrations/platform/linear/integration.js +457 -1309
  53. package/dist/integrations/platform/linear/integration.js.map +1 -1
  54. package/dist/integrations/workos/integration.js +80 -85
  55. package/dist/integrations/workos/integration.js.map +1 -1
  56. package/dist/routes/config.d.ts.map +1 -1
  57. package/dist/routes/config.js +933 -912
  58. package/dist/routes/config.js.map +1 -1
  59. package/dist/routes/custom-provider-source.js +110 -93
  60. package/dist/routes/custom-provider-source.js.map +1 -1
  61. package/dist/routes/fs.js +401 -349
  62. package/dist/routes/fs.js.map +1 -1
  63. package/dist/routes/intake.js +165 -165
  64. package/dist/routes/intake.js.map +1 -1
  65. package/dist/routes/oauth.js +447 -25166
  66. package/dist/routes/oauth.js.map +1 -1
  67. package/dist/routes/projects.js +437 -376
  68. package/dist/routes/projects.js.map +1 -1
  69. package/dist/routes/provider-credentials.js +76 -58
  70. package/dist/routes/provider-credentials.js.map +1 -1
  71. package/dist/routes/route.js +12 -8
  72. package/dist/routes/route.js.map +1 -1
  73. package/dist/routes/skills.js +160 -173
  74. package/dist/routes/skills.js.map +1 -1
  75. package/dist/routes/surface.js +250 -28615
  76. package/dist/routes/surface.js.map +1 -1
  77. package/dist/routes/tenant-credentials.js +141 -166
  78. package/dist/routes/tenant-credentials.js.map +1 -1
  79. package/dist/routes/work-items.js +654 -862
  80. package/dist/routes/work-items.js.map +1 -1
  81. package/dist/rules/binding-context.js +23 -35
  82. package/dist/rules/binding-context.js.map +1 -1
  83. package/dist/rules/defaults.js +200 -309
  84. package/dist/rules/defaults.js.map +1 -1
  85. package/dist/rules/dispatcher.js +438 -683
  86. package/dist/rules/dispatcher.js.map +1 -1
  87. package/dist/rules/index.js +5 -599
  88. package/dist/rules/processor.js +344 -596
  89. package/dist/rules/processor.js.map +1 -1
  90. package/dist/rules/resolve.js +21 -18
  91. package/dist/rules/resolve.js.map +1 -1
  92. package/dist/rules/start-coordinator.js +168 -157
  93. package/dist/rules/start-coordinator.js.map +1 -1
  94. package/dist/rules/tools.js +50 -85
  95. package/dist/rules/tools.js.map +1 -1
  96. package/dist/rules/transition-service.js +183 -454
  97. package/dist/rules/transition-service.js.map +1 -1
  98. package/dist/rules/types.js +33 -29
  99. package/dist/rules/types.js.map +1 -1
  100. package/dist/rules/validation.js +266 -281
  101. package/dist/rules/validation.js.map +1 -1
  102. package/dist/sandbox/fleet.js +272 -250
  103. package/dist/sandbox/fleet.js.map +1 -1
  104. package/dist/sandbox/reattach.js +13 -6
  105. package/dist/sandbox/reattach.js.map +1 -1
  106. package/dist/server-error.js +12 -16
  107. package/dist/server-error.js.map +1 -1
  108. package/dist/skills/service.js +30 -35
  109. package/dist/skills/service.js.map +1 -1
  110. package/dist/spa-static.js +91 -65
  111. package/dist/spa-static.js.map +1 -1
  112. package/dist/state-signing.js +73 -44
  113. package/dist/state-signing.js.map +1 -1
  114. package/dist/storage/domains/audit/agent-audit.js +60 -59
  115. package/dist/storage/domains/audit/agent-audit.js.map +1 -1
  116. package/dist/storage/domains/audit/base.js +169 -112
  117. package/dist/storage/domains/audit/base.js.map +1 -1
  118. package/dist/storage/domains/audit/domain.js +155 -153
  119. package/dist/storage/domains/audit/domain.js.map +1 -1
  120. package/dist/storage/domains/credentials/base.js +259 -243
  121. package/dist/storage/domains/credentials/base.js.map +1 -1
  122. package/dist/storage/domains/custom-providers/base.js +138 -143
  123. package/dist/storage/domains/custom-providers/base.js.map +1 -1
  124. package/dist/storage/domains/intake/base.js +75 -57
  125. package/dist/storage/domains/intake/base.js.map +1 -1
  126. package/dist/storage/domains/integrations/base.js +310 -245
  127. package/dist/storage/domains/integrations/base.js.map +1 -1
  128. package/dist/storage/domains/memory-settings/base.js +117 -102
  129. package/dist/storage/domains/memory-settings/base.js.map +1 -1
  130. package/dist/storage/domains/model-packs/base.js +89 -88
  131. package/dist/storage/domains/model-packs/base.js.map +1 -1
  132. package/dist/storage/domains/projects/base.js +97 -92
  133. package/dist/storage/domains/projects/base.js.map +1 -1
  134. package/dist/storage/domains/queue-health/base.js +111 -76
  135. package/dist/storage/domains/queue-health/base.js.map +1 -1
  136. package/dist/storage/domains/source-control/base.js +777 -706
  137. package/dist/storage/domains/source-control/base.js.map +1 -1
  138. package/dist/storage/domains/source-control/inmemory.js +322 -348
  139. package/dist/storage/domains/source-control/inmemory.js.map +1 -1
  140. package/dist/storage/domains/work-items/base.js +1266 -1148
  141. package/dist/storage/domains/work-items/base.js.map +1 -1
  142. package/dist/storage/domains/work-items/metrics.js +202 -184
  143. package/dist/storage/domains/work-items/metrics.js.map +1 -1
  144. package/dist/timing.js +29 -22
  145. package/dist/timing.js.map +1 -1
  146. package/dist/workspace.js +236 -477
  147. package/dist/workspace.js.map +1 -1
  148. package/package.json +8 -8
  149. package/dist/capabilities/connection.js.map +0 -1
  150. package/dist/capabilities/intake.js.map +0 -1
  151. package/dist/capabilities/version-control.js.map +0 -1
  152. package/dist/index.js.map +0 -1
  153. package/dist/integrations/base.js.map +0 -1
  154. package/dist/integrations/linear/storage.js.map +0 -1
  155. package/dist/rules/index.js.map +0 -1
@@ -1,252 +1,317 @@
1
- // src/storage/domains/integrations/base.ts
2
1
  import { FactoryStorageDomain, UniqueViolationError } from "@mastra/core/storage";
3
- var INTEGRATION_CONNECTIONS_SCHEMA = {
4
- name: "integration_connections",
5
- columns: {
6
- id: { type: "uuid-pk" },
7
- integration_id: { type: "text" },
8
- org_id: { type: "text" },
9
- /** Who connected it (audit only — never scopes reads). */
10
- user_id: { type: "text", nullable: true },
11
- data: { type: "json" },
12
- metadata: { type: "json" },
13
- created_at: { type: "timestamp" },
14
- updated_at: { type: "timestamp" }
15
- },
16
- uniqueIndexes: [{ name: "integration_connections_integration_org_unique", columns: ["integration_id", "org_id"] }]
2
+ //#region src/storage/domains/integrations/base.ts
3
+ /**
4
+ * Generic integration storage — the default persistence surface for
5
+ * `FactoryIntegration`s.
6
+ *
7
+ * Most integrations persist the same three shapes: an org-owned OAuth
8
+ * **connection**, **subscriptions** binding external objects to
9
+ * sessions/threads, and per-`(org, user)` **settings**. This built-in domain
10
+ * stores all three in shared collections keyed by `integration_id`, so an
11
+ * integration author writes zero schema, zero DDL, and zero queries — and
12
+ * org scoping is enforced by construction through the pre-scoped handle
13
+ * returned by {@link IntegrationStorage.forIntegration}.
14
+ *
15
+ * Source-control integrations additionally use the shared, provider-scoped
16
+ * source-control domain for installations, projects, worktrees, and sandboxes.
17
+ *
18
+ * Payloads (`data` / `config`) are JSON documents typed per-integration via
19
+ * the handle's generics. JSON round-trips exactly what JSON can represent:
20
+ * store timestamps inside payloads as epoch millis or ISO strings, not
21
+ * `Date`s.
22
+ */
23
+ const INTEGRATION_CONNECTIONS_SCHEMA = {
24
+ name: "integration_connections",
25
+ columns: {
26
+ id: { type: "uuid-pk" },
27
+ integration_id: { type: "text" },
28
+ org_id: { type: "text" },
29
+ /** Who connected it (audit only — never scopes reads). */
30
+ user_id: {
31
+ type: "text",
32
+ nullable: true
33
+ },
34
+ data: { type: "json" },
35
+ metadata: { type: "json" },
36
+ created_at: { type: "timestamp" },
37
+ updated_at: { type: "timestamp" }
38
+ },
39
+ uniqueIndexes: [{
40
+ name: "integration_connections_integration_org_unique",
41
+ columns: ["integration_id", "org_id"]
42
+ }]
17
43
  };
18
- var INTEGRATION_SUBSCRIPTIONS_SCHEMA = {
19
- name: "integration_subscriptions",
20
- columns: {
21
- id: { type: "uuid-pk" },
22
- integration_id: { type: "text" },
23
- org_id: { type: "text" },
24
- /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */
25
- target_key: { type: "text" },
26
- session_id: { type: "text", nullable: true },
27
- resource_id: { type: "text", nullable: true },
28
- thread_id: { type: "text", nullable: true },
29
- session_scope: { type: "text", nullable: true },
30
- status: { type: "text" },
31
- data: { type: "json" },
32
- created_at: { type: "timestamp" },
33
- updated_at: { type: "timestamp" }
34
- },
35
- indexes: [
36
- { name: "integration_subscriptions_target_idx", columns: ["integration_id", "target_key"] },
37
- { name: "integration_subscriptions_org_idx", columns: ["integration_id", "org_id"] }
38
- ]
44
+ const INTEGRATION_SUBSCRIPTIONS_SCHEMA = {
45
+ name: "integration_subscriptions",
46
+ columns: {
47
+ id: { type: "uuid-pk" },
48
+ integration_id: { type: "text" },
49
+ org_id: { type: "text" },
50
+ /** Canonical external-object key the integration derives (e.g. `pr:{installation}:{repo}:{number}`). */
51
+ target_key: { type: "text" },
52
+ session_id: {
53
+ type: "text",
54
+ nullable: true
55
+ },
56
+ resource_id: {
57
+ type: "text",
58
+ nullable: true
59
+ },
60
+ thread_id: {
61
+ type: "text",
62
+ nullable: true
63
+ },
64
+ session_scope: {
65
+ type: "text",
66
+ nullable: true
67
+ },
68
+ status: { type: "text" },
69
+ data: { type: "json" },
70
+ created_at: { type: "timestamp" },
71
+ updated_at: { type: "timestamp" }
72
+ },
73
+ indexes: [{
74
+ name: "integration_subscriptions_target_idx",
75
+ columns: ["integration_id", "target_key"]
76
+ }, {
77
+ name: "integration_subscriptions_org_idx",
78
+ columns: ["integration_id", "org_id"]
79
+ }]
39
80
  };
40
- var INTEGRATION_SETTINGS_SCHEMA = {
41
- name: "integration_settings",
42
- columns: {
43
- id: { type: "uuid-pk" },
44
- integration_id: { type: "text" },
45
- org_id: { type: "text" },
46
- user_id: { type: "text" },
47
- config: { type: "json" },
48
- created_at: { type: "timestamp" },
49
- updated_at: { type: "timestamp" }
50
- },
51
- uniqueIndexes: [
52
- { name: "integration_settings_integration_org_user_unique", columns: ["integration_id", "org_id", "user_id"] }
53
- ]
81
+ const INTEGRATION_SETTINGS_SCHEMA = {
82
+ name: "integration_settings",
83
+ columns: {
84
+ id: { type: "uuid-pk" },
85
+ integration_id: { type: "text" },
86
+ org_id: { type: "text" },
87
+ user_id: { type: "text" },
88
+ config: { type: "json" },
89
+ created_at: { type: "timestamp" },
90
+ updated_at: { type: "timestamp" }
91
+ },
92
+ uniqueIndexes: [{
93
+ name: "integration_settings_integration_org_user_unique",
94
+ columns: [
95
+ "integration_id",
96
+ "org_id",
97
+ "user_id"
98
+ ]
99
+ }]
54
100
  };
101
+ /**
102
+ * The built-in generic integration domain, written once against the
103
+ * `FactoryStorageOps` surface — works on any `FactoryStorage` backend.
104
+ */
55
105
  var IntegrationStorage = class extends FactoryStorageDomain {
56
- constructor() {
57
- super("integrations");
58
- }
59
- async init() {
60
- await this.ensureCollections([
61
- INTEGRATION_CONNECTIONS_SCHEMA,
62
- INTEGRATION_SUBSCRIPTIONS_SCHEMA,
63
- INTEGRATION_SETTINGS_SCHEMA
64
- ]);
65
- }
66
- async dangerouslyClearAll() {
67
- await this.ops.deleteMany("integration_subscriptions", {});
68
- await this.ops.deleteMany("integration_settings", {});
69
- await this.ops.deleteMany("integration_connections", {});
70
- }
71
- get #db() {
72
- return this.ops;
73
- }
74
- /** A typed handle pre-scoped to `integrationId`. */
75
- forIntegration(integrationId) {
76
- if (!integrationId) throw new Error("[IntegrationStorage] integrationId is required.");
77
- const db = () => this.#db;
78
- const scoped = { integration_id: integrationId };
79
- const mapConnection = (row) => ({
80
- id: row.id,
81
- orgId: row.org_id,
82
- userId: row.user_id,
83
- data: row.data,
84
- metadata: row.metadata ?? {},
85
- createdAt: row.created_at,
86
- updatedAt: row.updated_at
87
- });
88
- const mapSubscription = (row) => ({
89
- id: row.id,
90
- orgId: row.org_id,
91
- targetKey: row.target_key,
92
- sessionId: row.session_id,
93
- resourceId: row.resource_id,
94
- threadId: row.thread_id,
95
- sessionScope: row.session_scope,
96
- status: row.status,
97
- data: row.data,
98
- createdAt: row.created_at,
99
- updatedAt: row.updated_at
100
- });
101
- return {
102
- integrationId,
103
- connections: {
104
- get: async (orgId) => {
105
- const row = await db().findOne("integration_connections", { ...scoped, org_id: orgId });
106
- return row ? mapConnection(row) : null;
107
- },
108
- upsert: async (orgId, input) => {
109
- const where = { ...scoped, org_id: orgId };
110
- const update = async () => db().updateMany("integration_connections", where, {
111
- user_id: input.userId ?? null,
112
- data: input.data,
113
- metadata: input.metadata ?? {},
114
- updated_at: /* @__PURE__ */ new Date()
115
- });
116
- let lastError;
117
- for (let attempt = 0; attempt < 2; attempt++) {
118
- if (await update() > 0) return;
119
- const now = /* @__PURE__ */ new Date();
120
- try {
121
- await db().insertOne("integration_connections", {
122
- ...where,
123
- user_id: input.userId ?? null,
124
- data: input.data,
125
- metadata: input.metadata ?? {},
126
- created_at: now,
127
- updated_at: now
128
- });
129
- return;
130
- } catch (error) {
131
- if (!(error instanceof UniqueViolationError)) throw error;
132
- lastError = error;
133
- }
134
- }
135
- throw lastError;
136
- },
137
- update: async (orgId, fn) => {
138
- const row = await db().updateAtomic(
139
- "integration_connections",
140
- { ...scoped, org_id: orgId },
141
- (current) => ({ data: fn(current.data), updated_at: /* @__PURE__ */ new Date() })
142
- );
143
- return row ? mapConnection(row) : null;
144
- },
145
- delete: async (orgId) => {
146
- const deleted = await db().deleteMany("integration_connections", { ...scoped, org_id: orgId });
147
- return deleted > 0;
148
- }
149
- },
150
- subscriptions: {
151
- create: async (input) => {
152
- const now = /* @__PURE__ */ new Date();
153
- const row = await db().insertOne("integration_subscriptions", {
154
- ...scoped,
155
- org_id: input.orgId,
156
- target_key: input.targetKey,
157
- session_id: input.sessionId ?? null,
158
- resource_id: input.resourceId ?? null,
159
- thread_id: input.threadId ?? null,
160
- session_scope: input.sessionScope ?? null,
161
- status: input.status ?? "active",
162
- data: input.data ?? {},
163
- created_at: now,
164
- updated_at: now
165
- });
166
- return mapSubscription(row);
167
- },
168
- listByTarget: async (targetKey, opts) => {
169
- const rows = await db().findMany(
170
- "integration_subscriptions",
171
- { ...scoped, target_key: targetKey, ...opts?.status !== void 0 ? { status: opts.status } : {} },
172
- { orderBy: [["created_at", "asc"]] }
173
- );
174
- return rows.map(mapSubscription);
175
- },
176
- listBySession: async (sessionId) => {
177
- const rows = await db().findMany(
178
- "integration_subscriptions",
179
- { ...scoped, session_id: sessionId },
180
- { orderBy: [["created_at", "asc"]] }
181
- );
182
- return rows.map(mapSubscription);
183
- },
184
- listByThread: async (resourceId, threadId) => {
185
- const rows = await db().findMany(
186
- "integration_subscriptions",
187
- { ...scoped, resource_id: resourceId, thread_id: threadId },
188
- { orderBy: [["created_at", "asc"]] }
189
- );
190
- return rows.map(mapSubscription);
191
- },
192
- updateStatus: async (id, status) => {
193
- await db().updateMany("integration_subscriptions", { ...scoped, id }, { status, updated_at: /* @__PURE__ */ new Date() });
194
- },
195
- delete: async (id) => {
196
- const deleted = await db().deleteMany("integration_subscriptions", { ...scoped, id });
197
- return deleted > 0;
198
- },
199
- deleteWhere: async (where) => {
200
- return db().deleteMany("integration_subscriptions", {
201
- ...scoped,
202
- org_id: where.orgId,
203
- ...where.targetKey !== void 0 ? { target_key: where.targetKey } : {},
204
- ...where.sessionId !== void 0 ? { session_id: where.sessionId } : {}
205
- });
206
- }
207
- },
208
- settings: {
209
- get: async (orgId, userId) => {
210
- const row = await db().findOne("integration_settings", {
211
- ...scoped,
212
- org_id: orgId,
213
- user_id: userId
214
- });
215
- return row ? structuredClone(row.config) : null;
216
- },
217
- save: async (orgId, userId, config) => {
218
- const where = { ...scoped, org_id: orgId, user_id: userId };
219
- const update = async () => db().updateMany("integration_settings", where, {
220
- config,
221
- updated_at: /* @__PURE__ */ new Date()
222
- });
223
- let lastError;
224
- for (let attempt = 0; attempt < 2; attempt++) {
225
- if (await update() > 0) return;
226
- const now = /* @__PURE__ */ new Date();
227
- try {
228
- await db().insertOne("integration_settings", {
229
- ...where,
230
- config,
231
- created_at: now,
232
- updated_at: now
233
- });
234
- return;
235
- } catch (error) {
236
- if (!(error instanceof UniqueViolationError)) throw error;
237
- lastError = error;
238
- }
239
- }
240
- throw lastError;
241
- }
242
- }
243
- };
244
- }
245
- };
246
- export {
247
- INTEGRATION_CONNECTIONS_SCHEMA,
248
- INTEGRATION_SETTINGS_SCHEMA,
249
- INTEGRATION_SUBSCRIPTIONS_SCHEMA,
250
- IntegrationStorage
106
+ constructor() {
107
+ super("integrations");
108
+ }
109
+ async init() {
110
+ await this.ensureCollections([
111
+ INTEGRATION_CONNECTIONS_SCHEMA,
112
+ INTEGRATION_SUBSCRIPTIONS_SCHEMA,
113
+ INTEGRATION_SETTINGS_SCHEMA
114
+ ]);
115
+ }
116
+ async dangerouslyClearAll() {
117
+ await this.ops.deleteMany("integration_subscriptions", {});
118
+ await this.ops.deleteMany("integration_settings", {});
119
+ await this.ops.deleteMany("integration_connections", {});
120
+ }
121
+ get #db() {
122
+ return this.ops;
123
+ }
124
+ /** A typed handle pre-scoped to `integrationId`. */
125
+ forIntegration(integrationId) {
126
+ if (!integrationId) throw new Error("[IntegrationStorage] integrationId is required.");
127
+ const db = () => this.#db;
128
+ const scoped = { integration_id: integrationId };
129
+ const mapConnection = (row) => ({
130
+ id: row.id,
131
+ orgId: row.org_id,
132
+ userId: row.user_id,
133
+ data: row.data,
134
+ metadata: row.metadata ?? {},
135
+ createdAt: row.created_at,
136
+ updatedAt: row.updated_at
137
+ });
138
+ const mapSubscription = (row) => ({
139
+ id: row.id,
140
+ orgId: row.org_id,
141
+ targetKey: row.target_key,
142
+ sessionId: row.session_id,
143
+ resourceId: row.resource_id,
144
+ threadId: row.thread_id,
145
+ sessionScope: row.session_scope,
146
+ status: row.status,
147
+ data: row.data,
148
+ createdAt: row.created_at,
149
+ updatedAt: row.updated_at
150
+ });
151
+ return {
152
+ integrationId,
153
+ connections: {
154
+ get: async (orgId) => {
155
+ const row = await db().findOne("integration_connections", {
156
+ ...scoped,
157
+ org_id: orgId
158
+ });
159
+ return row ? mapConnection(row) : null;
160
+ },
161
+ upsert: async (orgId, input) => {
162
+ const where = {
163
+ ...scoped,
164
+ org_id: orgId
165
+ };
166
+ const update = async () => db().updateMany("integration_connections", where, {
167
+ user_id: input.userId ?? null,
168
+ data: input.data,
169
+ metadata: input.metadata ?? {},
170
+ updated_at: /* @__PURE__ */ new Date()
171
+ });
172
+ let lastError;
173
+ for (let attempt = 0; attempt < 2; attempt++) {
174
+ if (await update() > 0) return;
175
+ const now = /* @__PURE__ */ new Date();
176
+ try {
177
+ await db().insertOne("integration_connections", {
178
+ ...where,
179
+ user_id: input.userId ?? null,
180
+ data: input.data,
181
+ metadata: input.metadata ?? {},
182
+ created_at: now,
183
+ updated_at: now
184
+ });
185
+ return;
186
+ } catch (error) {
187
+ if (!(error instanceof UniqueViolationError)) throw error;
188
+ lastError = error;
189
+ }
190
+ }
191
+ throw lastError;
192
+ },
193
+ update: async (orgId, fn) => {
194
+ const row = await db().updateAtomic("integration_connections", {
195
+ ...scoped,
196
+ org_id: orgId
197
+ }, (current) => ({
198
+ data: fn(current.data),
199
+ updated_at: /* @__PURE__ */ new Date()
200
+ }));
201
+ return row ? mapConnection(row) : null;
202
+ },
203
+ delete: async (orgId) => {
204
+ return await db().deleteMany("integration_connections", {
205
+ ...scoped,
206
+ org_id: orgId
207
+ }) > 0;
208
+ }
209
+ },
210
+ subscriptions: {
211
+ create: async (input) => {
212
+ const now = /* @__PURE__ */ new Date();
213
+ const row = await db().insertOne("integration_subscriptions", {
214
+ ...scoped,
215
+ org_id: input.orgId,
216
+ target_key: input.targetKey,
217
+ session_id: input.sessionId ?? null,
218
+ resource_id: input.resourceId ?? null,
219
+ thread_id: input.threadId ?? null,
220
+ session_scope: input.sessionScope ?? null,
221
+ status: input.status ?? "active",
222
+ data: input.data ?? {},
223
+ created_at: now,
224
+ updated_at: now
225
+ });
226
+ return mapSubscription(row);
227
+ },
228
+ listByTarget: async (targetKey, opts) => {
229
+ return (await db().findMany("integration_subscriptions", {
230
+ ...scoped,
231
+ target_key: targetKey,
232
+ ...opts?.status !== void 0 ? { status: opts.status } : {}
233
+ }, { orderBy: [["created_at", "asc"]] })).map(mapSubscription);
234
+ },
235
+ listBySession: async (sessionId) => {
236
+ return (await db().findMany("integration_subscriptions", {
237
+ ...scoped,
238
+ session_id: sessionId
239
+ }, { orderBy: [["created_at", "asc"]] })).map(mapSubscription);
240
+ },
241
+ listByThread: async (resourceId, threadId) => {
242
+ return (await db().findMany("integration_subscriptions", {
243
+ ...scoped,
244
+ resource_id: resourceId,
245
+ thread_id: threadId
246
+ }, { orderBy: [["created_at", "asc"]] })).map(mapSubscription);
247
+ },
248
+ updateStatus: async (id, status) => {
249
+ await db().updateMany("integration_subscriptions", {
250
+ ...scoped,
251
+ id
252
+ }, {
253
+ status,
254
+ updated_at: /* @__PURE__ */ new Date()
255
+ });
256
+ },
257
+ delete: async (id) => {
258
+ return await db().deleteMany("integration_subscriptions", {
259
+ ...scoped,
260
+ id
261
+ }) > 0;
262
+ },
263
+ deleteWhere: async (where) => {
264
+ return db().deleteMany("integration_subscriptions", {
265
+ ...scoped,
266
+ org_id: where.orgId,
267
+ ...where.targetKey !== void 0 ? { target_key: where.targetKey } : {},
268
+ ...where.sessionId !== void 0 ? { session_id: where.sessionId } : {}
269
+ });
270
+ }
271
+ },
272
+ settings: {
273
+ get: async (orgId, userId) => {
274
+ const row = await db().findOne("integration_settings", {
275
+ ...scoped,
276
+ org_id: orgId,
277
+ user_id: userId
278
+ });
279
+ return row ? structuredClone(row.config) : null;
280
+ },
281
+ save: async (orgId, userId, config) => {
282
+ const where = {
283
+ ...scoped,
284
+ org_id: orgId,
285
+ user_id: userId
286
+ };
287
+ const update = async () => db().updateMany("integration_settings", where, {
288
+ config,
289
+ updated_at: /* @__PURE__ */ new Date()
290
+ });
291
+ let lastError;
292
+ for (let attempt = 0; attempt < 2; attempt++) {
293
+ if (await update() > 0) return;
294
+ const now = /* @__PURE__ */ new Date();
295
+ try {
296
+ await db().insertOne("integration_settings", {
297
+ ...where,
298
+ config,
299
+ created_at: now,
300
+ updated_at: now
301
+ });
302
+ return;
303
+ } catch (error) {
304
+ if (!(error instanceof UniqueViolationError)) throw error;
305
+ lastError = error;
306
+ }
307
+ }
308
+ throw lastError;
309
+ }
310
+ }
311
+ };
312
+ }
251
313
  };
314
+ //#endregion
315
+ export { INTEGRATION_CONNECTIONS_SCHEMA, INTEGRATION_SETTINGS_SCHEMA, INTEGRATION_SUBSCRIPTIONS_SCHEMA, IntegrationStorage };
316
+
252
317
  //# sourceMappingURL=base.js.map