@agenticmail/enterprise 0.2.1

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 (69) hide show
  1. package/ARCHITECTURE.md +183 -0
  2. package/agenticmail-enterprise.db +0 -0
  3. package/dashboards/README.md +120 -0
  4. package/dashboards/dotnet/Program.cs +261 -0
  5. package/dashboards/express/app.js +146 -0
  6. package/dashboards/go/main.go +513 -0
  7. package/dashboards/html/index.html +535 -0
  8. package/dashboards/java/AgenticMailDashboard.java +376 -0
  9. package/dashboards/php/index.php +414 -0
  10. package/dashboards/python/app.py +273 -0
  11. package/dashboards/ruby/app.rb +195 -0
  12. package/dist/chunk-77IDQJL3.js +7 -0
  13. package/dist/chunk-7RGCCHIT.js +115 -0
  14. package/dist/chunk-DXNKR3TG.js +1355 -0
  15. package/dist/chunk-IQWA44WT.js +970 -0
  16. package/dist/chunk-LCUZGIDH.js +965 -0
  17. package/dist/chunk-N2JVTNNJ.js +2553 -0
  18. package/dist/chunk-O462UJBH.js +363 -0
  19. package/dist/chunk-PNKVD2UK.js +26 -0
  20. package/dist/cli.js +218 -0
  21. package/dist/dashboard/index.html +558 -0
  22. package/dist/db-adapter-DEWEFNIV.js +7 -0
  23. package/dist/dynamodb-CCGL2E77.js +426 -0
  24. package/dist/engine/index.js +1261 -0
  25. package/dist/index.js +522 -0
  26. package/dist/mongodb-ODTXIVPV.js +319 -0
  27. package/dist/mysql-RM3S2FV5.js +521 -0
  28. package/dist/postgres-LN7A6MGQ.js +518 -0
  29. package/dist/routes-2JEPIIKC.js +441 -0
  30. package/dist/routes-74ZLKJKP.js +399 -0
  31. package/dist/server.js +7 -0
  32. package/dist/sqlite-3K5YOZ4K.js +439 -0
  33. package/dist/turso-LDWODSDI.js +442 -0
  34. package/package.json +49 -0
  35. package/src/admin/routes.ts +331 -0
  36. package/src/auth/routes.ts +130 -0
  37. package/src/cli.ts +260 -0
  38. package/src/dashboard/index.html +558 -0
  39. package/src/db/adapter.ts +230 -0
  40. package/src/db/dynamodb.ts +456 -0
  41. package/src/db/factory.ts +51 -0
  42. package/src/db/mongodb.ts +360 -0
  43. package/src/db/mysql.ts +472 -0
  44. package/src/db/postgres.ts +479 -0
  45. package/src/db/sql-schema.ts +123 -0
  46. package/src/db/sqlite.ts +391 -0
  47. package/src/db/turso.ts +411 -0
  48. package/src/deploy/fly.ts +368 -0
  49. package/src/deploy/managed.ts +213 -0
  50. package/src/engine/activity.ts +474 -0
  51. package/src/engine/agent-config.ts +429 -0
  52. package/src/engine/agenticmail-bridge.ts +296 -0
  53. package/src/engine/approvals.ts +278 -0
  54. package/src/engine/db-adapter.ts +682 -0
  55. package/src/engine/db-schema.ts +335 -0
  56. package/src/engine/deployer.ts +595 -0
  57. package/src/engine/index.ts +134 -0
  58. package/src/engine/knowledge.ts +486 -0
  59. package/src/engine/lifecycle.ts +635 -0
  60. package/src/engine/openclaw-hook.ts +371 -0
  61. package/src/engine/routes.ts +528 -0
  62. package/src/engine/skills.ts +473 -0
  63. package/src/engine/tenant.ts +345 -0
  64. package/src/engine/tool-catalog.ts +189 -0
  65. package/src/index.ts +64 -0
  66. package/src/lib/resilience.ts +326 -0
  67. package/src/middleware/index.ts +286 -0
  68. package/src/server.ts +310 -0
  69. package/tsconfig.json +14 -0
@@ -0,0 +1,521 @@
1
+ import {
2
+ getAllCreateStatements
3
+ } from "./chunk-7RGCCHIT.js";
4
+ import {
5
+ DatabaseAdapter
6
+ } from "./chunk-77IDQJL3.js";
7
+ import "./chunk-PNKVD2UK.js";
8
+
9
+ // src/db/mysql.ts
10
+ import { randomUUID, createHash } from "crypto";
11
+ var mysql2;
12
+ async function getMysql() {
13
+ if (!mysql2) {
14
+ try {
15
+ mysql2 = await import("mysql2/promise");
16
+ } catch {
17
+ throw new Error(
18
+ "MySQL driver not found. Install it: npm install mysql2\nFor PlanetScale, the same driver works with SSL enabled."
19
+ );
20
+ }
21
+ }
22
+ return mysql2;
23
+ }
24
+ var MysqlAdapter = class extends DatabaseAdapter {
25
+ type = "mysql";
26
+ pool = null;
27
+ async connect(config) {
28
+ const m = await getMysql();
29
+ const poolConfig = config.connectionString ? { uri: config.connectionString } : {
30
+ host: config.host || "localhost",
31
+ port: config.port || 3306,
32
+ database: config.database,
33
+ user: config.username,
34
+ password: config.password
35
+ };
36
+ poolConfig.waitForConnections = true;
37
+ poolConfig.connectionLimit = 20;
38
+ poolConfig.idleTimeout = 3e4;
39
+ if (config.ssl) {
40
+ poolConfig.ssl = { rejectUnauthorized: false };
41
+ }
42
+ this.pool = m.createPool(poolConfig);
43
+ const conn = await this.pool.getConnection();
44
+ conn.release();
45
+ }
46
+ async disconnect() {
47
+ if (this.pool) await this.pool.end();
48
+ }
49
+ isConnected() {
50
+ return this.pool !== null;
51
+ }
52
+ async migrate() {
53
+ const stmts = getAllCreateStatements();
54
+ const conn = await this.pool.getConnection();
55
+ try {
56
+ for (const stmt of stmts) {
57
+ const mysqlStmt = stmt.replace(
58
+ /CREATE INDEX IF NOT EXISTS (\w+)/g,
59
+ "CREATE INDEX IF NOT EXISTS $1"
60
+ );
61
+ await conn.execute(mysqlStmt);
62
+ }
63
+ await conn.execute(
64
+ `INSERT IGNORE INTO retention_policy (id) VALUES ('default')`
65
+ );
66
+ } finally {
67
+ conn.release();
68
+ }
69
+ }
70
+ // ─── Helpers ─────────────────────────────────────────
71
+ async query(sql, params = []) {
72
+ const [rows] = await this.pool.execute(sql, params);
73
+ return rows;
74
+ }
75
+ async queryOne(sql, params = []) {
76
+ const rows = await this.query(sql, params);
77
+ return rows[0] || null;
78
+ }
79
+ async execute(sql, params = []) {
80
+ await this.pool.execute(sql, params);
81
+ }
82
+ // ─── Company ─────────────────────────────────────────
83
+ async getSettings() {
84
+ const r = await this.queryOne("SELECT * FROM company_settings WHERE id = ?", ["default"]);
85
+ return r ? this.mapSettings(r) : null;
86
+ }
87
+ async updateSettings(updates) {
88
+ const map = {
89
+ name: "name",
90
+ domain: "domain",
91
+ subdomain: "subdomain",
92
+ smtpHost: "smtp_host",
93
+ smtpPort: "smtp_port",
94
+ smtpUser: "smtp_user",
95
+ smtpPass: "smtp_pass",
96
+ dkimPrivateKey: "dkim_private_key",
97
+ logoUrl: "logo_url",
98
+ primaryColor: "primary_color",
99
+ plan: "plan"
100
+ };
101
+ const sets = [];
102
+ const vals = [];
103
+ for (const [key, col] of Object.entries(map)) {
104
+ if (updates[key] !== void 0) {
105
+ sets.push(`${col} = ?`);
106
+ vals.push(updates[key]);
107
+ }
108
+ }
109
+ if (sets.length === 0) return this.getSettings();
110
+ sets.push("updated_at = NOW()");
111
+ vals.push("default");
112
+ await this.execute(`UPDATE company_settings SET ${sets.join(", ")} WHERE id = ?`, vals);
113
+ return this.getSettings();
114
+ }
115
+ // ─── Agents ──────────────────────────────────────────
116
+ async createAgent(input) {
117
+ const id = randomUUID();
118
+ const email = input.email || `${input.name.toLowerCase().replace(/\s+/g, "-")}@localhost`;
119
+ await this.execute(
120
+ `INSERT INTO agents (id, name, email, role, metadata, created_by) VALUES (?, ?, ?, ?, ?, ?)`,
121
+ [id, input.name, email, input.role || "assistant", JSON.stringify(input.metadata || {}), input.createdBy]
122
+ );
123
+ return await this.getAgent(id);
124
+ }
125
+ async getAgent(id) {
126
+ const r = await this.queryOne("SELECT * FROM agents WHERE id = ?", [id]);
127
+ return r ? this.mapAgent(r) : null;
128
+ }
129
+ async getAgentByName(name) {
130
+ const r = await this.queryOne("SELECT * FROM agents WHERE name = ?", [name]);
131
+ return r ? this.mapAgent(r) : null;
132
+ }
133
+ async listAgents(opts) {
134
+ let q = "SELECT * FROM agents";
135
+ const params = [];
136
+ if (opts?.status) {
137
+ q += " WHERE status = ?";
138
+ params.push(opts.status);
139
+ }
140
+ q += " ORDER BY created_at DESC";
141
+ if (opts?.limit) {
142
+ q += " LIMIT ?";
143
+ params.push(opts.limit);
144
+ }
145
+ if (opts?.offset) {
146
+ q += " OFFSET ?";
147
+ params.push(opts.offset);
148
+ }
149
+ const rows = await this.query(q, params);
150
+ return rows.map((r) => this.mapAgent(r));
151
+ }
152
+ async updateAgent(id, updates) {
153
+ const fields = [];
154
+ const vals = [];
155
+ for (const [key, col] of Object.entries({ name: "name", email: "email", role: "role", status: "status" })) {
156
+ if (updates[key] !== void 0) {
157
+ fields.push(`${col} = ?`);
158
+ vals.push(updates[key]);
159
+ }
160
+ }
161
+ if (updates.metadata) {
162
+ fields.push("metadata = ?");
163
+ vals.push(JSON.stringify(updates.metadata));
164
+ }
165
+ if (fields.length === 0) return await this.getAgent(id);
166
+ fields.push("updated_at = NOW()");
167
+ vals.push(id);
168
+ await this.execute(`UPDATE agents SET ${fields.join(", ")} WHERE id = ?`, vals);
169
+ return await this.getAgent(id);
170
+ }
171
+ async archiveAgent(id) {
172
+ await this.execute("UPDATE agents SET status = 'archived', updated_at = NOW() WHERE id = ?", [id]);
173
+ }
174
+ async deleteAgent(id) {
175
+ await this.execute("DELETE FROM agents WHERE id = ?", [id]);
176
+ }
177
+ async countAgents(status) {
178
+ const q = status ? await this.queryOne("SELECT COUNT(*) as c FROM agents WHERE status = ?", [status]) : await this.queryOne("SELECT COUNT(*) as c FROM agents");
179
+ return Number(q?.c || 0);
180
+ }
181
+ // ─── Users ───────────────────────────────────────────
182
+ async createUser(input) {
183
+ const id = randomUUID();
184
+ let passwordHash = null;
185
+ if (input.password) {
186
+ const { default: bcrypt } = await import("bcryptjs");
187
+ passwordHash = await bcrypt.hash(input.password, 12);
188
+ }
189
+ await this.execute(
190
+ `INSERT INTO users (id, email, name, role, password_hash, sso_provider, sso_subject) VALUES (?, ?, ?, ?, ?, ?, ?)`,
191
+ [id, input.email, input.name, input.role, passwordHash, input.ssoProvider || null, input.ssoSubject || null]
192
+ );
193
+ return await this.getUser(id);
194
+ }
195
+ async getUser(id) {
196
+ const r = await this.queryOne("SELECT * FROM users WHERE id = ?", [id]);
197
+ return r ? this.mapUser(r) : null;
198
+ }
199
+ async getUserByEmail(email) {
200
+ const r = await this.queryOne("SELECT * FROM users WHERE email = ?", [email]);
201
+ return r ? this.mapUser(r) : null;
202
+ }
203
+ async getUserBySso(provider, subject) {
204
+ const r = await this.queryOne(
205
+ "SELECT * FROM users WHERE sso_provider = ? AND sso_subject = ?",
206
+ [provider, subject]
207
+ );
208
+ return r ? this.mapUser(r) : null;
209
+ }
210
+ async listUsers(opts) {
211
+ let q = "SELECT * FROM users ORDER BY created_at DESC";
212
+ const params = [];
213
+ if (opts?.limit) {
214
+ q += " LIMIT ?";
215
+ params.push(opts.limit);
216
+ }
217
+ if (opts?.offset) {
218
+ q += " OFFSET ?";
219
+ params.push(opts.offset);
220
+ }
221
+ const rows = await this.query(q, params);
222
+ return rows.map((r) => this.mapUser(r));
223
+ }
224
+ async updateUser(id, updates) {
225
+ const fields = [];
226
+ const vals = [];
227
+ for (const key of ["email", "name", "role"]) {
228
+ if (updates[key] !== void 0) {
229
+ fields.push(`${key} = ?`);
230
+ vals.push(updates[key]);
231
+ }
232
+ }
233
+ if (fields.length === 0) return await this.getUser(id);
234
+ fields.push("updated_at = NOW()");
235
+ vals.push(id);
236
+ await this.execute(`UPDATE users SET ${fields.join(", ")} WHERE id = ?`, vals);
237
+ return await this.getUser(id);
238
+ }
239
+ async deleteUser(id) {
240
+ await this.execute("DELETE FROM users WHERE id = ?", [id]);
241
+ }
242
+ // ─── Audit ───────────────────────────────────────────
243
+ async logEvent(event) {
244
+ await this.execute(
245
+ `INSERT INTO audit_log (id, actor, actor_type, action, resource, details, ip) VALUES (?, ?, ?, ?, ?, ?, ?)`,
246
+ [
247
+ randomUUID(),
248
+ event.actor,
249
+ event.actorType,
250
+ event.action,
251
+ event.resource,
252
+ JSON.stringify(event.details || {}),
253
+ event.ip || null
254
+ ]
255
+ );
256
+ }
257
+ async queryAudit(filters) {
258
+ const where = [];
259
+ const params = [];
260
+ if (filters.actor) {
261
+ where.push("actor = ?");
262
+ params.push(filters.actor);
263
+ }
264
+ if (filters.action) {
265
+ where.push("action = ?");
266
+ params.push(filters.action);
267
+ }
268
+ if (filters.resource) {
269
+ where.push("resource LIKE ?");
270
+ params.push(`%${filters.resource}%`);
271
+ }
272
+ if (filters.from) {
273
+ where.push("timestamp >= ?");
274
+ params.push(filters.from);
275
+ }
276
+ if (filters.to) {
277
+ where.push("timestamp <= ?");
278
+ params.push(filters.to);
279
+ }
280
+ const wc = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
281
+ const countRow = await this.queryOne(`SELECT COUNT(*) as c FROM audit_log ${wc}`, params);
282
+ const total = Number(countRow?.c || 0);
283
+ let q = `SELECT * FROM audit_log ${wc} ORDER BY timestamp DESC`;
284
+ const qParams = [...params];
285
+ if (filters.limit) {
286
+ q += " LIMIT ?";
287
+ qParams.push(filters.limit);
288
+ }
289
+ if (filters.offset) {
290
+ q += " OFFSET ?";
291
+ qParams.push(filters.offset);
292
+ }
293
+ const rows = await this.query(q, qParams);
294
+ return {
295
+ events: rows.map((r) => ({
296
+ id: r.id,
297
+ timestamp: new Date(r.timestamp),
298
+ actor: r.actor,
299
+ actorType: r.actor_type,
300
+ action: r.action,
301
+ resource: r.resource,
302
+ details: typeof r.details === "string" ? JSON.parse(r.details) : r.details || {},
303
+ ip: r.ip
304
+ })),
305
+ total
306
+ };
307
+ }
308
+ // ─── API Keys ────────────────────────────────────────
309
+ async createApiKey(input) {
310
+ const id = randomUUID();
311
+ const plaintext = `ek_${randomUUID().replace(/-/g, "")}`;
312
+ const keyHash = createHash("sha256").update(plaintext).digest("hex");
313
+ const keyPrefix = plaintext.substring(0, 11);
314
+ await this.execute(
315
+ `INSERT INTO api_keys (id, name, key_hash, key_prefix, scopes, created_by, expires_at) VALUES (?, ?, ?, ?, ?, ?, ?)`,
316
+ [id, input.name, keyHash, keyPrefix, JSON.stringify(input.scopes), input.createdBy, input.expiresAt || null]
317
+ );
318
+ return { key: await this.getApiKey(id), plaintext };
319
+ }
320
+ async getApiKey(id) {
321
+ const r = await this.queryOne("SELECT * FROM api_keys WHERE id = ?", [id]);
322
+ return r ? this.mapApiKey(r) : null;
323
+ }
324
+ async validateApiKey(plaintext) {
325
+ const keyHash = createHash("sha256").update(plaintext).digest("hex");
326
+ const r = await this.queryOne("SELECT * FROM api_keys WHERE key_hash = ? AND revoked = 0", [keyHash]);
327
+ if (!r) return null;
328
+ const key = this.mapApiKey(r);
329
+ if (key.expiresAt && /* @__PURE__ */ new Date() > key.expiresAt) return null;
330
+ await this.execute("UPDATE api_keys SET last_used_at = NOW() WHERE id = ?", [key.id]);
331
+ return key;
332
+ }
333
+ async listApiKeys(opts) {
334
+ let q = "SELECT * FROM api_keys";
335
+ const params = [];
336
+ if (opts?.createdBy) {
337
+ q += " WHERE created_by = ?";
338
+ params.push(opts.createdBy);
339
+ }
340
+ q += " ORDER BY created_at DESC";
341
+ const rows = await this.query(q, params);
342
+ return rows.map((r) => this.mapApiKey(r));
343
+ }
344
+ async revokeApiKey(id) {
345
+ await this.execute("UPDATE api_keys SET revoked = 1 WHERE id = ?", [id]);
346
+ }
347
+ // ─── Rules ───────────────────────────────────────────
348
+ async createRule(rule) {
349
+ const id = randomUUID();
350
+ await this.execute(
351
+ `INSERT INTO email_rules (id, name, agent_id, conditions, actions, priority, enabled) VALUES (?, ?, ?, ?, ?, ?, ?)`,
352
+ [
353
+ id,
354
+ rule.name,
355
+ rule.agentId || null,
356
+ JSON.stringify(rule.conditions),
357
+ JSON.stringify(rule.actions),
358
+ rule.priority,
359
+ rule.enabled ? 1 : 0
360
+ ]
361
+ );
362
+ const r = await this.queryOne("SELECT * FROM email_rules WHERE id = ?", [id]);
363
+ return this.mapRule(r);
364
+ }
365
+ async getRules(agentId) {
366
+ let q = "SELECT * FROM email_rules";
367
+ const params = [];
368
+ if (agentId) {
369
+ q += " WHERE agent_id = ? OR agent_id IS NULL";
370
+ params.push(agentId);
371
+ }
372
+ q += " ORDER BY priority DESC";
373
+ const rows = await this.query(q, params);
374
+ return rows.map((r) => this.mapRule(r));
375
+ }
376
+ async updateRule(id, updates) {
377
+ const fields = [];
378
+ const vals = [];
379
+ if (updates.name !== void 0) {
380
+ fields.push("name = ?");
381
+ vals.push(updates.name);
382
+ }
383
+ if (updates.conditions) {
384
+ fields.push("conditions = ?");
385
+ vals.push(JSON.stringify(updates.conditions));
386
+ }
387
+ if (updates.actions) {
388
+ fields.push("actions = ?");
389
+ vals.push(JSON.stringify(updates.actions));
390
+ }
391
+ if (updates.priority !== void 0) {
392
+ fields.push("priority = ?");
393
+ vals.push(updates.priority);
394
+ }
395
+ if (updates.enabled !== void 0) {
396
+ fields.push("enabled = ?");
397
+ vals.push(updates.enabled ? 1 : 0);
398
+ }
399
+ if (fields.length === 0) {
400
+ const r2 = await this.queryOne("SELECT * FROM email_rules WHERE id = ?", [id]);
401
+ return this.mapRule(r2);
402
+ }
403
+ fields.push("updated_at = NOW()");
404
+ vals.push(id);
405
+ await this.execute(`UPDATE email_rules SET ${fields.join(", ")} WHERE id = ?`, vals);
406
+ const r = await this.queryOne("SELECT * FROM email_rules WHERE id = ?", [id]);
407
+ return this.mapRule(r);
408
+ }
409
+ async deleteRule(id) {
410
+ await this.execute("DELETE FROM email_rules WHERE id = ?", [id]);
411
+ }
412
+ // ─── Retention ───────────────────────────────────────
413
+ async getRetentionPolicy() {
414
+ const r = await this.queryOne("SELECT * FROM retention_policy WHERE id = ?", ["default"]);
415
+ if (!r) return { enabled: false, retainDays: 365, archiveFirst: true };
416
+ return {
417
+ enabled: !!r.enabled,
418
+ retainDays: r.retain_days,
419
+ excludeTags: typeof r.exclude_tags === "string" ? JSON.parse(r.exclude_tags) : r.exclude_tags || [],
420
+ archiveFirst: !!r.archive_first
421
+ };
422
+ }
423
+ async setRetentionPolicy(policy) {
424
+ await this.execute(
425
+ `UPDATE retention_policy SET enabled = ?, retain_days = ?, exclude_tags = ?, archive_first = ? WHERE id = 'default'`,
426
+ [policy.enabled ? 1 : 0, policy.retainDays, JSON.stringify(policy.excludeTags || []), policy.archiveFirst ? 1 : 0]
427
+ );
428
+ }
429
+ // ─── Stats ───────────────────────────────────────────
430
+ async getStats() {
431
+ const [agents, active, users, audit] = await Promise.all([
432
+ this.queryOne("SELECT COUNT(*) as c FROM agents"),
433
+ this.queryOne("SELECT COUNT(*) as c FROM agents WHERE status = 'active'"),
434
+ this.queryOne("SELECT COUNT(*) as c FROM users"),
435
+ this.queryOne("SELECT COUNT(*) as c FROM audit_log")
436
+ ]);
437
+ return {
438
+ totalAgents: Number(agents?.c || 0),
439
+ activeAgents: Number(active?.c || 0),
440
+ totalUsers: Number(users?.c || 0),
441
+ totalEmails: 0,
442
+ totalAuditEvents: Number(audit?.c || 0)
443
+ };
444
+ }
445
+ // ─── Mappers ─────────────────────────────────────────
446
+ mapAgent(r) {
447
+ return {
448
+ id: r.id,
449
+ name: r.name,
450
+ email: r.email,
451
+ role: r.role,
452
+ status: r.status,
453
+ metadata: typeof r.metadata === "string" ? JSON.parse(r.metadata) : r.metadata || {},
454
+ createdAt: new Date(r.created_at),
455
+ updatedAt: new Date(r.updated_at),
456
+ createdBy: r.created_by
457
+ };
458
+ }
459
+ mapUser(r) {
460
+ return {
461
+ id: r.id,
462
+ email: r.email,
463
+ name: r.name,
464
+ role: r.role,
465
+ passwordHash: r.password_hash,
466
+ ssoProvider: r.sso_provider,
467
+ ssoSubject: r.sso_subject,
468
+ createdAt: new Date(r.created_at),
469
+ updatedAt: new Date(r.updated_at),
470
+ lastLoginAt: r.last_login_at ? new Date(r.last_login_at) : void 0
471
+ };
472
+ }
473
+ mapApiKey(r) {
474
+ return {
475
+ id: r.id,
476
+ name: r.name,
477
+ keyHash: r.key_hash,
478
+ keyPrefix: r.key_prefix,
479
+ scopes: typeof r.scopes === "string" ? JSON.parse(r.scopes) : r.scopes || [],
480
+ createdBy: r.created_by,
481
+ createdAt: new Date(r.created_at),
482
+ lastUsedAt: r.last_used_at ? new Date(r.last_used_at) : void 0,
483
+ expiresAt: r.expires_at ? new Date(r.expires_at) : void 0,
484
+ revoked: !!r.revoked
485
+ };
486
+ }
487
+ mapRule(r) {
488
+ return {
489
+ id: r.id,
490
+ name: r.name,
491
+ agentId: r.agent_id,
492
+ conditions: typeof r.conditions === "string" ? JSON.parse(r.conditions) : r.conditions || {},
493
+ actions: typeof r.actions === "string" ? JSON.parse(r.actions) : r.actions || {},
494
+ priority: r.priority,
495
+ enabled: !!r.enabled,
496
+ createdAt: new Date(r.created_at),
497
+ updatedAt: new Date(r.updated_at)
498
+ };
499
+ }
500
+ mapSettings(r) {
501
+ return {
502
+ id: r.id,
503
+ name: r.name,
504
+ domain: r.domain,
505
+ subdomain: r.subdomain,
506
+ smtpHost: r.smtp_host,
507
+ smtpPort: r.smtp_port,
508
+ smtpUser: r.smtp_user,
509
+ smtpPass: r.smtp_pass,
510
+ dkimPrivateKey: r.dkim_private_key,
511
+ logoUrl: r.logo_url,
512
+ primaryColor: r.primary_color,
513
+ plan: r.plan,
514
+ createdAt: new Date(r.created_at),
515
+ updatedAt: new Date(r.updated_at)
516
+ };
517
+ }
518
+ };
519
+ export {
520
+ MysqlAdapter
521
+ };