@agenticmail/enterprise 0.5.10 → 0.5.12

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.
@@ -0,0 +1,581 @@
1
+ import {
2
+ getAllCreateStatements
3
+ } from "./chunk-XMDE2NGH.js";
4
+ import {
5
+ DatabaseAdapter
6
+ } from "./chunk-FLRYMSKY.js";
7
+ import "./chunk-KFQGP6VL.js";
8
+
9
+ // src/db/postgres.ts
10
+ import { randomUUID, createHash } from "crypto";
11
+ var pg;
12
+ async function getPg() {
13
+ if (!pg) {
14
+ const { resolveDriver } = await import("./resolve-driver-VQXMFKLJ.js");
15
+ pg = await resolveDriver(
16
+ "pg",
17
+ "PostgreSQL driver not found. Install it: npm install pg\nFor Supabase/Neon/CockroachDB, the same pg driver works."
18
+ );
19
+ }
20
+ return pg;
21
+ }
22
+ var PostgresAdapter = class extends DatabaseAdapter {
23
+ type = "postgres";
24
+ pool = null;
25
+ async connect(config) {
26
+ const { Pool } = await getPg();
27
+ this.pool = new Pool({
28
+ connectionString: config.connectionString,
29
+ host: config.host,
30
+ port: config.port,
31
+ database: config.database,
32
+ user: config.username,
33
+ password: config.password,
34
+ ssl: config.ssl ? { rejectUnauthorized: false } : void 0,
35
+ max: 20,
36
+ idleTimeoutMillis: 3e4
37
+ });
38
+ const client = await this.pool.connect();
39
+ client.release();
40
+ }
41
+ async disconnect() {
42
+ if (this.pool) await this.pool.end();
43
+ }
44
+ isConnected() {
45
+ return this.pool !== null;
46
+ }
47
+ // ─── Engine Integration ──────────────────────────────────
48
+ getEngineDB() {
49
+ if (!this.pool) return null;
50
+ const pool = this.pool;
51
+ const pgSql = (sql) => {
52
+ let i = 0;
53
+ return sql.replace(/\?/g, () => `$${++i}`);
54
+ };
55
+ return {
56
+ run: async (sql, params) => {
57
+ await pool.query(pgSql(sql), params);
58
+ },
59
+ get: async (sql, params) => {
60
+ const result = await pool.query(pgSql(sql), params);
61
+ return result.rows[0];
62
+ },
63
+ all: async (sql, params) => {
64
+ const result = await pool.query(pgSql(sql), params);
65
+ return result.rows;
66
+ }
67
+ };
68
+ }
69
+ getDialect() {
70
+ return "postgres";
71
+ }
72
+ async migrate() {
73
+ const stmts = getAllCreateStatements();
74
+ const client = await this.pool.connect();
75
+ try {
76
+ await client.query("BEGIN");
77
+ for (const stmt of stmts) {
78
+ await client.query(stmt);
79
+ }
80
+ await client.query(`
81
+ INSERT INTO retention_policy (id) VALUES ('default')
82
+ ON CONFLICT (id) DO NOTHING
83
+ `);
84
+ await client.query("COMMIT");
85
+ } catch (err) {
86
+ await client.query("ROLLBACK");
87
+ throw err;
88
+ } finally {
89
+ client.release();
90
+ }
91
+ }
92
+ // ─── Company ─────────────────────────────────────────────
93
+ async getSettings() {
94
+ const { rows } = await this.pool.query(
95
+ "SELECT * FROM company_settings WHERE id = $1",
96
+ ["default"]
97
+ );
98
+ return rows[0] ? this.mapSettings(rows[0]) : null;
99
+ }
100
+ async updateSettings(updates) {
101
+ await this.pool.query(
102
+ `INSERT INTO company_settings (id, name, subdomain) VALUES ('default', '', '')
103
+ ON CONFLICT (id) DO NOTHING`
104
+ );
105
+ const fields = [];
106
+ const values = [];
107
+ let i = 1;
108
+ const map = {
109
+ name: "name",
110
+ domain: "domain",
111
+ subdomain: "subdomain",
112
+ smtpHost: "smtp_host",
113
+ smtpPort: "smtp_port",
114
+ smtpUser: "smtp_user",
115
+ smtpPass: "smtp_pass",
116
+ dkimPrivateKey: "dkim_private_key",
117
+ logoUrl: "logo_url",
118
+ primaryColor: "primary_color",
119
+ plan: "plan",
120
+ deploymentKeyHash: "deployment_key_hash",
121
+ domainRegistrationId: "domain_registration_id",
122
+ domainDnsChallenge: "domain_dns_challenge",
123
+ domainVerifiedAt: "domain_verified_at",
124
+ domainRegisteredAt: "domain_registered_at",
125
+ domainStatus: "domain_status"
126
+ };
127
+ for (const [key, col] of Object.entries(map)) {
128
+ if (updates[key] !== void 0) {
129
+ fields.push(`${col} = $${i}`);
130
+ values.push(updates[key]);
131
+ i++;
132
+ }
133
+ }
134
+ if (updates.ssoConfig !== void 0) {
135
+ fields.push(`sso_config = $${i}`);
136
+ values.push(JSON.stringify(updates.ssoConfig));
137
+ i++;
138
+ }
139
+ if (updates.toolSecurityConfig !== void 0) {
140
+ fields.push(`tool_security_config = $${i}`);
141
+ values.push(JSON.stringify(updates.toolSecurityConfig));
142
+ i++;
143
+ }
144
+ if (updates.firewallConfig !== void 0) {
145
+ fields.push(`firewall_config = $${i}`);
146
+ values.push(JSON.stringify(updates.firewallConfig));
147
+ i++;
148
+ }
149
+ if (updates.modelPricingConfig !== void 0) {
150
+ fields.push(`model_pricing_config = $${i}`);
151
+ values.push(JSON.stringify(updates.modelPricingConfig));
152
+ i++;
153
+ }
154
+ fields.push(`updated_at = NOW()`);
155
+ values.push("default");
156
+ const { rows } = await this.pool.query(
157
+ `UPDATE company_settings SET ${fields.join(", ")} WHERE id = $${i} RETURNING *`,
158
+ values
159
+ );
160
+ return this.mapSettings(rows[0]);
161
+ }
162
+ // ─── Agents ──────────────────────────────────────────────
163
+ async createAgent(input) {
164
+ const id = input.id || randomUUID();
165
+ const email = input.email || `${input.name.toLowerCase().replace(/\s+/g, "-")}@localhost`;
166
+ const { rows } = await this.pool.query(
167
+ `INSERT INTO agents (id, name, email, role, metadata, created_by)
168
+ VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`,
169
+ [id, input.name, email, input.role || "assistant", JSON.stringify(input.metadata || {}), input.createdBy]
170
+ );
171
+ return this.mapAgent(rows[0]);
172
+ }
173
+ async getAgent(id) {
174
+ const { rows } = await this.pool.query("SELECT * FROM agents WHERE id = $1", [id]);
175
+ return rows[0] ? this.mapAgent(rows[0]) : null;
176
+ }
177
+ async getAgentByName(name) {
178
+ const { rows } = await this.pool.query("SELECT * FROM agents WHERE name = $1", [name]);
179
+ return rows[0] ? this.mapAgent(rows[0]) : null;
180
+ }
181
+ async listAgents(opts) {
182
+ let q = "SELECT * FROM agents";
183
+ const params = [];
184
+ if (opts?.status) {
185
+ q += " WHERE status = $1";
186
+ params.push(opts.status);
187
+ }
188
+ q += " ORDER BY created_at DESC";
189
+ if (opts?.limit) {
190
+ q += ` LIMIT ${opts.limit}`;
191
+ }
192
+ if (opts?.offset) {
193
+ q += ` OFFSET ${opts.offset}`;
194
+ }
195
+ const { rows } = await this.pool.query(q, params);
196
+ return rows.map((r) => this.mapAgent(r));
197
+ }
198
+ async updateAgent(id, updates) {
199
+ const fields = [];
200
+ const values = [];
201
+ let i = 1;
202
+ for (const [key, col] of Object.entries({ name: "name", email: "email", role: "role", status: "status" })) {
203
+ if (updates[key] !== void 0) {
204
+ fields.push(`${col} = $${i}`);
205
+ values.push(updates[key]);
206
+ i++;
207
+ }
208
+ }
209
+ if (updates.metadata) {
210
+ fields.push(`metadata = $${i}`);
211
+ values.push(JSON.stringify(updates.metadata));
212
+ i++;
213
+ }
214
+ fields.push("updated_at = NOW()");
215
+ values.push(id);
216
+ const { rows } = await this.pool.query(
217
+ `UPDATE agents SET ${fields.join(", ")} WHERE id = $${i} RETURNING *`,
218
+ values
219
+ );
220
+ return this.mapAgent(rows[0]);
221
+ }
222
+ async archiveAgent(id) {
223
+ await this.pool.query("UPDATE agents SET status = 'archived', updated_at = NOW() WHERE id = $1", [id]);
224
+ }
225
+ async deleteAgent(id) {
226
+ await this.pool.query("DELETE FROM agents WHERE id = $1", [id]);
227
+ }
228
+ async countAgents(status) {
229
+ const q = status ? await this.pool.query("SELECT COUNT(*) FROM agents WHERE status = $1", [status]) : await this.pool.query("SELECT COUNT(*) FROM agents");
230
+ return parseInt(q.rows[0].count, 10);
231
+ }
232
+ // ─── Users ───────────────────────────────────────────────
233
+ async createUser(input) {
234
+ const id = randomUUID();
235
+ let passwordHash = null;
236
+ if (input.password) {
237
+ const { default: bcrypt } = await import("bcryptjs");
238
+ passwordHash = await bcrypt.hash(input.password, 12);
239
+ }
240
+ const { rows } = await this.pool.query(
241
+ `INSERT INTO users (id, email, name, role, password_hash, sso_provider, sso_subject)
242
+ VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *`,
243
+ [id, input.email, input.name, input.role, passwordHash, input.ssoProvider || null, input.ssoSubject || null]
244
+ );
245
+ return this.mapUser(rows[0]);
246
+ }
247
+ async getUser(id) {
248
+ const { rows } = await this.pool.query("SELECT * FROM users WHERE id = $1", [id]);
249
+ return rows[0] ? this.mapUser(rows[0]) : null;
250
+ }
251
+ async getUserByEmail(email) {
252
+ const { rows } = await this.pool.query("SELECT * FROM users WHERE email = $1", [email]);
253
+ return rows[0] ? this.mapUser(rows[0]) : null;
254
+ }
255
+ async getUserBySso(provider, subject) {
256
+ const { rows } = await this.pool.query(
257
+ "SELECT * FROM users WHERE sso_provider = $1 AND sso_subject = $2",
258
+ [provider, subject]
259
+ );
260
+ return rows[0] ? this.mapUser(rows[0]) : null;
261
+ }
262
+ async listUsers(opts) {
263
+ let q = "SELECT * FROM users ORDER BY created_at DESC";
264
+ if (opts?.limit) q += ` LIMIT ${opts.limit}`;
265
+ if (opts?.offset) q += ` OFFSET ${opts.offset}`;
266
+ const { rows } = await this.pool.query(q);
267
+ return rows.map((r) => this.mapUser(r));
268
+ }
269
+ async updateUser(id, updates) {
270
+ const fields = [];
271
+ const values = [];
272
+ let i = 1;
273
+ for (const key of ["email", "name", "role", "sso_provider", "sso_subject"]) {
274
+ const camelKey = key.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
275
+ if (updates[camelKey] !== void 0) {
276
+ fields.push(`${key} = $${i}`);
277
+ values.push(updates[camelKey]);
278
+ i++;
279
+ }
280
+ }
281
+ fields.push("updated_at = NOW()");
282
+ values.push(id);
283
+ const { rows } = await this.pool.query(
284
+ `UPDATE users SET ${fields.join(", ")} WHERE id = $${i} RETURNING *`,
285
+ values
286
+ );
287
+ return this.mapUser(rows[0]);
288
+ }
289
+ async deleteUser(id) {
290
+ await this.pool.query("DELETE FROM users WHERE id = $1", [id]);
291
+ }
292
+ // ─── Audit ───────────────────────────────────────────────
293
+ async logEvent(event) {
294
+ await this.pool.query(
295
+ `INSERT INTO audit_log (id, actor, actor_type, action, resource, details, ip)
296
+ VALUES ($1, $2, $3, $4, $5, $6, $7)`,
297
+ [
298
+ randomUUID(),
299
+ event.actor,
300
+ event.actorType,
301
+ event.action,
302
+ event.resource,
303
+ JSON.stringify(event.details || {}),
304
+ event.ip || null
305
+ ]
306
+ );
307
+ }
308
+ async queryAudit(filters) {
309
+ const where = [];
310
+ const params = [];
311
+ let i = 1;
312
+ if (filters.actor) {
313
+ where.push(`actor = $${i++}`);
314
+ params.push(filters.actor);
315
+ }
316
+ if (filters.action) {
317
+ where.push(`action = $${i++}`);
318
+ params.push(filters.action);
319
+ }
320
+ if (filters.resource) {
321
+ where.push(`resource LIKE $${i++}`);
322
+ params.push(`%${filters.resource}%`);
323
+ }
324
+ if (filters.from) {
325
+ where.push(`timestamp >= $${i++}`);
326
+ params.push(filters.from);
327
+ }
328
+ if (filters.to) {
329
+ where.push(`timestamp <= $${i++}`);
330
+ params.push(filters.to);
331
+ }
332
+ const whereClause = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
333
+ const countResult = await this.pool.query(`SELECT COUNT(*) FROM audit_log ${whereClause}`, params);
334
+ const total = parseInt(countResult.rows[0].count, 10);
335
+ let q = `SELECT * FROM audit_log ${whereClause} ORDER BY timestamp DESC`;
336
+ if (filters.limit) q += ` LIMIT ${filters.limit}`;
337
+ if (filters.offset) q += ` OFFSET ${filters.offset}`;
338
+ const { rows } = await this.pool.query(q, params);
339
+ return {
340
+ events: rows.map((r) => ({
341
+ id: r.id,
342
+ timestamp: r.timestamp,
343
+ actor: r.actor,
344
+ actorType: r.actor_type,
345
+ action: r.action,
346
+ resource: r.resource,
347
+ details: JSON.parse(r.details || "{}"),
348
+ ip: r.ip
349
+ })),
350
+ total
351
+ };
352
+ }
353
+ // ─── API Keys ────────────────────────────────────────────
354
+ async createApiKey(input) {
355
+ const id = randomUUID();
356
+ const plaintext = `ek_${randomUUID().replace(/-/g, "")}`;
357
+ const keyHash = createHash("sha256").update(plaintext).digest("hex");
358
+ const keyPrefix = plaintext.substring(0, 11);
359
+ const { rows } = await this.pool.query(
360
+ `INSERT INTO api_keys (id, name, key_hash, key_prefix, scopes, created_by, expires_at)
361
+ VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *`,
362
+ [id, input.name, keyHash, keyPrefix, JSON.stringify(input.scopes), input.createdBy, input.expiresAt || null]
363
+ );
364
+ return { key: this.mapApiKey(rows[0]), plaintext };
365
+ }
366
+ async getApiKey(id) {
367
+ const { rows } = await this.pool.query("SELECT * FROM api_keys WHERE id = $1", [id]);
368
+ return rows[0] ? this.mapApiKey(rows[0]) : null;
369
+ }
370
+ async validateApiKey(plaintext) {
371
+ const keyHash = createHash("sha256").update(plaintext).digest("hex");
372
+ const { rows } = await this.pool.query(
373
+ "SELECT * FROM api_keys WHERE key_hash = $1 AND revoked = 0",
374
+ [keyHash]
375
+ );
376
+ if (!rows[0]) return null;
377
+ const key = this.mapApiKey(rows[0]);
378
+ if (key.expiresAt && /* @__PURE__ */ new Date() > key.expiresAt) return null;
379
+ await this.pool.query("UPDATE api_keys SET last_used_at = NOW() WHERE id = $1", [key.id]);
380
+ return key;
381
+ }
382
+ async listApiKeys(opts) {
383
+ let q = "SELECT * FROM api_keys";
384
+ const params = [];
385
+ if (opts?.createdBy) {
386
+ q += " WHERE created_by = $1";
387
+ params.push(opts.createdBy);
388
+ }
389
+ q += " ORDER BY created_at DESC";
390
+ const { rows } = await this.pool.query(q, params);
391
+ return rows.map((r) => this.mapApiKey(r));
392
+ }
393
+ async revokeApiKey(id) {
394
+ await this.pool.query("UPDATE api_keys SET revoked = 1 WHERE id = $1", [id]);
395
+ }
396
+ // ─── Rules ───────────────────────────────────────────────
397
+ async createRule(rule) {
398
+ const id = randomUUID();
399
+ const { rows } = await this.pool.query(
400
+ `INSERT INTO email_rules (id, name, agent_id, conditions, actions, priority, enabled)
401
+ VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *`,
402
+ [
403
+ id,
404
+ rule.name,
405
+ rule.agentId || null,
406
+ JSON.stringify(rule.conditions),
407
+ JSON.stringify(rule.actions),
408
+ rule.priority,
409
+ rule.enabled ? 1 : 0
410
+ ]
411
+ );
412
+ return this.mapRule(rows[0]);
413
+ }
414
+ async getRules(agentId) {
415
+ let q = "SELECT * FROM email_rules";
416
+ const params = [];
417
+ if (agentId) {
418
+ q += " WHERE agent_id = $1 OR agent_id IS NULL";
419
+ params.push(agentId);
420
+ }
421
+ q += " ORDER BY priority DESC";
422
+ const { rows } = await this.pool.query(q, params);
423
+ return rows.map((r) => this.mapRule(r));
424
+ }
425
+ async updateRule(id, updates) {
426
+ const fields = [];
427
+ const values = [];
428
+ let i = 1;
429
+ if (updates.name !== void 0) {
430
+ fields.push(`name = $${i++}`);
431
+ values.push(updates.name);
432
+ }
433
+ if (updates.conditions) {
434
+ fields.push(`conditions = $${i++}`);
435
+ values.push(JSON.stringify(updates.conditions));
436
+ }
437
+ if (updates.actions) {
438
+ fields.push(`actions = $${i++}`);
439
+ values.push(JSON.stringify(updates.actions));
440
+ }
441
+ if (updates.priority !== void 0) {
442
+ fields.push(`priority = $${i++}`);
443
+ values.push(updates.priority);
444
+ }
445
+ if (updates.enabled !== void 0) {
446
+ fields.push(`enabled = $${i++}`);
447
+ values.push(updates.enabled ? 1 : 0);
448
+ }
449
+ fields.push("updated_at = NOW()");
450
+ values.push(id);
451
+ const { rows } = await this.pool.query(
452
+ `UPDATE email_rules SET ${fields.join(", ")} WHERE id = $${i} RETURNING *`,
453
+ values
454
+ );
455
+ return this.mapRule(rows[0]);
456
+ }
457
+ async deleteRule(id) {
458
+ await this.pool.query("DELETE FROM email_rules WHERE id = $1", [id]);
459
+ }
460
+ // ─── Retention ───────────────────────────────────────────
461
+ async getRetentionPolicy() {
462
+ const { rows } = await this.pool.query("SELECT * FROM retention_policy WHERE id = $1", ["default"]);
463
+ if (!rows[0]) return { enabled: false, retainDays: 365, archiveFirst: true };
464
+ return {
465
+ enabled: !!rows[0].enabled,
466
+ retainDays: rows[0].retain_days,
467
+ excludeTags: JSON.parse(rows[0].exclude_tags || "[]"),
468
+ archiveFirst: !!rows[0].archive_first
469
+ };
470
+ }
471
+ async setRetentionPolicy(policy) {
472
+ await this.pool.query(
473
+ `UPDATE retention_policy SET enabled = $1, retain_days = $2, exclude_tags = $3, archive_first = $4
474
+ WHERE id = 'default'`,
475
+ [policy.enabled ? 1 : 0, policy.retainDays, JSON.stringify(policy.excludeTags || []), policy.archiveFirst ? 1 : 0]
476
+ );
477
+ }
478
+ // ─── Stats ───────────────────────────────────────────────
479
+ async getStats() {
480
+ const [agents, active, users, audit] = await Promise.all([
481
+ this.pool.query("SELECT COUNT(*) FROM agents"),
482
+ this.pool.query("SELECT COUNT(*) FROM agents WHERE status = 'active'"),
483
+ this.pool.query("SELECT COUNT(*) FROM users"),
484
+ this.pool.query("SELECT COUNT(*) FROM audit_log")
485
+ ]);
486
+ return {
487
+ totalAgents: parseInt(agents.rows[0].count, 10),
488
+ activeAgents: parseInt(active.rows[0].count, 10),
489
+ totalUsers: parseInt(users.rows[0].count, 10),
490
+ totalEmails: 0,
491
+ // TODO: wire to email storage
492
+ totalAuditEvents: parseInt(audit.rows[0].count, 10)
493
+ };
494
+ }
495
+ // ─── Mappers ─────────────────────────────────────────────
496
+ mapAgent(r) {
497
+ return {
498
+ id: r.id,
499
+ name: r.name,
500
+ email: r.email,
501
+ role: r.role,
502
+ status: r.status,
503
+ metadata: typeof r.metadata === "string" ? JSON.parse(r.metadata) : r.metadata,
504
+ createdAt: new Date(r.created_at),
505
+ updatedAt: new Date(r.updated_at),
506
+ createdBy: r.created_by
507
+ };
508
+ }
509
+ mapUser(r) {
510
+ return {
511
+ id: r.id,
512
+ email: r.email,
513
+ name: r.name,
514
+ role: r.role,
515
+ passwordHash: r.password_hash,
516
+ ssoProvider: r.sso_provider,
517
+ ssoSubject: r.sso_subject,
518
+ createdAt: new Date(r.created_at),
519
+ updatedAt: new Date(r.updated_at),
520
+ lastLoginAt: r.last_login_at ? new Date(r.last_login_at) : void 0
521
+ };
522
+ }
523
+ mapApiKey(r) {
524
+ return {
525
+ id: r.id,
526
+ name: r.name,
527
+ keyHash: r.key_hash,
528
+ keyPrefix: r.key_prefix,
529
+ scopes: typeof r.scopes === "string" ? JSON.parse(r.scopes) : r.scopes,
530
+ createdBy: r.created_by,
531
+ createdAt: new Date(r.created_at),
532
+ lastUsedAt: r.last_used_at ? new Date(r.last_used_at) : void 0,
533
+ expiresAt: r.expires_at ? new Date(r.expires_at) : void 0,
534
+ revoked: !!r.revoked
535
+ };
536
+ }
537
+ mapRule(r) {
538
+ return {
539
+ id: r.id,
540
+ name: r.name,
541
+ agentId: r.agent_id,
542
+ conditions: typeof r.conditions === "string" ? JSON.parse(r.conditions) : r.conditions,
543
+ actions: typeof r.actions === "string" ? JSON.parse(r.actions) : r.actions,
544
+ priority: r.priority,
545
+ enabled: !!r.enabled,
546
+ createdAt: new Date(r.created_at),
547
+ updatedAt: new Date(r.updated_at)
548
+ };
549
+ }
550
+ mapSettings(r) {
551
+ return {
552
+ id: r.id,
553
+ name: r.name,
554
+ domain: r.domain,
555
+ subdomain: r.subdomain,
556
+ smtpHost: r.smtp_host,
557
+ smtpPort: r.smtp_port,
558
+ smtpUser: r.smtp_user,
559
+ smtpPass: r.smtp_pass,
560
+ dkimPrivateKey: r.dkim_private_key,
561
+ logoUrl: r.logo_url,
562
+ primaryColor: r.primary_color,
563
+ ssoConfig: r.sso_config ? typeof r.sso_config === "string" ? JSON.parse(r.sso_config) : r.sso_config : void 0,
564
+ toolSecurityConfig: r.tool_security_config ? typeof r.tool_security_config === "string" ? JSON.parse(r.tool_security_config) : r.tool_security_config : {},
565
+ firewallConfig: r.firewall_config ? typeof r.firewall_config === "string" ? JSON.parse(r.firewall_config) : r.firewall_config : {},
566
+ modelPricingConfig: r.model_pricing_config ? typeof r.model_pricing_config === "string" ? JSON.parse(r.model_pricing_config) : r.model_pricing_config : {},
567
+ plan: r.plan,
568
+ createdAt: new Date(r.created_at),
569
+ updatedAt: new Date(r.updated_at),
570
+ deploymentKeyHash: r.deployment_key_hash,
571
+ domainRegistrationId: r.domain_registration_id,
572
+ domainDnsChallenge: r.domain_dns_challenge,
573
+ domainVerifiedAt: r.domain_verified_at || void 0,
574
+ domainRegisteredAt: r.domain_registered_at || void 0,
575
+ domainStatus: r.domain_status || "unregistered"
576
+ };
577
+ }
578
+ };
579
+ export {
580
+ PostgresAdapter
581
+ };
@@ -0,0 +1,11 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-AXLDCUI7.js";
4
+ import "./chunk-ZNR5DDTA.js";
5
+ import "./chunk-RO537U6H.js";
6
+ import "./chunk-DRXMYYKN.js";
7
+ import "./chunk-JLSQOQ5L.js";
8
+ import "./chunk-KFQGP6VL.js";
9
+ export {
10
+ createServer
11
+ };
@@ -0,0 +1,11 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-ECBK6SB7.js";
4
+ import "./chunk-ZNR5DDTA.js";
5
+ import "./chunk-RO537U6H.js";
6
+ import "./chunk-DRXMYYKN.js";
7
+ import "./chunk-JLSQOQ5L.js";
8
+ import "./chunk-KFQGP6VL.js";
9
+ export {
10
+ createServer
11
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-77T3UAIL.js";
10
+ import "./chunk-FM7SWVJG.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-WOJ47LRQ.js";
10
+ import "./chunk-6TDW6ZNI.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -62,14 +62,19 @@ export class PostgresAdapter extends DatabaseAdapter {
62
62
  getEngineDB() {
63
63
  if (!this.pool) return null;
64
64
  const pool = this.pool;
65
+ // Convert ? placeholders to $1, $2, ... for pg driver
66
+ const pgSql = (sql: string) => {
67
+ let i = 0;
68
+ return sql.replace(/\?/g, () => `$${++i}`);
69
+ };
65
70
  return {
66
- run: async (sql: string, params?: any[]) => { await pool.query(sql, params); },
71
+ run: async (sql: string, params?: any[]) => { await pool.query(pgSql(sql), params); },
67
72
  get: async <T = any>(sql: string, params?: any[]): Promise<T | undefined> => {
68
- const result = await pool.query(sql, params);
73
+ const result = await pool.query(pgSql(sql), params);
69
74
  return result.rows[0] as T | undefined;
70
75
  },
71
76
  all: async <T = any>(sql: string, params?: any[]): Promise<T[]> => {
72
- const result = await pool.query(sql, params);
77
+ const result = await pool.query(pgSql(sql), params);
73
78
  return result.rows as T[];
74
79
  },
75
80
  };
@@ -111,6 +116,12 @@ export class PostgresAdapter extends DatabaseAdapter {
111
116
  }
112
117
 
113
118
  async updateSettings(updates: Partial<CompanySettings>): Promise<CompanySettings> {
119
+ // Ensure default row exists first
120
+ await this.pool.query(
121
+ `INSERT INTO company_settings (id, name, subdomain) VALUES ('default', '', '')
122
+ ON CONFLICT (id) DO NOTHING`
123
+ );
124
+
114
125
  const fields: string[] = [];
115
126
  const values: any[] = [];
116
127
  let i = 1;