@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.d.cts
CHANGED
|
@@ -6,3 +6,4 @@ export { createEmailRoutes, createTemplateRoutes, createTrackingRoutes } from '.
|
|
|
6
6
|
export { encodeTrackingLinks, extractVariables, getWebsiteUrl, markdownToPlainText, resetWebsiteUrlCache, wrapInEmailTemplate } from './common/index.cjs';
|
|
7
7
|
import 'react';
|
|
8
8
|
import 'hono';
|
|
9
|
+
import 'hono/types';
|
package/dist/index.d.ts
CHANGED
|
@@ -6,3 +6,4 @@ export { createEmailRoutes, createTemplateRoutes, createTrackingRoutes } from '.
|
|
|
6
6
|
export { encodeTrackingLinks, extractVariables, getWebsiteUrl, markdownToPlainText, resetWebsiteUrlCache, wrapInEmailTemplate } from './common/index.js';
|
|
7
7
|
import 'react';
|
|
8
8
|
import 'hono';
|
|
9
|
+
import 'hono/types';
|
package/dist/index.js
CHANGED
|
@@ -766,6 +766,9 @@ var EmailService = class {
|
|
|
766
766
|
// Updater function to save settings to backend
|
|
767
767
|
// Signature: async (profile, tenantId, settings) => void
|
|
768
768
|
settingsUpdater: config.settingsUpdater || null,
|
|
769
|
+
// Settings configuration
|
|
770
|
+
settingsTableName: config.settingsTableName || "system_settings",
|
|
771
|
+
settingsKeyPrefix: config.settingsKeyPrefix || "system_email.",
|
|
769
772
|
// Branding configuration for email templates
|
|
770
773
|
branding: {
|
|
771
774
|
brandName: config.branding?.brandName || "Your App",
|
|
@@ -814,6 +817,22 @@ var EmailService = class {
|
|
|
814
817
|
console.warn("[EmailService] settingsLoader failed:", e);
|
|
815
818
|
}
|
|
816
819
|
}
|
|
820
|
+
if (!settings && profile === "system" && this.db) {
|
|
821
|
+
try {
|
|
822
|
+
const tableName = this.config.settingsTableName;
|
|
823
|
+
const prefix = this.config.settingsKeyPrefix;
|
|
824
|
+
const { results } = await this.db.prepare(`SELECT * FROM ${tableName} WHERE key LIKE ?`).bind(`${prefix}%`).all();
|
|
825
|
+
if (results && results.length > 0) {
|
|
826
|
+
settings = {};
|
|
827
|
+
for (const row of results) {
|
|
828
|
+
const cleanKey = row.key.slice(prefix.length);
|
|
829
|
+
settings[cleanKey] = row.value;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
} catch (e) {
|
|
833
|
+
console.warn("[EmailService] Failed to load settings from DB:", e.message);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
817
836
|
if (settings) {
|
|
818
837
|
if (this.cache && this.cache.putSettings) {
|
|
819
838
|
try {
|
|
@@ -1344,82 +1363,148 @@ var EmailService = class {
|
|
|
1344
1363
|
};
|
|
1345
1364
|
|
|
1346
1365
|
// src/backend/routes/index.js
|
|
1347
|
-
import { Hono as
|
|
1366
|
+
import { Hono as Hono5 } from "hono";
|
|
1348
1367
|
|
|
1349
|
-
// src/backend/routes/
|
|
1368
|
+
// src/backend/routes/settings.js
|
|
1350
1369
|
import { Hono } from "hono";
|
|
1351
|
-
function
|
|
1370
|
+
function createSettingsRoutes(config = {}) {
|
|
1352
1371
|
const app = new Hono();
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1372
|
+
const tableName = config.tableName || "system_settings";
|
|
1373
|
+
const keyPrefix = config.keyPrefix || "system_email.";
|
|
1374
|
+
const getSettings = async (db) => {
|
|
1375
|
+
try {
|
|
1376
|
+
const { results } = await db.prepare(`SELECT * FROM ${tableName} WHERE key LIKE ?`).bind(`${keyPrefix}%`).all();
|
|
1377
|
+
const settings = {};
|
|
1378
|
+
for (const row of results) {
|
|
1379
|
+
const cleanKey = row.key.slice(keyPrefix.length);
|
|
1380
|
+
settings[cleanKey] = row.value;
|
|
1381
|
+
}
|
|
1382
|
+
return settings;
|
|
1383
|
+
} catch (e) {
|
|
1384
|
+
console.warn(`[Settings] Failed to fetch from ${tableName}:`, e.message);
|
|
1385
|
+
return {};
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
app.get("/", async (c) => {
|
|
1389
|
+
try {
|
|
1390
|
+
const settings = await getSettings(c.env.DB);
|
|
1391
|
+
return c.json(settings);
|
|
1392
|
+
} catch (error) {
|
|
1393
|
+
console.error("Failed to fetch settings:", error);
|
|
1394
|
+
return c.json({ error: error.message }, 500);
|
|
1395
|
+
}
|
|
1396
|
+
});
|
|
1397
|
+
app.post("/", async (c) => {
|
|
1398
|
+
try {
|
|
1399
|
+
const body = await c.req.json();
|
|
1400
|
+
const db = c.env.DB;
|
|
1401
|
+
const updates = Object.entries(body).map(([k, v]) => ({
|
|
1402
|
+
key: `${keyPrefix}${k}`,
|
|
1403
|
+
value: v
|
|
1404
|
+
}));
|
|
1405
|
+
if (updates.length === 0) return c.json({ success: true });
|
|
1406
|
+
const stmt = db.prepare(`
|
|
1407
|
+
INSERT INTO ${tableName} (key, value, updated_at)
|
|
1408
|
+
VALUES (?, ?, strftime('%s', 'now'))
|
|
1409
|
+
ON CONFLICT(key) DO UPDATE SET
|
|
1410
|
+
value = excluded.value,
|
|
1411
|
+
updated_at = excluded.updated_at
|
|
1412
|
+
`);
|
|
1413
|
+
const batch = updates.map((u) => stmt.bind(u.key, u.value === void 0 || u.value === null ? "" : String(u.value)));
|
|
1414
|
+
await db.batch(batch);
|
|
1415
|
+
return c.json({ success: true });
|
|
1416
|
+
} catch (error) {
|
|
1417
|
+
console.error("Failed to save settings:", error);
|
|
1418
|
+
return c.json({ error: error.message }, 500);
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
return app;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// src/backend/routes/templates.js
|
|
1425
|
+
import { Hono as Hono2 } from "hono";
|
|
1426
|
+
function createTemplateRoutes2(config = {}) {
|
|
1427
|
+
const app = new Hono2();
|
|
1428
|
+
app.get("/", async (c) => {
|
|
1429
|
+
const emailService = new EmailService(c.env, config);
|
|
1355
1430
|
try {
|
|
1356
1431
|
const templates = await emailService.getAllTemplates();
|
|
1357
|
-
return c.json(
|
|
1432
|
+
return c.json(templates);
|
|
1358
1433
|
} catch (err) {
|
|
1359
|
-
return c.json({
|
|
1434
|
+
return c.json({ error: err.message }, 500);
|
|
1360
1435
|
}
|
|
1361
1436
|
});
|
|
1362
|
-
app.get("
|
|
1437
|
+
app.get("/:id", async (c) => {
|
|
1438
|
+
const emailService = new EmailService(c.env, config);
|
|
1363
1439
|
try {
|
|
1364
1440
|
const template = await emailService.getTemplate(c.req.param("id"));
|
|
1365
|
-
if (!template) return c.json({
|
|
1366
|
-
return c.json(
|
|
1441
|
+
if (!template) return c.json({ error: "Template not found" }, 404);
|
|
1442
|
+
return c.json(template);
|
|
1367
1443
|
} catch (err) {
|
|
1368
|
-
return c.json({
|
|
1444
|
+
return c.json({ error: err.message }, 500);
|
|
1369
1445
|
}
|
|
1370
1446
|
});
|
|
1371
|
-
app.post("/
|
|
1447
|
+
app.post("/", async (c) => {
|
|
1448
|
+
const emailService = new EmailService(c.env, config);
|
|
1372
1449
|
try {
|
|
1373
1450
|
const data = await c.req.json();
|
|
1374
|
-
|
|
1375
|
-
|
|
1451
|
+
let userId = "admin";
|
|
1452
|
+
const user = c.get("dbUser") || c.get("user");
|
|
1453
|
+
if (user && user.id) userId = user.id;
|
|
1454
|
+
if (!data.template_id || !data.subject_template) {
|
|
1455
|
+
return c.json({ error: "Missing required fields (template_id, subject_template)" }, 400);
|
|
1456
|
+
}
|
|
1457
|
+
const result = await emailService.saveTemplate(data, userId);
|
|
1458
|
+
return c.json({ success: true, message: "Template saved", result });
|
|
1459
|
+
} catch (err) {
|
|
1460
|
+
return c.json({ error: err.message }, 500);
|
|
1461
|
+
}
|
|
1462
|
+
});
|
|
1463
|
+
app.post("/send-test", async (c) => {
|
|
1464
|
+
const emailService = new EmailService(c.env, config);
|
|
1465
|
+
try {
|
|
1466
|
+
const { template_id, to, variables } = await c.req.json();
|
|
1467
|
+
let tid = template_id;
|
|
1468
|
+
if (!tid || !to) {
|
|
1469
|
+
return c.json({ error: "Missing required fields (template_id, to)" }, 400);
|
|
1470
|
+
}
|
|
1471
|
+
const user = c.get("dbUser") || c.get("user");
|
|
1472
|
+
const recipientUserId = user?.id || null;
|
|
1473
|
+
const result = await emailService.sendViaTemplate(tid, variables || {}, {
|
|
1474
|
+
to,
|
|
1475
|
+
profile: "test",
|
|
1476
|
+
recipientUserId
|
|
1477
|
+
});
|
|
1478
|
+
return c.json({ success: true, result });
|
|
1376
1479
|
} catch (err) {
|
|
1377
|
-
return c.json({
|
|
1480
|
+
return c.json({ error: `Failed to send test email: ${err.message}` }, 500);
|
|
1378
1481
|
}
|
|
1379
1482
|
});
|
|
1380
|
-
app.delete("
|
|
1483
|
+
app.delete("/:id", async (c) => {
|
|
1484
|
+
const emailService = new EmailService(c.env, config);
|
|
1381
1485
|
try {
|
|
1382
1486
|
await emailService.deleteTemplate(c.req.param("id"));
|
|
1383
1487
|
return c.json({ success: true, message: "Template deleted" });
|
|
1384
1488
|
} catch (err) {
|
|
1385
|
-
return c.json({
|
|
1489
|
+
return c.json({ error: err.message }, 500);
|
|
1386
1490
|
}
|
|
1387
1491
|
});
|
|
1388
|
-
app.post("
|
|
1492
|
+
app.post("/:id/preview", async (c) => {
|
|
1493
|
+
const emailService = new EmailService(c.env, config);
|
|
1389
1494
|
try {
|
|
1390
1495
|
const id = c.req.param("id");
|
|
1391
1496
|
const data = await c.req.json();
|
|
1392
1497
|
const result = await emailService.renderTemplate(id, data);
|
|
1393
1498
|
return c.json({ success: true, preview: result });
|
|
1394
1499
|
} catch (err) {
|
|
1395
|
-
return c.json({
|
|
1396
|
-
}
|
|
1397
|
-
});
|
|
1398
|
-
app.post("/templates/:id/test", async (c) => {
|
|
1399
|
-
try {
|
|
1400
|
-
const id = c.req.param("id");
|
|
1401
|
-
const { to, data } = await c.req.json();
|
|
1402
|
-
const { subject, html, plainText } = await emailService.renderTemplate(id, data);
|
|
1403
|
-
const result = await emailService.sendEmail({
|
|
1404
|
-
to,
|
|
1405
|
-
subject: `[TEST] ${subject}`,
|
|
1406
|
-
html,
|
|
1407
|
-
text: plainText
|
|
1408
|
-
});
|
|
1409
|
-
if (result.success) {
|
|
1410
|
-
return c.json({ success: true, message: "Test email sent" });
|
|
1411
|
-
} else {
|
|
1412
|
-
return c.json({ success: false, error: result.error }, 500);
|
|
1413
|
-
}
|
|
1414
|
-
} catch (err) {
|
|
1415
|
-
return c.json({ success: false, error: err.message }, 500);
|
|
1500
|
+
return c.json({ error: err.message }, 500);
|
|
1416
1501
|
}
|
|
1417
1502
|
});
|
|
1418
1503
|
return app;
|
|
1419
1504
|
}
|
|
1420
1505
|
|
|
1421
1506
|
// src/backend/routes/tracking.js
|
|
1422
|
-
import { Hono as
|
|
1507
|
+
import { Hono as Hono3 } from "hono";
|
|
1423
1508
|
var TRACKING_PIXEL = new Uint8Array([
|
|
1424
1509
|
71,
|
|
1425
1510
|
73,
|
|
@@ -1465,7 +1550,7 @@ var TRACKING_PIXEL = new Uint8Array([
|
|
|
1465
1550
|
59
|
|
1466
1551
|
]);
|
|
1467
1552
|
function createTrackingRoutes(env, config = {}) {
|
|
1468
|
-
const app = new
|
|
1553
|
+
const app = new Hono3();
|
|
1469
1554
|
const db = env.DB;
|
|
1470
1555
|
const tablePrefix = config.emailTablePrefix || config.tableNamePrefix || "system_email_";
|
|
1471
1556
|
app.get("/track/open/:token", async (c) => {
|
|
@@ -1593,11 +1678,19 @@ function createTrackingRoutes(env, config = {}) {
|
|
|
1593
1678
|
return app;
|
|
1594
1679
|
}
|
|
1595
1680
|
|
|
1681
|
+
// src/backend/routes/logs.js
|
|
1682
|
+
import { Hono as Hono4 } from "hono";
|
|
1683
|
+
|
|
1596
1684
|
// src/backend/routes/index.js
|
|
1597
|
-
function createEmailRoutes(
|
|
1598
|
-
const app = new
|
|
1599
|
-
app.route("/
|
|
1600
|
-
app.route("/
|
|
1685
|
+
function createEmailRoutes(config = {}, cacheProvider = null) {
|
|
1686
|
+
const app = new Hono5();
|
|
1687
|
+
app.route("/templates", createTemplateRoutes(config, cacheProvider));
|
|
1688
|
+
app.route("/logs", createLogRoutes(config));
|
|
1689
|
+
app.route("/settings", createSettingsRoutes({
|
|
1690
|
+
...config,
|
|
1691
|
+
tableName: config.settingsTableName || "system_settings",
|
|
1692
|
+
keyPrefix: config.settingsKeyPrefix || "system_email."
|
|
1693
|
+
}));
|
|
1601
1694
|
return app;
|
|
1602
1695
|
}
|
|
1603
1696
|
|
|
@@ -2143,7 +2236,7 @@ export {
|
|
|
2143
2236
|
createDOCacheProvider,
|
|
2144
2237
|
createEmailLoggerCallback,
|
|
2145
2238
|
createEmailRoutes,
|
|
2146
|
-
createTemplateRoutes,
|
|
2239
|
+
createTemplateRoutes2 as createTemplateRoutes,
|
|
2147
2240
|
createTrackingRoutes,
|
|
2148
2241
|
encodeTrackingLinks,
|
|
2149
2242
|
extractVariables,
|