@aevr/mailer 1.0.0

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 (69) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +80 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/adapters/nodemailer.d.ts +3 -0
  6. package/dist/adapters/nodemailer.d.ts.map +1 -0
  7. package/dist/adapters/nodemailer.js +31 -0
  8. package/dist/adapters/nodemailer.js.map +1 -0
  9. package/dist/adapters/resend.d.ts +3 -0
  10. package/dist/adapters/resend.d.ts.map +1 -0
  11. package/dist/adapters/resend.js +27 -0
  12. package/dist/adapters/resend.js.map +1 -0
  13. package/dist/adapters/zeptomail.d.ts +3 -0
  14. package/dist/adapters/zeptomail.d.ts.map +1 -0
  15. package/dist/adapters/zeptomail.js +29 -0
  16. package/dist/adapters/zeptomail.js.map +1 -0
  17. package/dist/index.d.ts +21 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +69 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/templates/_layout.d.ts +26 -0
  22. package/dist/templates/_layout.d.ts.map +1 -0
  23. package/dist/templates/_layout.js +83 -0
  24. package/dist/templates/_layout.js.map +1 -0
  25. package/dist/templates/adminAlert.d.ts +23 -0
  26. package/dist/templates/adminAlert.d.ts.map +1 -0
  27. package/dist/templates/adminAlert.js +61 -0
  28. package/dist/templates/adminAlert.js.map +1 -0
  29. package/dist/templates/deploymentBuildFailed.d.ts +13 -0
  30. package/dist/templates/deploymentBuildFailed.d.ts.map +1 -0
  31. package/dist/templates/deploymentBuildFailed.js +38 -0
  32. package/dist/templates/deploymentBuildFailed.js.map +1 -0
  33. package/dist/templates/deploymentFailed.d.ts +13 -0
  34. package/dist/templates/deploymentFailed.d.ts.map +1 -0
  35. package/dist/templates/deploymentFailed.js +38 -0
  36. package/dist/templates/deploymentFailed.js.map +1 -0
  37. package/dist/templates/deploymentRunning.d.ts +13 -0
  38. package/dist/templates/deploymentRunning.d.ts.map +1 -0
  39. package/dist/templates/deploymentRunning.js +38 -0
  40. package/dist/templates/deploymentRunning.js.map +1 -0
  41. package/dist/templates/emailVerification.d.ts +12 -0
  42. package/dist/templates/emailVerification.d.ts.map +1 -0
  43. package/dist/templates/emailVerification.js +34 -0
  44. package/dist/templates/emailVerification.js.map +1 -0
  45. package/dist/templates/index.d.ts +21 -0
  46. package/dist/templates/index.d.ts.map +1 -0
  47. package/dist/templates/index.js +13 -0
  48. package/dist/templates/index.js.map +1 -0
  49. package/dist/templates/instance.d.ts +65 -0
  50. package/dist/templates/instance.d.ts.map +1 -0
  51. package/dist/templates/instance.js +196 -0
  52. package/dist/templates/instance.js.map +1 -0
  53. package/dist/templates/passwordReset.d.ts +12 -0
  54. package/dist/templates/passwordReset.d.ts.map +1 -0
  55. package/dist/templates/passwordReset.js +37 -0
  56. package/dist/templates/passwordReset.js.map +1 -0
  57. package/dist/templates/sslFailed.d.ts +15 -0
  58. package/dist/templates/sslFailed.d.ts.map +1 -0
  59. package/dist/templates/sslFailed.js +47 -0
  60. package/dist/templates/sslFailed.js.map +1 -0
  61. package/dist/templates/teamInvite.d.ts +18 -0
  62. package/dist/templates/teamInvite.d.ts.map +1 -0
  63. package/dist/templates/teamInvite.js +51 -0
  64. package/dist/templates/teamInvite.js.map +1 -0
  65. package/dist/types.d.ts +35 -0
  66. package/dist/types.d.ts.map +1 -0
  67. package/dist/types.js +3 -0
  68. package/dist/types.js.map +1 -0
  69. package/package.json +49 -0
@@ -0,0 +1,196 @@
1
+ import { emailLayout, emailButton, t } from "./_layout.js";
2
+ export function instanceProvisionedTemplate(opts) {
3
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Platform";
4
+ const greeting = opts.userName ? `Hi ${opts.userName},` : "Hi there,";
5
+ const detailsTable = `
6
+ <table style="width:100%;border-collapse:collapse;margin:20px 0;font-size:15px">
7
+ <tr>
8
+ <td style="padding:10px 0;color:${t.mutedColor};border-bottom:1px solid ${t.borderColor};width:40%">Instance Name</td>
9
+ <td style="padding:10px 0;color:${t.headingColor};border-bottom:1px solid ${t.borderColor};font-weight:600">${opts.instanceName}</td>
10
+ </tr>
11
+ <tr>
12
+ <td style="padding:10px 0;color:${t.mutedColor};border-bottom:1px solid ${t.borderColor}">Instance ID</td>
13
+ <td style="padding:10px 0;color:${t.headingColor};border-bottom:1px solid ${t.borderColor};font-family:'Courier New',monospace;font-size:13px">${opts.instanceId}</td>
14
+ </tr>
15
+ ${opts.ipAddress
16
+ ? `<tr>
17
+ <td style="padding:10px 0;color:${t.mutedColor}">IP Address</td>
18
+ <td style="padding:10px 0;color:${t.headingColor};font-family:'Courier New',monospace">${opts.ipAddress}</td>
19
+ </tr>`
20
+ : ""}
21
+ </table>`;
22
+ const cta = opts.dashboardUrl ? emailButton("View instance", opts.dashboardUrl) : "";
23
+ const body = `
24
+ <p style="margin:0 0 16px">${greeting}</p>
25
+ <p style="margin:0 0 16px">
26
+ Your instance <strong>${opts.instanceName}</strong> has been successfully provisioned and is ready to use.
27
+ </p>
28
+ ${detailsTable}
29
+ ${cta}`;
30
+ const textLines = [
31
+ greeting,
32
+ "",
33
+ `Your instance "${opts.instanceName}" has been provisioned and is ready.`,
34
+ "",
35
+ `Instance ID: ${opts.instanceId}`,
36
+ ...(opts.ipAddress ? [`IP Address: ${opts.ipAddress}`] : []),
37
+ ...(opts.dashboardUrl ? ["", `View it at: ${opts.dashboardUrl}`] : []),
38
+ ];
39
+ return {
40
+ subject: `Your instance "${opts.instanceName}" is ready — ${appName}`,
41
+ html: emailLayout({
42
+ preview: `Your instance ${opts.instanceName} is ready`,
43
+ title: "Instance ready",
44
+ body,
45
+ appName,
46
+ }),
47
+ text: textLines.join("\n"),
48
+ };
49
+ }
50
+ export function instanceErrorTemplate(opts) {
51
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Platform";
52
+ const greeting = opts.userName ? `Hi ${opts.userName},` : "Hi there,";
53
+ const errorBlock = opts.errorMessage
54
+ ? `<div style="margin:20px 0;padding:16px 20px;background-color:#fef2f2;border-radius:12px;
55
+ border-left:4px solid #f87171;font-family:'Courier New',monospace;
56
+ font-size:13px;color:#b91c1c;word-break:break-all">
57
+ ${opts.errorMessage}
58
+ </div>`
59
+ : "";
60
+ const cta = opts.supportUrl ? emailButton("Contact support", opts.supportUrl) : "";
61
+ const body = `
62
+ <p style="margin:0 0 16px">${greeting}</p>
63
+ <p style="margin:0 0 16px">
64
+ We encountered an error while provisioning your instance <strong>${opts.instanceName}</strong>
65
+ (ID: <code style="font-family:'Courier New',monospace;font-size:13px">${opts.instanceId}</code>).
66
+ Our team has been notified.
67
+ </p>
68
+ ${errorBlock}
69
+ <p style="margin:16px 0 0">
70
+ Please try again or contact support if the problem persists.
71
+ </p>
72
+ ${cta}`;
73
+ return {
74
+ subject: `Provisioning failed for "${opts.instanceName}" — ${appName}`,
75
+ html: emailLayout({
76
+ preview: `Provisioning failed for ${opts.instanceName}`,
77
+ title: "Provisioning failed",
78
+ body,
79
+ appName,
80
+ }),
81
+ text: [
82
+ greeting,
83
+ "",
84
+ `There was an error provisioning your instance "${opts.instanceName}" (${opts.instanceId}).`,
85
+ ...(opts.errorMessage ? ["", `Error: ${opts.errorMessage}`] : []),
86
+ "",
87
+ "Please try again or contact support if the problem persists.",
88
+ ...(opts.supportUrl ? [`Support: ${opts.supportUrl}`] : []),
89
+ ].join("\n"),
90
+ };
91
+ }
92
+ export function instanceDeletedTemplate(opts) {
93
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Platform";
94
+ const greeting = opts.userName ? `Hi ${opts.userName},` : "Hi there,";
95
+ const body = `
96
+ <p style="margin:0 0 16px">${greeting}</p>
97
+ <p style="margin:0 0 0">
98
+ Your instance <strong>${opts.instanceName}</strong>
99
+ (ID: <code style="font-family:'Courier New',monospace;font-size:13px">${opts.instanceId}</code>)
100
+ has been permanently deleted. All associated data has been removed.
101
+ </p>`;
102
+ return {
103
+ subject: `Instance "${opts.instanceName}" deleted — ${appName}`,
104
+ html: emailLayout({
105
+ preview: `Instance ${opts.instanceName} deleted`,
106
+ title: "Instance deleted",
107
+ body,
108
+ appName,
109
+ }),
110
+ text: [
111
+ greeting,
112
+ "",
113
+ `Your instance "${opts.instanceName}" (${opts.instanceId}) has been permanently deleted.`,
114
+ ].join("\n"),
115
+ };
116
+ }
117
+ export function instanceHighUsageTemplate(opts) {
118
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Platform";
119
+ const greeting = opts.userName ? `Hi ${opts.userName},` : "Hi there,";
120
+ const fmt = (n) => n.toFixed(1);
121
+ const alertRows = [];
122
+ const textAlerts = [];
123
+ if (opts.cpu && opts.cpu.usedPercent >= 80) {
124
+ alertRows.push(`
125
+ <tr>
126
+ <td style="padding:10px 0;color:${t.mutedColor};border-bottom:1px solid ${t.borderColor};width:40%">CPU</td>
127
+ <td style="padding:10px 0;border-bottom:1px solid ${t.borderColor}">
128
+ <span style="color:#d97706;font-weight:600">${fmt(opts.cpu.usedPercent)}%</span>
129
+ <span style="color:${t.mutedColor};font-size:13px"> of ${opts.cpu.cores} vCPU${opts.cpu.cores !== 1 ? "s" : ""}</span>
130
+ </td>
131
+ </tr>`);
132
+ textAlerts.push(`CPU: ${fmt(opts.cpu.usedPercent)}% (${opts.cpu.cores} vCPUs)`);
133
+ }
134
+ if (opts.memory && opts.memory.usedPercent >= 80) {
135
+ alertRows.push(`
136
+ <tr>
137
+ <td style="padding:10px 0;color:${t.mutedColor};border-bottom:1px solid ${t.borderColor}">Memory</td>
138
+ <td style="padding:10px 0;border-bottom:1px solid ${t.borderColor}">
139
+ <span style="color:#d97706;font-weight:600">${fmt(opts.memory.usedPercent)}%</span>
140
+ <span style="color:${t.mutedColor};font-size:13px"> — ${Math.round(opts.memory.usedMb / 1024 * 10) / 10} GB of ${Math.round(opts.memory.totalMb / 1024 * 10) / 10} GB</span>
141
+ </td>
142
+ </tr>`);
143
+ textAlerts.push(`Memory: ${fmt(opts.memory.usedPercent)}% (${Math.round(opts.memory.usedMb / 1024 * 10) / 10} GB / ${Math.round(opts.memory.totalMb / 1024 * 10) / 10} GB)`);
144
+ }
145
+ if (opts.disk && opts.disk.usedPercent >= 85) {
146
+ alertRows.push(`
147
+ <tr>
148
+ <td style="padding:10px 0;color:${t.mutedColor}">Disk</td>
149
+ <td style="padding:10px 0">
150
+ <span style="color:#d97706;font-weight:600">${fmt(opts.disk.usedPercent)}%</span>
151
+ <span style="color:${t.mutedColor};font-size:13px"> — ${fmt(opts.disk.usedGb)} GB of ${fmt(opts.disk.totalGb)} GB</span>
152
+ </td>
153
+ </tr>`);
154
+ textAlerts.push(`Disk: ${fmt(opts.disk.usedPercent)}% (${fmt(opts.disk.usedGb)} GB / ${fmt(opts.disk.totalGb)} GB)`);
155
+ }
156
+ const table = alertRows.length
157
+ ? `<table style="width:100%;border-collapse:collapse;margin:20px 0;font-size:15px">${alertRows.join("")}</table>`
158
+ : "";
159
+ const cta = opts.upgradeUrl
160
+ ? emailButton("Upgrade instance", opts.upgradeUrl)
161
+ : opts.dashboardUrl
162
+ ? emailButton("View instance", opts.dashboardUrl)
163
+ : "";
164
+ const body = `
165
+ <p style="margin:0 0 16px">${greeting}</p>
166
+ <p style="margin:0 0 16px">
167
+ Your instance <strong>${opts.instanceName}</strong> is running high on resources.
168
+ Consider upgrading to avoid performance issues or downtime.
169
+ </p>
170
+ ${table}
171
+ ${cta}
172
+ <p style="margin:16px 0 0;color:${t.mutedColor};font-size:13px">
173
+ You can upgrade CPU, RAM, or disk from the instance settings in your dashboard.
174
+ Disk changes are permanent; CPU and RAM take effect on next restart.
175
+ </p>`;
176
+ return {
177
+ subject: `Action needed: "${opts.instanceName}" is running low on resources — ${appName}`,
178
+ html: emailLayout({
179
+ preview: `${opts.instanceName} is running high on resources`,
180
+ title: "Resource alert",
181
+ body,
182
+ appName,
183
+ }),
184
+ text: [
185
+ greeting,
186
+ "",
187
+ `Your instance "${opts.instanceName}" is running high on resources:`,
188
+ "",
189
+ ...textAlerts,
190
+ "",
191
+ ...(opts.upgradeUrl ? [`Upgrade: ${opts.upgradeUrl}`] : []),
192
+ ...(opts.dashboardUrl ? [`Dashboard: ${opts.dashboardUrl}`] : []),
193
+ ].join("\n"),
194
+ };
195
+ }
196
+ //# sourceMappingURL=instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.js","sourceRoot":"","sources":["../../src/templates/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAa3D,MAAM,UAAU,2BAA2B,CAAC,IAAgC;IAK1E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtE,MAAM,YAAY,GAAG;;;sCAGe,CAAC,CAAC,UAAU,4BAA4B,CAAC,CAAC,WAAW;sCACrD,CAAC,CAAC,YAAY,4BAA4B,CAAC,CAAC,WAAW,qBAAqB,IAAI,CAAC,YAAY;;;sCAG7F,CAAC,CAAC,UAAU,4BAA4B,CAAC,CAAC,WAAW;sCACrD,CAAC,CAAC,YAAY,4BAA4B,CAAC,CAAC,WAAW,wDAAwD,IAAI,CAAC,UAAU;;IAGhK,IAAI,CAAC,SAAS;QACZ,CAAC,CAAC;sCAC8B,CAAC,CAAC,UAAU;sCACZ,CAAC,CAAC,YAAY,yCAAyC,IAAI,CAAC,SAAS;QACnG;QACF,CAAC,CAAC,EACN;SACO,CAAC;IAER,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErF,MAAM,IAAI,GAAG;6BACc,QAAQ;;0BAEX,IAAI,CAAC,YAAY;;EAEzC,YAAY;EACZ,GAAG,EAAE,CAAC;IAEN,MAAM,SAAS,GAAG;QAChB,QAAQ;QACR,EAAE;QACF,kBAAkB,IAAI,CAAC,YAAY,sCAAsC;QACzE,EAAE;QACF,gBAAgB,IAAI,CAAC,UAAU,EAAE;QACjC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,eAAe,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,kBAAkB,IAAI,CAAC,YAAY,gBAAgB,OAAO,EAAE;QACrE,IAAI,EAAE,WAAW,CAAC;YAChB,OAAO,EAAE,iBAAiB,IAAI,CAAC,YAAY,WAAW;YACtD,KAAK,EAAE,gBAAgB;YACvB,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;KAC3B,CAAC;AACJ,CAAC;AAaD,MAAM,UAAU,qBAAqB,CAAC,IAA0B;IAK9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtE,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY;QAClC,CAAC,CAAC;;;UAGI,IAAI,CAAC,YAAY;cACb;QACV,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnF,MAAM,IAAI,GAAG;6BACc,QAAQ;;qEAEgC,IAAI,CAAC,YAAY;0EACZ,IAAI,CAAC,UAAU;;;EAGvF,UAAU;;;;EAIV,GAAG,EAAE,CAAC;IAEN,OAAO;QACL,OAAO,EAAE,4BAA4B,IAAI,CAAC,YAAY,OAAO,OAAO,EAAE;QACtE,IAAI,EAAE,WAAW,CAAC;YAChB,OAAO,EAAE,2BAA2B,IAAI,CAAC,YAAY,EAAE;YACvD,KAAK,EAAE,qBAAqB;YAC5B,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,EAAE;YACJ,QAAQ;YACR,EAAE;YACF,kDAAkD,IAAI,CAAC,YAAY,MAAM,IAAI,CAAC,UAAU,IAAI;YAC5F,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,EAAE;YACF,8DAA8D;YAC9D,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC;AAWD,MAAM,UAAU,uBAAuB,CAAC,IAA4B;IAKlE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtE,MAAM,IAAI,GAAG;6BACc,QAAQ;;0BAEX,IAAI,CAAC,YAAY;0EAC+B,IAAI,CAAC,UAAU;;KAEpF,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE,aAAa,IAAI,CAAC,YAAY,eAAe,OAAO,EAAE;QAC/D,IAAI,EAAE,WAAW,CAAC;YAChB,OAAO,EAAE,YAAY,IAAI,CAAC,YAAY,UAAU;YAChD,KAAK,EAAE,kBAAkB;YACzB,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,EAAE;YACJ,QAAQ;YACR,EAAE;YACF,kBAAkB,IAAI,CAAC,YAAY,MAAM,IAAI,CAAC,UAAU,iCAAiC;SAC1F,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC;AAgBD,MAAM,UAAU,yBAAyB,CAAC,IAA8B;IAKtE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IAEtE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAExC,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QAC3C,SAAS,CAAC,IAAI,CAAC;;sCAEmB,CAAC,CAAC,UAAU,4BAA4B,CAAC,CAAC,WAAW;wDACnC,CAAC,CAAC,WAAW;oDACjB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;2BAClD,CAAC,CAAC,UAAU,wBAAwB,IAAI,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;;QAE5G,CAAC,CAAC;QACN,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QACjD,SAAS,CAAC,IAAI,CAAC;;sCAEmB,CAAC,CAAC,UAAU,4BAA4B,CAAC,CAAC,WAAW;wDACnC,CAAC,CAAC,WAAW;oDACjB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;2BACrD,CAAC,CAAC,UAAU,uBAAuB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE;;QAE/J,CAAC,CAAC;QACN,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/K,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QAC7C,SAAS,CAAC,IAAI,CAAC;;sCAEmB,CAAC,CAAC,UAAU;;oDAEE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;2BACnD,CAAC,CAAC,UAAU,uBAAuB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;;QAE3G,CAAC,CAAC;QACN,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzH,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM;QAC5B,CAAC,CAAC,mFAAmF,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU;QACjH,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;QACzB,CAAC,CAAC,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,UAAU,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,YAAY;YACjB,CAAC,CAAC,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC;YACjD,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,IAAI,GAAG;6BACc,QAAQ;;0BAEX,IAAI,CAAC,YAAY;;;EAGzC,KAAK;EACL,GAAG;kCAC6B,CAAC,CAAC,UAAU;;;KAGzC,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE,mBAAmB,IAAI,CAAC,YAAY,mCAAmC,OAAO,EAAE;QACzF,IAAI,EAAE,WAAW,CAAC;YAChB,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,+BAA+B;YAC5D,KAAK,EAAE,gBAAgB;YACvB,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,EAAE;YACJ,QAAQ;YACR,EAAE;YACF,kBAAkB,IAAI,CAAC,YAAY,iCAAiC;YACpE,EAAE;YACF,GAAG,UAAU;YACb,EAAE;YACF,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAClE,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface PasswordResetOptions {
2
+ userName?: string;
3
+ resetUrl: string;
4
+ expiresIn?: string;
5
+ appName?: string;
6
+ }
7
+ export declare function passwordResetTemplate(opts: PasswordResetOptions): {
8
+ subject: string;
9
+ html: string;
10
+ text: string;
11
+ };
12
+ //# sourceMappingURL=passwordReset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passwordReset.d.ts","sourceRoot":"","sources":["../../src/templates/passwordReset.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,oBAAoB,GAAG;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAoCA"}
@@ -0,0 +1,37 @@
1
+ import { emailLayout, emailButton } from "./_layout.js";
2
+ export function passwordResetTemplate(opts) {
3
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Platform";
4
+ const greeting = opts.userName ? `Hi ${opts.userName},` : "Hi there,";
5
+ const expiryNote = opts.expiresIn ? ` This link expires in ${opts.expiresIn}.` : "";
6
+ const body = `
7
+ <p style="margin:0 0 16px">${greeting}</p>
8
+ <p style="margin:0 0 16px">
9
+ We received a request to reset your password.${expiryNote} Click the button below to choose a new one.
10
+ </p>
11
+ ${emailButton("Reset my password", opts.resetUrl)}
12
+ <p style="margin:16px 0 0;font-size:14px;color:#64748b">
13
+ If you didn't request a password reset, you can safely ignore this email.
14
+ Your password won't change until you click the link above.
15
+ </p>`;
16
+ return {
17
+ subject: `Reset your password — ${appName}`,
18
+ html: emailLayout({
19
+ preview: `Reset your ${appName} password`,
20
+ title: "Reset your password",
21
+ body,
22
+ appName,
23
+ }),
24
+ text: [
25
+ greeting,
26
+ "",
27
+ "We received a request to reset your password.",
28
+ expiryNote,
29
+ "",
30
+ "Reset your password:",
31
+ opts.resetUrl,
32
+ "",
33
+ "If you didn't request this, you can safely ignore this email.",
34
+ ].join("\n"),
35
+ };
36
+ }
37
+ //# sourceMappingURL=passwordReset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passwordReset.js","sourceRoot":"","sources":["../../src/templates/passwordReset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AASxD,MAAM,UAAU,qBAAqB,CAAC,IAA0B;IAK9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;IACtE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpF,MAAM,IAAI,GAAG;6BACc,QAAQ;;iDAEY,UAAU;;EAEzD,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,QAAQ,CAAC;;;;KAI5C,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE,yBAAyB,OAAO,EAAE;QAC3C,IAAI,EAAE,WAAW,CAAC;YAChB,OAAO,EAAE,cAAc,OAAO,WAAW;YACzC,KAAK,EAAE,qBAAqB;YAC5B,IAAI;YACJ,OAAO;SACR,CAAC;QACF,IAAI,EAAE;YACJ,QAAQ;YACR,EAAE;YACF,+CAA+C;YAC/C,UAAU;YACV,EAAE;YACF,sBAAsB;YACtB,IAAI,CAAC,QAAQ;YACb,EAAE;YACF,+DAA+D;SAChE,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface SslFailedEmailOptions {
2
+ hostname: string;
3
+ serviceName: string;
4
+ teamName: string;
5
+ /** Machine-readable error: "cert_timeout" | "unreachable" | "tls_handshake_failed" */
6
+ sslError: string;
7
+ dashboardUrl: string;
8
+ appName?: string;
9
+ }
10
+ export declare function renderSslFailedEmail(opts: SslFailedEmailOptions): {
11
+ subject: string;
12
+ html: string;
13
+ text: string;
14
+ };
15
+ //# sourceMappingURL=sslFailed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sslFailed.d.ts","sourceRoot":"","sources":["../../src/templates/sslFailed.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CA6CA"}
@@ -0,0 +1,47 @@
1
+ import { emailLayout, emailButton, t } from "./_layout.js";
2
+ const SSL_ERROR_DESCRIPTIONS = {
3
+ cert_timeout: "Certificate issuance timed out. Make sure your domain is publicly reachable on port 80 and that your DNS record is correct.",
4
+ unreachable: "The domain is not reachable. Check that your service is running and that traffic is routing correctly to the platform.",
5
+ tls_handshake_failed: "TLS handshake failed during cert verification. The certificate may belong to a different domain.",
6
+ };
7
+ export function renderSslFailedEmail(opts) {
8
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Superrails";
9
+ const description = SSL_ERROR_DESCRIPTIONS[opts.sslError] ??
10
+ "An unknown error prevented SSL certificate issuance.";
11
+ const subject = `SSL certificate failed: ${opts.hostname}`;
12
+ const body = `
13
+ <p style="margin:0 0 16px;color:${t.bodyColor}">
14
+ The SSL certificate for <strong>${opts.hostname}</strong> (service: ${opts.serviceName})
15
+ could not be issued.
16
+ </p>
17
+ <div style="margin:0 0 20px;padding:16px;background:#fef2f2;border-left:4px solid #ef4444;
18
+ border-radius:0 8px 8px 0;font-size:14px;line-height:1.6;color:#7f1d1d">
19
+ ${description}
20
+ </div>
21
+ <p style="margin:0 0 20px;font-size:14px;color:#64748b">
22
+ Your custom domain is currently serving a broken HTTPS connection to visitors.
23
+ Visit the service settings to diagnose and retry.
24
+ </p>
25
+ ${emailButton("Fix SSL Issue", opts.dashboardUrl)}
26
+ <p style="margin:20px 0 0;font-size:13px;color:#94a3b8">
27
+ Team: ${opts.teamName}
28
+ </p>`;
29
+ const html = emailLayout({
30
+ preview: `SSL certificate failed for ${opts.hostname} — action required`,
31
+ title: `SSL certificate failed`,
32
+ body,
33
+ appName,
34
+ });
35
+ const text = [
36
+ `SSL certificate failed: ${opts.hostname}`,
37
+ ``,
38
+ description,
39
+ ``,
40
+ `Your custom domain is serving a broken HTTPS connection.`,
41
+ `Fix the issue: ${opts.dashboardUrl}`,
42
+ ``,
43
+ `Team: ${opts.teamName}`,
44
+ ].join("\n");
45
+ return { subject, html, text };
46
+ }
47
+ //# sourceMappingURL=sslFailed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sslFailed.js","sourceRoot":"","sources":["../../src/templates/sslFailed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AAY3D,MAAM,sBAAsB,GAA2B;IACrD,YAAY,EACV,6HAA6H;IAC/H,WAAW,EACT,wHAAwH;IAC1H,oBAAoB,EAClB,kGAAkG;CACrG,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,IAA2B;IAK9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC;IACxE,MAAM,WAAW,GACf,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACrC,sDAAsD,CAAC;IAEzD,MAAM,OAAO,GAAG,2BAA2B,IAAI,CAAC,QAAQ,EAAE,CAAC;IAE3D,MAAM,IAAI,GAAG;kCACmB,CAAC,CAAC,SAAS;oCACT,IAAI,CAAC,QAAQ,uBAAuB,IAAI,CAAC,WAAW;;;;;IAKpF,WAAW;;;;;;EAMb,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC,YAAY,CAAC;;UAEvC,IAAI,CAAC,QAAQ;KAClB,CAAC;IAEJ,MAAM,IAAI,GAAG,WAAW,CAAC;QACvB,OAAO,EAAE,8BAA8B,IAAI,CAAC,QAAQ,oBAAoB;QACxE,KAAK,EAAE,wBAAwB;QAC/B,IAAI;QACJ,OAAO;KACR,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG;QACX,2BAA2B,IAAI,CAAC,QAAQ,EAAE;QAC1C,EAAE;QACF,WAAW;QACX,EAAE;QACF,0DAA0D;QAC1D,kBAAkB,IAAI,CAAC,YAAY,EAAE;QACrC,EAAE;QACF,SAAS,IAAI,CAAC,QAAQ,EAAE;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface TeamInviteOptions {
2
+ inviterName: string;
3
+ inviterEmail: string;
4
+ teamName: string;
5
+ /** Role being granted: "admin" or "member" */
6
+ role: string;
7
+ acceptUrl: string;
8
+ expiresAt: Date;
9
+ appName?: string;
10
+ }
11
+ export declare function renderTeamInviteEmail(opts: TeamInviteOptions): string;
12
+ /** Full email object (subject + html + text) for use with any mailer adapter. */
13
+ export declare function teamInviteTemplate(opts: TeamInviteOptions): {
14
+ subject: string;
15
+ html: string;
16
+ text: string;
17
+ };
18
+ //# sourceMappingURL=teamInvite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamInvite.d.ts","sourceRoot":"","sources":["../../src/templates/teamInvite.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CA6BrE;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAoBA"}
@@ -0,0 +1,51 @@
1
+ import { emailLayout, emailButton } from "./_layout.js";
2
+ export function renderTeamInviteEmail(opts) {
3
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Superrails";
4
+ const roleLabel = opts.role === "admin" ? "Admin" : "Member";
5
+ const expiryStr = opts.expiresAt.toLocaleDateString("en-US", {
6
+ month: "long",
7
+ day: "numeric",
8
+ year: "numeric",
9
+ });
10
+ const body = `
11
+ <p style="margin:0 0 16px">Hi there,</p>
12
+ <p style="margin:0 0 16px">
13
+ <strong>${opts.inviterName}</strong> (${opts.inviterEmail}) has invited you to join
14
+ <strong>${opts.teamName}</strong> on ${appName} as <strong>${roleLabel}</strong>.
15
+ </p>
16
+ ${emailButton("Accept Invitation", opts.acceptUrl)}
17
+ <p style="margin:16px 0 0;font-size:14px;color:#64748b">
18
+ This invitation expires on <strong>${expiryStr}</strong>.
19
+ </p>
20
+ <p style="margin:8px 0 0;font-size:14px;color:#64748b">
21
+ If you weren't expecting this invitation, you can safely ignore this email.
22
+ </p>`;
23
+ return emailLayout({
24
+ preview: `${opts.inviterName} invited you to join ${opts.teamName}`,
25
+ title: `Join ${opts.teamName}`,
26
+ body,
27
+ appName,
28
+ });
29
+ }
30
+ /** Full email object (subject + html + text) for use with any mailer adapter. */
31
+ export function teamInviteTemplate(opts) {
32
+ const appName = opts.appName ?? process.env["APP_NAME"] ?? "Superrails";
33
+ const roleLabel = opts.role === "admin" ? "Admin" : "Member";
34
+ return {
35
+ subject: `${opts.inviterName} invited you to join ${opts.teamName} on ${appName}`,
36
+ html: renderTeamInviteEmail(opts),
37
+ text: [
38
+ `Hi there,`,
39
+ ``,
40
+ `${opts.inviterName} (${opts.inviterEmail}) has invited you to join ${opts.teamName} on ${appName} as ${roleLabel}.`,
41
+ ``,
42
+ `Accept your invitation:`,
43
+ opts.acceptUrl,
44
+ ``,
45
+ `This invitation expires on ${opts.expiresAt.toLocaleDateString()}.`,
46
+ ``,
47
+ `If you weren't expecting this, you can safely ignore this email.`,
48
+ ].join("\n"),
49
+ };
50
+ }
51
+ //# sourceMappingURL=teamInvite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teamInvite.js","sourceRoot":"","sources":["../../src/templates/teamInvite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAaxD,MAAM,UAAU,qBAAqB,CAAC,IAAuB;IAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE;QAC3D,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,SAAS;KAChB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG;;;YAGH,IAAI,CAAC,WAAW,cAAc,IAAI,CAAC,YAAY;YAC/C,IAAI,CAAC,QAAQ,gBAAgB,OAAO,eAAe,SAAS;;EAEtE,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC,SAAS,CAAC;;uCAEX,SAAS;;;;KAI3C,CAAC;IAEJ,OAAO,WAAW,CAAC;QACjB,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,wBAAwB,IAAI,CAAC,QAAQ,EAAE;QACnE,KAAK,EAAE,QAAQ,IAAI,CAAC,QAAQ,EAAE;QAC9B,IAAI;QACJ,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,IAAuB;IAKxD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE7D,OAAO;QACL,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,wBAAwB,IAAI,CAAC,QAAQ,OAAO,OAAO,EAAE;QACjF,IAAI,EAAE,qBAAqB,CAAC,IAAI,CAAC;QACjC,IAAI,EAAE;YACJ,WAAW;YACX,EAAE;YACF,GAAG,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,YAAY,6BAA6B,IAAI,CAAC,QAAQ,OAAO,OAAO,OAAO,SAAS,GAAG;YACpH,EAAE;YACF,yBAAyB;YACzB,IAAI,CAAC,SAAS;YACd,EAAE;YACF,8BAA8B,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,GAAG;YACpE,EAAE;YACF,kEAAkE;SACnE,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ export interface Recipient {
2
+ email: string;
3
+ name?: string;
4
+ }
5
+ export interface SendEmailOptions {
6
+ to: Recipient | Recipient[];
7
+ subject: string;
8
+ html: string;
9
+ text?: string;
10
+ from?: Recipient;
11
+ replyTo?: string;
12
+ }
13
+ export interface MailAdapter {
14
+ send(opts: SendEmailOptions): Promise<void>;
15
+ }
16
+ export interface MailerConfig {
17
+ /** Which transport to use. Default: "console" */
18
+ provider?: "nodemailer" | "resend" | "zeptomail" | "console";
19
+ from?: Recipient;
20
+ nodemailer?: {
21
+ host: string;
22
+ port: number;
23
+ secure?: boolean;
24
+ user?: string;
25
+ pass?: string;
26
+ };
27
+ resend?: {
28
+ apiKey: string;
29
+ };
30
+ zeptomail?: {
31
+ apiKey: string;
32
+ apiUrl?: string;
33
+ };
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,SAAS,GAAG,SAAS,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B,iDAAiD;IACjD,QAAQ,CAAC,EAAE,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;IAC7D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // ─── Core types ───────────────────────────────────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iFAAiF"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@aevr/mailer",
3
+ "version": "1.0.0",
4
+ "description": "Provider-agnostic email adapter framework. Switch between Resend, SMTP/Nodemailer, ZeptoMail, or console with one env var.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./templates": {
14
+ "types": "./dist/templates/index.d.ts",
15
+ "import": "./dist/templates/index.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "README.md",
21
+ "CHANGELOG.md"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc -p .",
25
+ "typecheck": "tsc --noEmit",
26
+ "prepublishOnly": "npm run build",
27
+ "release": "standard-version --tag-prefix mailer@v",
28
+ "release:patch": "standard-version --release-as patch --tag-prefix mailer@v",
29
+ "release:minor": "standard-version --release-as minor --tag-prefix mailer@v",
30
+ "release:major": "standard-version --release-as major --tag-prefix mailer@v"
31
+ },
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "license": "MIT",
36
+ "engines": {
37
+ "node": ">=20.0.0"
38
+ },
39
+ "dependencies": {
40
+ "nodemailer": "^6.10.1",
41
+ "resend": "^4.7.0",
42
+ "zeptomail": "^1.0.1"
43
+ },
44
+ "devDependencies": {
45
+ "@types/nodemailer": "^6.4.17",
46
+ "standard-version": "^9.5.0",
47
+ "typescript": "^5.7.2"
48
+ }
49
+ }