@agenticmail/api 0.5.59 → 0.5.60

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 (2) hide show
  1. package/dist/index.js +41 -41
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -264,17 +264,17 @@ function createAccountRoutes(accountManager, db, config) {
264
264
  const router = Router2();
265
265
  const deletionService = new AgentDeletionService(db, accountManager, config);
266
266
  router.post("/accounts", requireMaster, async (req, res, next) => {
267
+ if (!req.body || typeof req.body !== "object") {
268
+ res.status(400).json({ error: "Request body must be JSON" });
269
+ return;
270
+ }
271
+ const { name: accountName, domain, password, metadata, role, persistent } = req.body;
267
272
  try {
268
- if (!req.body || typeof req.body !== "object") {
269
- res.status(400).json({ error: "Request body must be JSON" });
270
- return;
271
- }
272
- const { name: name2, domain, password, metadata, role, persistent } = req.body;
273
- if (!name2 || typeof name2 !== "string") {
273
+ if (!accountName || typeof accountName !== "string") {
274
274
  res.status(400).json({ error: "name is required and must be a string" });
275
275
  return;
276
276
  }
277
- if (name2.length > 64) {
277
+ if (accountName.length > 64) {
278
278
  res.status(400).json({ error: "name must be 64 characters or fewer" });
279
279
  return;
280
280
  }
@@ -293,7 +293,7 @@ function createAccountRoutes(accountManager, db, config) {
293
293
  const cleanMeta = metadata ? Object.fromEntries(
294
294
  Object.entries(metadata).filter(([k]) => !k.startsWith("_"))
295
295
  ) : void 0;
296
- const agent = await accountManager.create({ name: name2, domain, password: password || void 0, metadata: cleanMeta, role });
296
+ const agent = await accountManager.create({ name: accountName, domain, password: password || void 0, metadata: cleanMeta, role });
297
297
  try {
298
298
  db.prepare("UPDATE agents SET last_activity_at = datetime('now') WHERE id = ?").run(agent.id);
299
299
  } catch {
@@ -310,7 +310,7 @@ function createAccountRoutes(accountManager, db, config) {
310
310
  } catch (err) {
311
311
  const msg = err.message ?? "";
312
312
  if (msg.includes("UNIQUE") || msg.includes("unique") || msg.includes("already exists") || msg.includes("duplicate") || msg.includes("fieldAlreadyExists") || msg.toLowerCase().includes("alreadyexists")) {
313
- res.status(409).json({ error: "Account already exists", name });
313
+ res.status(409).json({ error: "Account already exists", name: accountName });
314
314
  return;
315
315
  }
316
316
  next(err);
@@ -644,13 +644,13 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
644
644
  });
645
645
  router.post("/contacts", requireAgent, async (req, res, next) => {
646
646
  try {
647
- const { name: name2, email, notes } = req.body || {};
647
+ const { name, email, notes } = req.body || {};
648
648
  if (!email) {
649
649
  res.status(400).json({ error: "email is required" });
650
650
  return;
651
651
  }
652
652
  const id = uuidv4();
653
- db.prepare("INSERT OR REPLACE INTO contacts (id, agent_id, name, email, notes) VALUES (?, ?, ?, ?, ?)").run(id, req.agent.id, name2 || null, email, notes || null);
653
+ db.prepare("INSERT OR REPLACE INTO contacts (id, agent_id, name, email, notes) VALUES (?, ?, ?, ?, ?)").run(id, req.agent.id, name || null, email, notes || null);
654
654
  res.json({ ok: true, id, email });
655
655
  } catch (err) {
656
656
  next(err);
@@ -795,8 +795,8 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
795
795
  });
796
796
  router.post("/signatures", requireAgent, async (req, res, next) => {
797
797
  try {
798
- const { name: name2, text, html, isDefault } = req.body || {};
799
- if (!name2) {
798
+ const { name, text, html, isDefault } = req.body || {};
799
+ if (!name) {
800
800
  res.status(400).json({ error: "name is required" });
801
801
  return;
802
802
  }
@@ -804,7 +804,7 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
804
804
  if (isDefault) {
805
805
  db.prepare("UPDATE signatures SET is_default = 0 WHERE agent_id = ?").run(req.agent.id);
806
806
  }
807
- db.prepare("INSERT OR REPLACE INTO signatures (id, agent_id, name, text_content, html_content, is_default) VALUES (?, ?, ?, ?, ?, ?)").run(id, req.agent.id, name2, text || null, html || null, isDefault ? 1 : 0);
807
+ db.prepare("INSERT OR REPLACE INTO signatures (id, agent_id, name, text_content, html_content, is_default) VALUES (?, ?, ?, ?, ?, ?)").run(id, req.agent.id, name, text || null, html || null, isDefault ? 1 : 0);
808
808
  res.json({ ok: true, id });
809
809
  } catch (err) {
810
810
  next(err);
@@ -832,13 +832,13 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
832
832
  });
833
833
  router.post("/templates", requireAgent, async (req, res, next) => {
834
834
  try {
835
- const { name: name2, subject, text, html } = req.body || {};
836
- if (!name2) {
835
+ const { name, subject, text, html } = req.body || {};
836
+ if (!name) {
837
837
  res.status(400).json({ error: "name is required" });
838
838
  return;
839
839
  }
840
840
  const id = uuidv4();
841
- db.prepare("INSERT OR REPLACE INTO templates (id, agent_id, name, subject, text_body, html_body) VALUES (?, ?, ?, ?, ?, ?)").run(id, req.agent.id, name2, subject || null, text || null, html || null);
841
+ db.prepare("INSERT OR REPLACE INTO templates (id, agent_id, name, subject, text_body, html_body) VALUES (?, ?, ?, ?, ?, ?)").run(id, req.agent.id, name, subject || null, text || null, html || null);
842
842
  res.json({ ok: true, id });
843
843
  } catch (err) {
844
844
  next(err);
@@ -912,14 +912,14 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
912
912
  });
913
913
  router.post("/tags", requireAgent, async (req, res, next) => {
914
914
  try {
915
- const { name: name2, color } = req.body || {};
916
- if (!name2) {
915
+ const { name, color } = req.body || {};
916
+ if (!name) {
917
917
  res.status(400).json({ error: "name is required" });
918
918
  return;
919
919
  }
920
920
  const id = uuidv4();
921
- db.prepare("INSERT OR IGNORE INTO tags (id, agent_id, name, color) VALUES (?, ?, ?, ?)").run(id, req.agent.id, name2.trim(), color || "#888888");
922
- res.json({ ok: true, id, name: name2.trim(), color: color || "#888888" });
921
+ db.prepare("INSERT OR IGNORE INTO tags (id, agent_id, name, color) VALUES (?, ?, ?, ?)").run(id, req.agent.id, name.trim(), color || "#888888");
922
+ res.json({ ok: true, id, name: name.trim(), color: color || "#888888" });
923
923
  } catch (err) {
924
924
  next(err);
925
925
  }
@@ -1049,16 +1049,16 @@ function createFeatureRoutes(db, _accountManager, config, gatewayManager) {
1049
1049
  });
1050
1050
  router.post("/rules", requireAgent, async (req, res, next) => {
1051
1051
  try {
1052
- const { name: name2, conditions, actions, priority, enabled } = req.body || {};
1053
- if (!name2) {
1052
+ const { name, conditions, actions, priority, enabled } = req.body || {};
1053
+ if (!name) {
1054
1054
  res.status(400).json({ error: "name is required" });
1055
1055
  return;
1056
1056
  }
1057
1057
  const id = uuidv4();
1058
1058
  db.prepare(
1059
1059
  "INSERT INTO email_rules (id, agent_id, name, priority, enabled, conditions, actions) VALUES (?, ?, ?, ?, ?, ?, ?)"
1060
- ).run(id, req.agent.id, name2, priority ?? 0, enabled !== false ? 1 : 0, JSON.stringify(conditions || {}), JSON.stringify(actions || {}));
1061
- res.status(201).json({ id, name: name2, conditions: conditions || {}, actions: actions || {}, priority: priority ?? 0, enabled: enabled !== false });
1060
+ ).run(id, req.agent.id, name, priority ?? 0, enabled !== false ? 1 : 0, JSON.stringify(conditions || {}), JSON.stringify(actions || {}));
1061
+ res.status(201).json({ id, name, conditions: conditions || {}, actions: actions || {}, priority: priority ?? 0, enabled: enabled !== false });
1062
1062
  } catch (err) {
1063
1063
  next(err);
1064
1064
  }
@@ -1988,19 +1988,19 @@ function createMailRoutes(accountManager, config, db, gatewayManager) {
1988
1988
  router.post("/mail/folders", requireAgent, async (req, res, next) => {
1989
1989
  try {
1990
1990
  const agent = req.agent;
1991
- const { name: name2 } = req.body || {};
1992
- if (!name2 || typeof name2 !== "string" || !name2.trim()) {
1991
+ const { name } = req.body || {};
1992
+ if (!name || typeof name !== "string" || !name.trim()) {
1993
1993
  res.status(400).json({ error: "name is required" });
1994
1994
  return;
1995
1995
  }
1996
- if (name2.length > 200 || /[\\*%]/.test(name2)) {
1996
+ if (name.length > 200 || /[\\*%]/.test(name)) {
1997
1997
  res.status(400).json({ error: "Invalid folder name" });
1998
1998
  return;
1999
1999
  }
2000
2000
  const password = getAgentPassword(agent);
2001
2001
  const receiver = await getReceiver(agent.stalwartPrincipal, password, config);
2002
- await receiver.createFolder(name2);
2003
- res.json({ ok: true, folder: name2 });
2002
+ await receiver.createFolder(name);
2003
+ res.json({ ok: true, folder: name });
2004
2004
  } catch (err) {
2005
2005
  next(err);
2006
2006
  }
@@ -3478,7 +3478,7 @@ function buildColumnDDL(col, dialect) {
3478
3478
  if (typeof col.default === "string") {
3479
3479
  const trimmed = col.default.trim();
3480
3480
  const isSqlExpr = /\(.*\)/.test(trimmed) || /^CURRENT_(?:TIMESTAMP|DATE|TIME)$/i.test(trimmed);
3481
- val = isSqlExpr ? trimmed : `'${col.default.replace(/'/g, "''")}'`;
3481
+ val = isSqlExpr ? `(${trimmed})` : `'${col.default.replace(/'/g, "''")}'`;
3482
3482
  } else {
3483
3483
  val = col.default;
3484
3484
  }
@@ -3491,15 +3491,15 @@ function buildColumnDDL(col, dialect) {
3491
3491
  }
3492
3492
  return ddl;
3493
3493
  }
3494
- function safeTableName(agentId, name2, shared) {
3495
- const clean = name2.replace(/[^a-zA-Z0-9_]/g, "").substring(0, 64);
3494
+ function safeTableName(agentId, name, shared) {
3495
+ const clean = name.replace(/[^a-zA-Z0-9_]/g, "").substring(0, 64);
3496
3496
  if (!clean) throw new Error("Invalid table name");
3497
3497
  const prefix = shared ? "shared" : `agt_${agentId.replace(/[^a-zA-Z0-9]/g, "").substring(0, 16)}`;
3498
3498
  return `${prefix}_${clean}`;
3499
3499
  }
3500
- function resolveTable(agentId, name2) {
3501
- if (name2.startsWith("agt_") || name2.startsWith("shared_")) return name2;
3502
- return safeTableName(agentId, name2, false);
3500
+ function resolveTable(agentId, name) {
3501
+ if (name.startsWith("agt_") || name.startsWith("shared_")) return name;
3502
+ return safeTableName(agentId, name, false);
3503
3503
  }
3504
3504
  function isSafeTable(tableName) {
3505
3505
  return tableName.startsWith("agt_") || tableName.startsWith("shared_");
@@ -3657,8 +3657,8 @@ function createStorageRoutes(rawDb, accountManager, config, dialect = "sqlite")
3657
3657
  if (!agent) return;
3658
3658
  await ensureMetaTable();
3659
3659
  try {
3660
- const { name: name2, columns, indexes, shared, description, timestamps } = req.body;
3661
- if (!name2 || !columns?.length) return res.status(400).json({ error: "name and columns are required" });
3660
+ const { name, columns, indexes, shared, description, timestamps } = req.body;
3661
+ if (!name || !columns?.length) return res.status(400).json({ error: "name and columns are required" });
3662
3662
  const hasPK = columns.some((c) => c.primaryKey);
3663
3663
  const allCols = [...hasPK ? [] : [{ name: "id", type: "text", primaryKey: true }], ...columns];
3664
3664
  if (timestamps !== false) {
@@ -3669,9 +3669,9 @@ function createStorageRoutes(rawDb, accountManager, config, dialect = "sqlite")
3669
3669
  allCols.push({ name: "updated_at", type: "timestamp", default: nowExpr(dialect) });
3670
3670
  }
3671
3671
  }
3672
- const tableName = safeTableName(agent.id, name2, !!shared);
3672
+ const tableName = safeTableName(agent.id, name, !!shared);
3673
3673
  const existing = await db.get("SELECT table_name FROM agenticmail_storage_meta WHERE table_name = ?", [tableName]);
3674
- if (existing) return res.status(409).json({ error: `Table "${name2}" already exists`, table: tableName });
3674
+ if (existing) return res.status(409).json({ error: `Table "${name}" already exists`, table: tableName });
3675
3675
  const colDefs = allCols.map((c) => buildColumnDDL(c, dialect)).join(",\n ");
3676
3676
  await db.run(`CREATE TABLE IF NOT EXISTS ${tableName} (
3677
3677
  ${colDefs}
@@ -3692,7 +3692,7 @@ function createStorageRoutes(rawDb, accountManager, config, dialect = "sqlite")
3692
3692
  }
3693
3693
  await db.run(
3694
3694
  "INSERT INTO agenticmail_storage_meta (table_name, agent_id, display_name, description, shared, columns, indexes) VALUES (?, ?, ?, ?, ?, ?, ?)",
3695
- [tableName, agent.id, name2, description || "", shared ? 1 : 0, JSON.stringify(allCols), JSON.stringify(idxMeta)]
3695
+ [tableName, agent.id, name, description || "", shared ? 1 : 0, JSON.stringify(allCols), JSON.stringify(idxMeta)]
3696
3696
  );
3697
3697
  res.json({ ok: true, table: tableName, columns: allCols, indexes: idxMeta });
3698
3698
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/api",
3
- "version": "0.5.59",
3
+ "version": "0.5.60",
4
4
  "description": "REST API server for AgenticMail — email and SMS endpoints for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",