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