@contentgrowth/content-emailing 0.7.5 → 0.7.7
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.
- package/dist/backend/EmailService.cjs +19 -0
- package/dist/backend/EmailService.cjs.map +1 -1
- package/dist/backend/EmailService.d.cts +2 -0
- package/dist/backend/EmailService.d.ts +2 -0
- package/dist/backend/EmailService.js +19 -0
- package/dist/backend/EmailService.js.map +1 -1
- package/dist/backend/index.cjs +139 -46
- package/dist/backend/index.cjs.map +1 -1
- package/dist/backend/index.d.cts +1 -0
- package/dist/backend/index.d.ts +1 -0
- package/dist/backend/index.js +139 -46
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/routes/index.cjs +174 -47
- package/dist/backend/routes/index.cjs.map +1 -1
- package/dist/backend/routes/index.d.cts +23 -6
- package/dist/backend/routes/index.d.ts +23 -6
- package/dist/backend/routes/index.js +172 -47
- package/dist/backend/routes/index.js.map +1 -1
- package/dist/index.cjs +139 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +139 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/backend/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ __export(backend_exports, {
|
|
|
35
35
|
createDOCacheProvider: () => createDOCacheProvider,
|
|
36
36
|
createEmailLoggerCallback: () => createEmailLoggerCallback,
|
|
37
37
|
createEmailRoutes: () => createEmailRoutes,
|
|
38
|
-
createTemplateRoutes: () =>
|
|
38
|
+
createTemplateRoutes: () => createTemplateRoutes2,
|
|
39
39
|
createTrackingRoutes: () => createTrackingRoutes,
|
|
40
40
|
encodeTrackingLinks: () => encodeTrackingLinks,
|
|
41
41
|
extractVariables: () => extractVariables,
|
|
@@ -814,6 +814,9 @@ var EmailService = class {
|
|
|
814
814
|
// Updater function to save settings to backend
|
|
815
815
|
// Signature: async (profile, tenantId, settings) => void
|
|
816
816
|
settingsUpdater: config.settingsUpdater || null,
|
|
817
|
+
// Settings configuration
|
|
818
|
+
settingsTableName: config.settingsTableName || "system_settings",
|
|
819
|
+
settingsKeyPrefix: config.settingsKeyPrefix || "system_email.",
|
|
817
820
|
// Branding configuration for email templates
|
|
818
821
|
branding: {
|
|
819
822
|
brandName: config.branding?.brandName || "Your App",
|
|
@@ -862,6 +865,22 @@ var EmailService = class {
|
|
|
862
865
|
console.warn("[EmailService] settingsLoader failed:", e);
|
|
863
866
|
}
|
|
864
867
|
}
|
|
868
|
+
if (!settings && profile === "system" && this.db) {
|
|
869
|
+
try {
|
|
870
|
+
const tableName = this.config.settingsTableName;
|
|
871
|
+
const prefix = this.config.settingsKeyPrefix;
|
|
872
|
+
const { results } = await this.db.prepare(`SELECT * FROM ${tableName} WHERE key LIKE ?`).bind(`${prefix}%`).all();
|
|
873
|
+
if (results && results.length > 0) {
|
|
874
|
+
settings = {};
|
|
875
|
+
for (const row of results) {
|
|
876
|
+
const cleanKey = row.key.slice(prefix.length);
|
|
877
|
+
settings[cleanKey] = row.value;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
} catch (e) {
|
|
881
|
+
console.warn("[EmailService] Failed to load settings from DB:", e.message);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
865
884
|
if (settings) {
|
|
866
885
|
if (this.cache && this.cache.putSettings) {
|
|
867
886
|
try {
|
|
@@ -1392,82 +1411,148 @@ var EmailService = class {
|
|
|
1392
1411
|
};
|
|
1393
1412
|
|
|
1394
1413
|
// src/backend/routes/index.js
|
|
1395
|
-
var
|
|
1414
|
+
var import_hono5 = require("hono");
|
|
1396
1415
|
|
|
1397
|
-
// src/backend/routes/
|
|
1416
|
+
// src/backend/routes/settings.js
|
|
1398
1417
|
var import_hono = require("hono");
|
|
1399
|
-
function
|
|
1418
|
+
function createSettingsRoutes(config = {}) {
|
|
1400
1419
|
const app = new import_hono.Hono();
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1420
|
+
const tableName = config.tableName || "system_settings";
|
|
1421
|
+
const keyPrefix = config.keyPrefix || "system_email.";
|
|
1422
|
+
const getSettings = async (db) => {
|
|
1423
|
+
try {
|
|
1424
|
+
const { results } = await db.prepare(`SELECT * FROM ${tableName} WHERE key LIKE ?`).bind(`${keyPrefix}%`).all();
|
|
1425
|
+
const settings = {};
|
|
1426
|
+
for (const row of results) {
|
|
1427
|
+
const cleanKey = row.key.slice(keyPrefix.length);
|
|
1428
|
+
settings[cleanKey] = row.value;
|
|
1429
|
+
}
|
|
1430
|
+
return settings;
|
|
1431
|
+
} catch (e) {
|
|
1432
|
+
console.warn(`[Settings] Failed to fetch from ${tableName}:`, e.message);
|
|
1433
|
+
return {};
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
app.get("/", async (c) => {
|
|
1437
|
+
try {
|
|
1438
|
+
const settings = await getSettings(c.env.DB);
|
|
1439
|
+
return c.json(settings);
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
console.error("Failed to fetch settings:", error);
|
|
1442
|
+
return c.json({ error: error.message }, 500);
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
app.post("/", async (c) => {
|
|
1446
|
+
try {
|
|
1447
|
+
const body = await c.req.json();
|
|
1448
|
+
const db = c.env.DB;
|
|
1449
|
+
const updates = Object.entries(body).map(([k, v]) => ({
|
|
1450
|
+
key: `${keyPrefix}${k}`,
|
|
1451
|
+
value: v
|
|
1452
|
+
}));
|
|
1453
|
+
if (updates.length === 0) return c.json({ success: true });
|
|
1454
|
+
const stmt = db.prepare(`
|
|
1455
|
+
INSERT INTO ${tableName} (key, value, updated_at)
|
|
1456
|
+
VALUES (?, ?, strftime('%s', 'now'))
|
|
1457
|
+
ON CONFLICT(key) DO UPDATE SET
|
|
1458
|
+
value = excluded.value,
|
|
1459
|
+
updated_at = excluded.updated_at
|
|
1460
|
+
`);
|
|
1461
|
+
const batch = updates.map((u) => stmt.bind(u.key, u.value === void 0 || u.value === null ? "" : String(u.value)));
|
|
1462
|
+
await db.batch(batch);
|
|
1463
|
+
return c.json({ success: true });
|
|
1464
|
+
} catch (error) {
|
|
1465
|
+
console.error("Failed to save settings:", error);
|
|
1466
|
+
return c.json({ error: error.message }, 500);
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
return app;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
// src/backend/routes/templates.js
|
|
1473
|
+
var import_hono2 = require("hono");
|
|
1474
|
+
function createTemplateRoutes2(config = {}) {
|
|
1475
|
+
const app = new import_hono2.Hono();
|
|
1476
|
+
app.get("/", async (c) => {
|
|
1477
|
+
const emailService = new EmailService(c.env, config);
|
|
1403
1478
|
try {
|
|
1404
1479
|
const templates = await emailService.getAllTemplates();
|
|
1405
|
-
return c.json(
|
|
1480
|
+
return c.json(templates);
|
|
1406
1481
|
} catch (err) {
|
|
1407
|
-
return c.json({
|
|
1482
|
+
return c.json({ error: err.message }, 500);
|
|
1408
1483
|
}
|
|
1409
1484
|
});
|
|
1410
|
-
app.get("
|
|
1485
|
+
app.get("/:id", async (c) => {
|
|
1486
|
+
const emailService = new EmailService(c.env, config);
|
|
1411
1487
|
try {
|
|
1412
1488
|
const template = await emailService.getTemplate(c.req.param("id"));
|
|
1413
|
-
if (!template) return c.json({
|
|
1414
|
-
return c.json(
|
|
1489
|
+
if (!template) return c.json({ error: "Template not found" }, 404);
|
|
1490
|
+
return c.json(template);
|
|
1415
1491
|
} catch (err) {
|
|
1416
|
-
return c.json({
|
|
1492
|
+
return c.json({ error: err.message }, 500);
|
|
1417
1493
|
}
|
|
1418
1494
|
});
|
|
1419
|
-
app.post("/
|
|
1495
|
+
app.post("/", async (c) => {
|
|
1496
|
+
const emailService = new EmailService(c.env, config);
|
|
1420
1497
|
try {
|
|
1421
1498
|
const data = await c.req.json();
|
|
1422
|
-
|
|
1423
|
-
|
|
1499
|
+
let userId = "admin";
|
|
1500
|
+
const user = c.get("dbUser") || c.get("user");
|
|
1501
|
+
if (user && user.id) userId = user.id;
|
|
1502
|
+
if (!data.template_id || !data.subject_template) {
|
|
1503
|
+
return c.json({ error: "Missing required fields (template_id, subject_template)" }, 400);
|
|
1504
|
+
}
|
|
1505
|
+
const result = await emailService.saveTemplate(data, userId);
|
|
1506
|
+
return c.json({ success: true, message: "Template saved", result });
|
|
1507
|
+
} catch (err) {
|
|
1508
|
+
return c.json({ error: err.message }, 500);
|
|
1509
|
+
}
|
|
1510
|
+
});
|
|
1511
|
+
app.post("/send-test", async (c) => {
|
|
1512
|
+
const emailService = new EmailService(c.env, config);
|
|
1513
|
+
try {
|
|
1514
|
+
const { template_id, to, variables } = await c.req.json();
|
|
1515
|
+
let tid = template_id;
|
|
1516
|
+
if (!tid || !to) {
|
|
1517
|
+
return c.json({ error: "Missing required fields (template_id, to)" }, 400);
|
|
1518
|
+
}
|
|
1519
|
+
const user = c.get("dbUser") || c.get("user");
|
|
1520
|
+
const recipientUserId = user?.id || null;
|
|
1521
|
+
const result = await emailService.sendViaTemplate(tid, variables || {}, {
|
|
1522
|
+
to,
|
|
1523
|
+
profile: "test",
|
|
1524
|
+
recipientUserId
|
|
1525
|
+
});
|
|
1526
|
+
return c.json({ success: true, result });
|
|
1424
1527
|
} catch (err) {
|
|
1425
|
-
return c.json({
|
|
1528
|
+
return c.json({ error: `Failed to send test email: ${err.message}` }, 500);
|
|
1426
1529
|
}
|
|
1427
1530
|
});
|
|
1428
|
-
app.delete("
|
|
1531
|
+
app.delete("/:id", async (c) => {
|
|
1532
|
+
const emailService = new EmailService(c.env, config);
|
|
1429
1533
|
try {
|
|
1430
1534
|
await emailService.deleteTemplate(c.req.param("id"));
|
|
1431
1535
|
return c.json({ success: true, message: "Template deleted" });
|
|
1432
1536
|
} catch (err) {
|
|
1433
|
-
return c.json({
|
|
1537
|
+
return c.json({ error: err.message }, 500);
|
|
1434
1538
|
}
|
|
1435
1539
|
});
|
|
1436
|
-
app.post("
|
|
1540
|
+
app.post("/:id/preview", async (c) => {
|
|
1541
|
+
const emailService = new EmailService(c.env, config);
|
|
1437
1542
|
try {
|
|
1438
1543
|
const id = c.req.param("id");
|
|
1439
1544
|
const data = await c.req.json();
|
|
1440
1545
|
const result = await emailService.renderTemplate(id, data);
|
|
1441
1546
|
return c.json({ success: true, preview: result });
|
|
1442
1547
|
} catch (err) {
|
|
1443
|
-
return c.json({
|
|
1444
|
-
}
|
|
1445
|
-
});
|
|
1446
|
-
app.post("/templates/:id/test", async (c) => {
|
|
1447
|
-
try {
|
|
1448
|
-
const id = c.req.param("id");
|
|
1449
|
-
const { to, data } = await c.req.json();
|
|
1450
|
-
const { subject, html, plainText } = await emailService.renderTemplate(id, data);
|
|
1451
|
-
const result = await emailService.sendEmail({
|
|
1452
|
-
to,
|
|
1453
|
-
subject: `[TEST] ${subject}`,
|
|
1454
|
-
html,
|
|
1455
|
-
text: plainText
|
|
1456
|
-
});
|
|
1457
|
-
if (result.success) {
|
|
1458
|
-
return c.json({ success: true, message: "Test email sent" });
|
|
1459
|
-
} else {
|
|
1460
|
-
return c.json({ success: false, error: result.error }, 500);
|
|
1461
|
-
}
|
|
1462
|
-
} catch (err) {
|
|
1463
|
-
return c.json({ success: false, error: err.message }, 500);
|
|
1548
|
+
return c.json({ error: err.message }, 500);
|
|
1464
1549
|
}
|
|
1465
1550
|
});
|
|
1466
1551
|
return app;
|
|
1467
1552
|
}
|
|
1468
1553
|
|
|
1469
1554
|
// src/backend/routes/tracking.js
|
|
1470
|
-
var
|
|
1555
|
+
var import_hono3 = require("hono");
|
|
1471
1556
|
var TRACKING_PIXEL = new Uint8Array([
|
|
1472
1557
|
71,
|
|
1473
1558
|
73,
|
|
@@ -1513,7 +1598,7 @@ var TRACKING_PIXEL = new Uint8Array([
|
|
|
1513
1598
|
59
|
|
1514
1599
|
]);
|
|
1515
1600
|
function createTrackingRoutes(env, config = {}) {
|
|
1516
|
-
const app = new
|
|
1601
|
+
const app = new import_hono3.Hono();
|
|
1517
1602
|
const db = env.DB;
|
|
1518
1603
|
const tablePrefix = config.emailTablePrefix || config.tableNamePrefix || "system_email_";
|
|
1519
1604
|
app.get("/track/open/:token", async (c) => {
|
|
@@ -1641,11 +1726,19 @@ function createTrackingRoutes(env, config = {}) {
|
|
|
1641
1726
|
return app;
|
|
1642
1727
|
}
|
|
1643
1728
|
|
|
1729
|
+
// src/backend/routes/logs.js
|
|
1730
|
+
var import_hono4 = require("hono");
|
|
1731
|
+
|
|
1644
1732
|
// src/backend/routes/index.js
|
|
1645
|
-
function createEmailRoutes(
|
|
1646
|
-
const app = new
|
|
1647
|
-
app.route("/
|
|
1648
|
-
app.route("/
|
|
1733
|
+
function createEmailRoutes(config = {}, cacheProvider = null) {
|
|
1734
|
+
const app = new import_hono5.Hono();
|
|
1735
|
+
app.route("/templates", createTemplateRoutes(config, cacheProvider));
|
|
1736
|
+
app.route("/logs", createLogRoutes(config));
|
|
1737
|
+
app.route("/settings", createSettingsRoutes({
|
|
1738
|
+
...config,
|
|
1739
|
+
tableName: config.settingsTableName || "system_settings",
|
|
1740
|
+
keyPrefix: config.settingsKeyPrefix || "system_email."
|
|
1741
|
+
}));
|
|
1649
1742
|
return app;
|
|
1650
1743
|
}
|
|
1651
1744
|
|