@contentgrowth/content-emailing 0.6.2 → 0.7.2
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 +315 -2
- package/dist/backend/EmailService.cjs.map +1 -1
- package/dist/backend/EmailService.d.cts +5 -1
- package/dist/backend/EmailService.d.ts +5 -1
- package/dist/backend/EmailService.js +315 -2
- package/dist/backend/EmailService.js.map +1 -1
- package/dist/backend/routes/index.cjs +315 -2
- package/dist/backend/routes/index.cjs.map +1 -1
- package/dist/backend/routes/index.js +315 -2
- package/dist/backend/routes/index.js.map +1 -1
- package/dist/frontend/index.cjs +144 -1
- package/dist/frontend/index.cjs.map +1 -1
- package/dist/frontend/index.d.cts +66 -1
- package/dist/frontend/index.d.ts +66 -1
- package/dist/frontend/index.js +143 -1
- package/dist/frontend/index.js.map +1 -1
- package/dist/index.cjs +324 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +322 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schema.sql +32 -0
package/dist/index.cjs
CHANGED
|
@@ -29,11 +29,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.js
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
+
EmailLogger: () => EmailLogger,
|
|
32
33
|
EmailService: () => EmailService,
|
|
33
34
|
EmailingCacheDO: () => EmailingCacheDO,
|
|
34
35
|
TemplateEditor: () => TemplateEditor,
|
|
35
36
|
TemplateManager: () => TemplateManager,
|
|
36
37
|
createDOCacheProvider: () => createDOCacheProvider,
|
|
38
|
+
createEmailLoggerCallback: () => createEmailLoggerCallback,
|
|
37
39
|
createEmailRoutes: () => createEmailRoutes,
|
|
38
40
|
createTemplateRoutes: () => createTemplateRoutes,
|
|
39
41
|
createTrackingRoutes: () => createTrackingRoutes,
|
|
@@ -568,6 +570,226 @@ function createDOCacheProvider(doStub, instanceName = "global") {
|
|
|
568
570
|
};
|
|
569
571
|
}
|
|
570
572
|
|
|
573
|
+
// src/backend/EmailLogger.js
|
|
574
|
+
var EmailLogger = class {
|
|
575
|
+
/**
|
|
576
|
+
* @param {Object} db - D1 database binding
|
|
577
|
+
* @param {Object} options - Configuration options
|
|
578
|
+
* @param {string} [options.tableName='system_email_logs'] - Table name for logs
|
|
579
|
+
*/
|
|
580
|
+
constructor(db, options = {}) {
|
|
581
|
+
this.db = db;
|
|
582
|
+
this.tableName = options.tableName || "system_email_logs";
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Creates a logger callback function for use with EmailService.
|
|
586
|
+
* Usage: new EmailService(env, { emailLogger: emailLogger.createCallback() })
|
|
587
|
+
*/
|
|
588
|
+
createCallback() {
|
|
589
|
+
return async (entry) => {
|
|
590
|
+
await this.log(entry);
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Log an email event (pending, sent, or failed)
|
|
595
|
+
* @param {Object} entry - Log entry
|
|
596
|
+
*/
|
|
597
|
+
async log(entry) {
|
|
598
|
+
const {
|
|
599
|
+
event,
|
|
600
|
+
recipientEmail,
|
|
601
|
+
recipientUserId,
|
|
602
|
+
templateId,
|
|
603
|
+
subject,
|
|
604
|
+
provider,
|
|
605
|
+
messageId,
|
|
606
|
+
batchId,
|
|
607
|
+
error,
|
|
608
|
+
errorCode,
|
|
609
|
+
metadata
|
|
610
|
+
} = entry;
|
|
611
|
+
try {
|
|
612
|
+
if (event === "pending") {
|
|
613
|
+
const id = crypto.randomUUID().replace(/-/g, "");
|
|
614
|
+
await this.db.prepare(`
|
|
615
|
+
INSERT INTO ${this.tableName}
|
|
616
|
+
(id, batch_id, recipient_email, recipient_user_id, template_id, subject, status, metadata, created_at)
|
|
617
|
+
VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, strftime('%s', 'now'))
|
|
618
|
+
`).bind(
|
|
619
|
+
id,
|
|
620
|
+
batchId || null,
|
|
621
|
+
recipientEmail,
|
|
622
|
+
recipientUserId || null,
|
|
623
|
+
templateId || "direct",
|
|
624
|
+
subject || null,
|
|
625
|
+
metadata ? JSON.stringify(metadata) : null
|
|
626
|
+
).run();
|
|
627
|
+
} else if (event === "sent") {
|
|
628
|
+
await this.db.prepare(`
|
|
629
|
+
UPDATE ${this.tableName}
|
|
630
|
+
SET status = 'sent',
|
|
631
|
+
provider = ?,
|
|
632
|
+
provider_message_id = ?,
|
|
633
|
+
sent_at = strftime('%s', 'now')
|
|
634
|
+
WHERE recipient_email = ?
|
|
635
|
+
AND template_id = ?
|
|
636
|
+
AND status = 'pending'
|
|
637
|
+
ORDER BY created_at DESC
|
|
638
|
+
LIMIT 1
|
|
639
|
+
`).bind(
|
|
640
|
+
provider || null,
|
|
641
|
+
messageId || null,
|
|
642
|
+
recipientEmail,
|
|
643
|
+
templateId || "direct"
|
|
644
|
+
).run();
|
|
645
|
+
} else if (event === "failed") {
|
|
646
|
+
await this.db.prepare(`
|
|
647
|
+
UPDATE ${this.tableName}
|
|
648
|
+
SET status = 'failed',
|
|
649
|
+
provider = ?,
|
|
650
|
+
error_message = ?,
|
|
651
|
+
error_code = ?
|
|
652
|
+
WHERE recipient_email = ?
|
|
653
|
+
AND template_id = ?
|
|
654
|
+
AND status = 'pending'
|
|
655
|
+
ORDER BY created_at DESC
|
|
656
|
+
LIMIT 1
|
|
657
|
+
`).bind(
|
|
658
|
+
provider || null,
|
|
659
|
+
error || null,
|
|
660
|
+
errorCode || null,
|
|
661
|
+
recipientEmail,
|
|
662
|
+
templateId || "direct"
|
|
663
|
+
).run();
|
|
664
|
+
}
|
|
665
|
+
} catch (e) {
|
|
666
|
+
console.error("[EmailLogger] Failed to log:", e);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Query email logs with filtering
|
|
671
|
+
* @param {Object} options - Query options
|
|
672
|
+
*/
|
|
673
|
+
async query(options = {}) {
|
|
674
|
+
const {
|
|
675
|
+
recipientEmail,
|
|
676
|
+
recipientUserId,
|
|
677
|
+
templateId,
|
|
678
|
+
status,
|
|
679
|
+
batchId,
|
|
680
|
+
limit = 50,
|
|
681
|
+
offset = 0
|
|
682
|
+
} = options;
|
|
683
|
+
const conditions = [];
|
|
684
|
+
const bindings = [];
|
|
685
|
+
if (recipientEmail) {
|
|
686
|
+
conditions.push("recipient_email = ?");
|
|
687
|
+
bindings.push(recipientEmail);
|
|
688
|
+
}
|
|
689
|
+
if (recipientUserId) {
|
|
690
|
+
conditions.push("recipient_user_id = ?");
|
|
691
|
+
bindings.push(recipientUserId);
|
|
692
|
+
}
|
|
693
|
+
if (templateId) {
|
|
694
|
+
conditions.push("template_id = ?");
|
|
695
|
+
bindings.push(templateId);
|
|
696
|
+
}
|
|
697
|
+
if (status) {
|
|
698
|
+
conditions.push("status = ?");
|
|
699
|
+
bindings.push(status);
|
|
700
|
+
}
|
|
701
|
+
if (batchId) {
|
|
702
|
+
conditions.push("batch_id = ?");
|
|
703
|
+
bindings.push(batchId);
|
|
704
|
+
}
|
|
705
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
706
|
+
const countResult = await this.db.prepare(
|
|
707
|
+
`SELECT COUNT(*) as count FROM ${this.tableName} ${whereClause}`
|
|
708
|
+
).bind(...bindings).first();
|
|
709
|
+
const { results } = await this.db.prepare(`
|
|
710
|
+
SELECT id, batch_id, recipient_email, recipient_user_id, template_id, subject,
|
|
711
|
+
status, provider, provider_message_id, error_message, error_code, metadata,
|
|
712
|
+
created_at, sent_at
|
|
713
|
+
FROM ${this.tableName}
|
|
714
|
+
${whereClause}
|
|
715
|
+
ORDER BY created_at DESC
|
|
716
|
+
LIMIT ? OFFSET ?
|
|
717
|
+
`).bind(...bindings, limit, offset).all();
|
|
718
|
+
const logs = (results || []).map((row) => ({
|
|
719
|
+
id: row.id,
|
|
720
|
+
batchId: row.batch_id,
|
|
721
|
+
recipientEmail: row.recipient_email,
|
|
722
|
+
recipientUserId: row.recipient_user_id,
|
|
723
|
+
templateId: row.template_id,
|
|
724
|
+
subject: row.subject,
|
|
725
|
+
status: row.status,
|
|
726
|
+
provider: row.provider,
|
|
727
|
+
providerMessageId: row.provider_message_id,
|
|
728
|
+
errorMessage: row.error_message,
|
|
729
|
+
errorCode: row.error_code,
|
|
730
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
|
|
731
|
+
createdAt: row.created_at,
|
|
732
|
+
sentAt: row.sent_at
|
|
733
|
+
}));
|
|
734
|
+
return { logs, total: countResult?.count || 0 };
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Get email sending statistics
|
|
738
|
+
* @param {number} sinceDays - Number of days to look back
|
|
739
|
+
*/
|
|
740
|
+
async getStats(sinceDays = 7) {
|
|
741
|
+
const sinceTimestamp = Math.floor(Date.now() / 1e3) - sinceDays * 24 * 60 * 60;
|
|
742
|
+
const statusResult = await this.db.prepare(`
|
|
743
|
+
SELECT status, COUNT(*) as count
|
|
744
|
+
FROM ${this.tableName}
|
|
745
|
+
WHERE created_at >= ?
|
|
746
|
+
GROUP BY status
|
|
747
|
+
`).bind(sinceTimestamp).all();
|
|
748
|
+
const templateResult = await this.db.prepare(`
|
|
749
|
+
SELECT template_id, COUNT(*) as count
|
|
750
|
+
FROM ${this.tableName}
|
|
751
|
+
WHERE created_at >= ?
|
|
752
|
+
GROUP BY template_id
|
|
753
|
+
`).bind(sinceTimestamp).all();
|
|
754
|
+
const stats = {
|
|
755
|
+
total: 0,
|
|
756
|
+
sent: 0,
|
|
757
|
+
failed: 0,
|
|
758
|
+
pending: 0,
|
|
759
|
+
byTemplate: {}
|
|
760
|
+
};
|
|
761
|
+
(statusResult.results || []).forEach((row) => {
|
|
762
|
+
const count = row.count || 0;
|
|
763
|
+
stats.total += count;
|
|
764
|
+
if (row.status === "sent") stats.sent = count;
|
|
765
|
+
if (row.status === "failed") stats.failed = count;
|
|
766
|
+
if (row.status === "pending") stats.pending = count;
|
|
767
|
+
});
|
|
768
|
+
(templateResult.results || []).forEach((row) => {
|
|
769
|
+
stats.byTemplate[row.template_id] = row.count;
|
|
770
|
+
});
|
|
771
|
+
return stats;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Get recent failed emails for debugging
|
|
775
|
+
* @param {number} limit - Number of failed emails to retrieve
|
|
776
|
+
*/
|
|
777
|
+
async getRecentFailures(limit = 20) {
|
|
778
|
+
const { results } = await this.db.prepare(`
|
|
779
|
+
SELECT id, recipient_email, template_id, subject, error_message, error_code, created_at
|
|
780
|
+
FROM ${this.tableName}
|
|
781
|
+
WHERE status = 'failed'
|
|
782
|
+
ORDER BY created_at DESC
|
|
783
|
+
LIMIT ?
|
|
784
|
+
`).bind(limit).all();
|
|
785
|
+
return results || [];
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
function createEmailLoggerCallback(db, tableName = "system_email_logs") {
|
|
789
|
+
const logger = new EmailLogger(db, { tableName });
|
|
790
|
+
return logger.createCallback();
|
|
791
|
+
}
|
|
792
|
+
|
|
571
793
|
// src/backend/EmailService.js
|
|
572
794
|
var EmailService = class {
|
|
573
795
|
/**
|
|
@@ -575,6 +797,7 @@ var EmailService = class {
|
|
|
575
797
|
* @param {Object} config - Configuration options
|
|
576
798
|
* @param {string} [config.emailTablePrefix='system_email_'] - Prefix for D1 tables
|
|
577
799
|
* @param {Object} [config.defaults] - Default settings (fromName, fromAddress)
|
|
800
|
+
* @param {boolean|Function} [config.emailLogger] - Email logger: true (default), false (disabled), or custom callback
|
|
578
801
|
* @param {Object} [cacheProvider] - Optional cache interface (DO stub or KV wrapper)
|
|
579
802
|
*/
|
|
580
803
|
constructor(env, config = {}, cacheProvider = null) {
|
|
@@ -602,6 +825,16 @@ var EmailService = class {
|
|
|
602
825
|
},
|
|
603
826
|
...config
|
|
604
827
|
};
|
|
828
|
+
if (config.emailLogger === false) {
|
|
829
|
+
this.emailLogger = null;
|
|
830
|
+
} else if (typeof config.emailLogger === "function") {
|
|
831
|
+
this.emailLogger = config.emailLogger;
|
|
832
|
+
} else if (env.DB) {
|
|
833
|
+
const logger = new EmailLogger(env.DB);
|
|
834
|
+
this.emailLogger = logger.createCallback();
|
|
835
|
+
} else {
|
|
836
|
+
this.emailLogger = null;
|
|
837
|
+
}
|
|
605
838
|
if (!cacheProvider && env.EMAIL_TEMPLATE_CACHE) {
|
|
606
839
|
this.cache = createDOCacheProvider(env.EMAIL_TEMPLATE_CACHE);
|
|
607
840
|
} else {
|
|
@@ -851,13 +1084,30 @@ var EmailService = class {
|
|
|
851
1084
|
* @param {Object} [params.metadata] - Additional metadata
|
|
852
1085
|
* @returns {Promise<Object>} Delivery result
|
|
853
1086
|
*/
|
|
854
|
-
async sendEmail({ to, subject, html, htmlBody, text, textBody, provider, profile = "system", tenantId = null, metadata = {} }) {
|
|
1087
|
+
async sendEmail({ to, subject, html, htmlBody, text, textBody, provider, profile = "system", tenantId = null, metadata = {}, batchId = null, userId = null }) {
|
|
855
1088
|
const htmlContent = html || htmlBody;
|
|
856
1089
|
const textContent = text || textBody;
|
|
1090
|
+
const templateId = metadata?.templateId || "direct";
|
|
1091
|
+
if (this.emailLogger) {
|
|
1092
|
+
try {
|
|
1093
|
+
await this.emailLogger({
|
|
1094
|
+
event: "pending",
|
|
1095
|
+
recipientEmail: to,
|
|
1096
|
+
recipientUserId: userId,
|
|
1097
|
+
templateId,
|
|
1098
|
+
subject,
|
|
1099
|
+
batchId,
|
|
1100
|
+
metadata
|
|
1101
|
+
});
|
|
1102
|
+
} catch (e) {
|
|
1103
|
+
console.warn("[EmailService] emailLogger pending failed:", e);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
857
1106
|
try {
|
|
858
1107
|
const settings = await this.loadSettings(profile, tenantId);
|
|
859
1108
|
const useProvider = provider || settings.provider || "mailchannels";
|
|
860
1109
|
let result;
|
|
1110
|
+
let providerMessageId = null;
|
|
861
1111
|
switch (useProvider) {
|
|
862
1112
|
case "mailchannels":
|
|
863
1113
|
result = await this.sendViaMailChannels(to, subject, htmlContent, textContent, settings, metadata);
|
|
@@ -867,22 +1117,91 @@ var EmailService = class {
|
|
|
867
1117
|
break;
|
|
868
1118
|
case "resend":
|
|
869
1119
|
result = await this.sendViaResend(to, subject, htmlContent, textContent, settings, metadata);
|
|
1120
|
+
if (result && typeof result === "object" && result.id) {
|
|
1121
|
+
providerMessageId = result.id;
|
|
1122
|
+
result = true;
|
|
1123
|
+
}
|
|
870
1124
|
break;
|
|
871
1125
|
case "sendpulse":
|
|
872
1126
|
result = await this.sendViaSendPulse(to, subject, htmlContent, textContent, settings, metadata);
|
|
873
1127
|
break;
|
|
874
1128
|
default:
|
|
875
1129
|
console.error(`[EmailService] Unknown provider: ${useProvider}`);
|
|
1130
|
+
if (this.emailLogger) {
|
|
1131
|
+
try {
|
|
1132
|
+
await this.emailLogger({
|
|
1133
|
+
event: "failed",
|
|
1134
|
+
recipientEmail: to,
|
|
1135
|
+
recipientUserId: userId,
|
|
1136
|
+
templateId,
|
|
1137
|
+
subject,
|
|
1138
|
+
provider: useProvider,
|
|
1139
|
+
batchId,
|
|
1140
|
+
error: `Unknown email provider: ${useProvider}`,
|
|
1141
|
+
metadata
|
|
1142
|
+
});
|
|
1143
|
+
} catch (e) {
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
876
1146
|
return { success: false, error: `Unknown email provider: ${useProvider}` };
|
|
877
1147
|
}
|
|
878
1148
|
if (result) {
|
|
879
|
-
|
|
1149
|
+
const messageId = providerMessageId || crypto.randomUUID();
|
|
1150
|
+
if (this.emailLogger) {
|
|
1151
|
+
try {
|
|
1152
|
+
await this.emailLogger({
|
|
1153
|
+
event: "sent",
|
|
1154
|
+
recipientEmail: to,
|
|
1155
|
+
recipientUserId: userId,
|
|
1156
|
+
templateId,
|
|
1157
|
+
subject,
|
|
1158
|
+
provider: useProvider,
|
|
1159
|
+
messageId,
|
|
1160
|
+
batchId,
|
|
1161
|
+
metadata
|
|
1162
|
+
});
|
|
1163
|
+
} catch (e) {
|
|
1164
|
+
console.warn("[EmailService] emailLogger sent failed:", e);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return { success: true, messageId };
|
|
880
1168
|
} else {
|
|
881
1169
|
console.error("[EmailService] Failed to send email to:", to);
|
|
1170
|
+
if (this.emailLogger) {
|
|
1171
|
+
try {
|
|
1172
|
+
await this.emailLogger({
|
|
1173
|
+
event: "failed",
|
|
1174
|
+
recipientEmail: to,
|
|
1175
|
+
recipientUserId: userId,
|
|
1176
|
+
templateId,
|
|
1177
|
+
subject,
|
|
1178
|
+
provider: useProvider,
|
|
1179
|
+
batchId,
|
|
1180
|
+
error: "Failed to send email",
|
|
1181
|
+
metadata
|
|
1182
|
+
});
|
|
1183
|
+
} catch (e) {
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
882
1186
|
return { success: false, error: "Failed to send email" };
|
|
883
1187
|
}
|
|
884
1188
|
} catch (error) {
|
|
885
1189
|
console.error("[EmailService] Error sending email:", error);
|
|
1190
|
+
if (this.emailLogger) {
|
|
1191
|
+
try {
|
|
1192
|
+
await this.emailLogger({
|
|
1193
|
+
event: "failed",
|
|
1194
|
+
recipientEmail: to,
|
|
1195
|
+
recipientUserId: userId,
|
|
1196
|
+
templateId,
|
|
1197
|
+
subject,
|
|
1198
|
+
batchId,
|
|
1199
|
+
error: error.message,
|
|
1200
|
+
metadata
|
|
1201
|
+
});
|
|
1202
|
+
} catch (e) {
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
886
1205
|
return { success: false, error: error.message };
|
|
887
1206
|
}
|
|
888
1207
|
}
|
|
@@ -1742,7 +2061,7 @@ var TemplateManager = ({
|
|
|
1742
2061
|
},
|
|
1743
2062
|
/* @__PURE__ */ import_react3.default.createElement("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react3.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" })),
|
|
1744
2063
|
"Create Template"
|
|
1745
|
-
)), error && /* @__PURE__ */ import_react3.default.createElement("div", { className: "mb-4 p-3 rounded-lg bg-red-50 text-red-800 border border-red-200" }, error, /* @__PURE__ */ import_react3.default.createElement("button", { onClick: () => setError(null), className: "ml-2 underline" }, "Dismiss")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "
|
|
2064
|
+
)), error && /* @__PURE__ */ import_react3.default.createElement("div", { className: "mb-4 p-3 rounded-lg bg-red-50 text-red-800 border border-red-200" }, error, /* @__PURE__ */ import_react3.default.createElement("button", { onClick: () => setError(null), className: "ml-2 underline" }, "Dismiss")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex gap-4 mb-6" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4 flex-1" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-2xl font-bold text-gray-900" }, templates.length), /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-sm text-gray-500" }, "Total")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4 flex-1" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-2xl font-bold text-green-600" }, templates.filter((t) => t.is_active).length), /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-sm text-gray-500" }, "Active")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4 flex-1" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-2xl font-bold text-yellow-600" }, templates.filter((t) => !t.is_active).length), /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-sm text-gray-500" }, "Inactive")), /* @__PURE__ */ import_react3.default.createElement("div", { className: "bg-white rounded-lg border border-gray-200 p-4 flex-1" }, /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-2xl font-bold text-blue-600" }, new Set(templates.map((t) => t.template_type)).size), /* @__PURE__ */ import_react3.default.createElement("div", { className: "text-sm text-gray-500" }, "Types"))), /* @__PURE__ */ import_react3.default.createElement("div", { className: "flex gap-2 mb-6 border-b border-gray-200 pb-3 flex-wrap" }, uniqueTypes.map((type) => /* @__PURE__ */ import_react3.default.createElement(
|
|
1746
2065
|
"button",
|
|
1747
2066
|
{
|
|
1748
2067
|
key: type,
|
|
@@ -1867,11 +2186,13 @@ var TemplateManager = ({
|
|
|
1867
2186
|
};
|
|
1868
2187
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1869
2188
|
0 && (module.exports = {
|
|
2189
|
+
EmailLogger,
|
|
1870
2190
|
EmailService,
|
|
1871
2191
|
EmailingCacheDO,
|
|
1872
2192
|
TemplateEditor,
|
|
1873
2193
|
TemplateManager,
|
|
1874
2194
|
createDOCacheProvider,
|
|
2195
|
+
createEmailLoggerCallback,
|
|
1875
2196
|
createEmailRoutes,
|
|
1876
2197
|
createTemplateRoutes,
|
|
1877
2198
|
createTrackingRoutes,
|