@razmatinyan/nuxt-email 0.1.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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +272 -0
  3. package/dist/module.d.mts +7 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +190 -0
  6. package/dist/runtime/server/api/config.get.d.ts +5 -0
  7. package/dist/runtime/server/api/config.get.js +10 -0
  8. package/dist/runtime/server/api/devtools.d.ts +2 -0
  9. package/dist/runtime/server/api/devtools.js +265 -0
  10. package/dist/runtime/server/api/log.get.d.ts +2 -0
  11. package/dist/runtime/server/api/log.get.js +5 -0
  12. package/dist/runtime/server/api/preview.d.ts +2 -0
  13. package/dist/runtime/server/api/preview.js +12 -0
  14. package/dist/runtime/server/api/send-test.post.d.ts +2 -0
  15. package/dist/runtime/server/api/send-test.post.js +33 -0
  16. package/dist/runtime/server/api/templates.get.d.ts +5 -0
  17. package/dist/runtime/server/api/templates.get.js +8 -0
  18. package/dist/runtime/server/composables/useEmail.d.ts +9 -0
  19. package/dist/runtime/server/composables/useEmail.js +96 -0
  20. package/dist/runtime/server/utils/dev-log.d.ts +14 -0
  21. package/dist/runtime/server/utils/dev-log.js +8 -0
  22. package/dist/runtime/server/utils/email-utils.d.ts +9 -0
  23. package/dist/runtime/server/utils/email-utils.js +134 -0
  24. package/dist/runtime/server/utils/providers/console.d.ts +6 -0
  25. package/dist/runtime/server/utils/providers/console.js +44 -0
  26. package/dist/runtime/server/utils/providers/fetch.d.ts +1 -0
  27. package/dist/runtime/server/utils/providers/index.d.ts +9 -0
  28. package/dist/runtime/server/utils/providers/index.js +33 -0
  29. package/dist/runtime/server/utils/providers/postmark.d.ts +8 -0
  30. package/dist/runtime/server/utils/providers/postmark.js +94 -0
  31. package/dist/runtime/server/utils/providers/resend.d.ts +8 -0
  32. package/dist/runtime/server/utils/providers/resend.js +73 -0
  33. package/dist/runtime/server/utils/providers/sendgrid.d.ts +8 -0
  34. package/dist/runtime/server/utils/providers/sendgrid.js +99 -0
  35. package/dist/runtime/server/utils/providers/shared.d.ts +7 -0
  36. package/dist/runtime/server/utils/providers/shared.js +29 -0
  37. package/dist/runtime/server/utils/providers/smtp.d.ts +8 -0
  38. package/dist/runtime/server/utils/providers/smtp.js +85 -0
  39. package/dist/runtime/server/utils/template-renderer.d.ts +5 -0
  40. package/dist/runtime/server/utils/template-renderer.js +10 -0
  41. package/dist/runtime/server/utils/templates.d.ts +4 -0
  42. package/dist/runtime/server/utils/templates.js +17 -0
  43. package/dist/runtime/templates.d.ts +6 -0
  44. package/dist/runtime/types/index.d.ts +110 -0
  45. package/dist/runtime/types/index.js +0 -0
  46. package/dist/types.d.mts +9 -0
  47. package/package.json +84 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Razmik Matinyan <razmatinyan28@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # nuxt-email
2
+
3
+ Transactional email for Nuxt 4: a provider-agnostic API, Vue-powered templates, and type-safe server composables.
4
+
5
+ - 📨 **One API, many providers** — Resend, SendGrid, Postmark, SMTP, and a console provider for local dev
6
+ - 🧩 **Vue email templates** — author emails as `.vue` files, rendered on the server and CSS-inlined
7
+ - 🔒 **Server-only & type-safe** — credentials stay private; `useEmail()` is auto-imported in your server routes
8
+ - 📎 **Attachments, CC/BCC, reply-to, headers, tags, and scheduling**
9
+ - 🔁 **Automatic retries** on transient failures, plus batch sending with a concurrency limit
10
+ - 🛠 **Nuxt DevTools tab** — browse templates, live-preview them, send a test, and watch a send log
11
+
12
+ ## Quick Setup
13
+
14
+ ```bash
15
+ npm install @razmatinyan/nuxt-email
16
+ ```
17
+
18
+ ```ts
19
+ // nuxt.config.ts
20
+ export default defineNuxtConfig({
21
+ modules: ['@razmatinyan/nuxt-email'],
22
+ email: {
23
+ provider: 'console', // logs to the terminal during development
24
+ from: 'App <noreply@myapp.com>',
25
+ },
26
+ })
27
+ ```
28
+
29
+ Send your first email from any server route:
30
+
31
+ ```ts
32
+ // server/api/register.post.ts
33
+ export default defineEventHandler(async (event) => {
34
+ const { sendEmail } = useEmail() // auto-imported on the server
35
+
36
+ const result = await sendEmail({
37
+ to: 'user@example.com',
38
+ subject: 'Welcome!',
39
+ html: '<h1>Welcome!</h1><p>Thanks for signing up.</p>',
40
+ })
41
+
42
+ if (!result.success) {
43
+ console.error('Email failed:', result.error)
44
+ }
45
+
46
+ return result
47
+ })
48
+ ```
49
+
50
+ ## Providers
51
+
52
+ All providers share the same API — switch by changing `provider` in `nuxt.config.ts`, no code changes.
53
+
54
+ | Provider | Transport | Extra dependency |
55
+ |------------|--------------------|-------------------------|
56
+ | `console` | Logs to stdout | — |
57
+ | `resend` | REST (`$fetch`) | — |
58
+ | `sendgrid` | REST (`$fetch`) | — |
59
+ | `postmark` | REST (`$fetch`) | — |
60
+ | `smtp` | `nodemailer` | `npm install nodemailer` (optional peer dependency) |
61
+
62
+ The REST providers use Nitro's built-in `$fetch`, so no SDKs are added to your dependency tree. SMTP needs `nodemailer`, which is an optional peer dependency you install only if you use it.
63
+
64
+ ```ts
65
+ export default defineNuxtConfig({
66
+ email: {
67
+ provider: 'resend',
68
+ from: 'Acme <hello@acme.com>',
69
+ apiKey: process.env.NUXT_EMAIL_API_KEY,
70
+ },
71
+ })
72
+ ```
73
+
74
+ ```ini
75
+ # .env
76
+ NUXT_EMAIL_API_KEY=re_your_key_here
77
+ ```
78
+
79
+ For SMTP:
80
+
81
+ ```ts
82
+ email: {
83
+ provider: 'smtp',
84
+ from: 'Acme <hello@acme.com>',
85
+ smtp: {
86
+ host: 'smtp.example.com',
87
+ port: 587,
88
+ user: process.env.SMTP_USER,
89
+ pass: process.env.SMTP_PASS,
90
+ secure: false, // true for port 465
91
+ },
92
+ }
93
+ ```
94
+
95
+ ### Multiple providers
96
+
97
+ Give each provider its own credentials with the optional `providers` map. Each entry overrides the top-level `apiKey` / `smtp` / `from` for that provider, so you can switch providers per call without reconfiguring:
98
+
99
+ ```ts
100
+ email: {
101
+ provider: 'resend', // the default
102
+ from: 'Acme <hello@acme.com>',
103
+ providers: {
104
+ resend: { apiKey: process.env.RESEND_API_KEY },
105
+ postmark: { apiKey: process.env.POSTMARK_API_KEY, from: 'Acme <tx@acme.com>' },
106
+ smtp: { smtp: { host: 'smtp.example.com', user: process.env.SMTP_USER, pass: process.env.SMTP_PASS } },
107
+ },
108
+ }
109
+ ```
110
+
111
+ ```ts
112
+ // uses the matching credentials from `providers.postmark`
113
+ await sendEmail({ to, subject, template, props }, { provider: 'postmark' })
114
+ ```
115
+
116
+ If you only use one provider, the top-level `apiKey`/`smtp` is all you need — `providers` is optional.
117
+
118
+ ## Vue email templates
119
+
120
+ Drop a `.vue` file into `server/emails/` (configurable via `templateDir`) and reference it by filename:
121
+
122
+ ```vue
123
+ <!-- server/emails/welcome.vue -->
124
+ <script setup lang="ts">
125
+ defineProps<{ name: string, verifyUrl: string }>()
126
+ </script>
127
+
128
+ <template>
129
+ <div style="font-family: sans-serif; padding: 24px;">
130
+ <h1>Welcome, {{ name }}!</h1>
131
+ <p>Please confirm your email address.</p>
132
+ <a :href="verifyUrl">Verify</a>
133
+ </div>
134
+ </template>
135
+ ```
136
+
137
+ ```ts
138
+ await sendEmail({
139
+ to: user.email,
140
+ subject: 'Welcome to Acme!',
141
+ template: 'welcome',
142
+ props: { name: user.name, verifyUrl: 'https://acme.com/verify?token=abc' },
143
+ })
144
+ ```
145
+
146
+ The template is rendered to HTML on the server, CSS is inlined for email-client compatibility, and a plain-text fallback is generated automatically. Style with inline `style` attributes or `<style>` blocks inside the `<template>` — SFC `<style>` blocks are stripped during compilation and won't be inlined.
147
+
148
+ ### Preview data
149
+
150
+ Export `previewProps` from a plain `<script>` block to give the dev preview and DevTools sample data:
151
+
152
+ ```vue
153
+ <script lang="ts">
154
+ export const previewProps = {
155
+ name: 'Jane Doe',
156
+ verifyUrl: 'https://example.com/verify',
157
+ }
158
+ </script>
159
+ ```
160
+
161
+ ## Sending options
162
+
163
+ ```ts
164
+ await sendEmail({
165
+ to: ['a@example.com', 'b@example.com'],
166
+ cc: 'manager@example.com',
167
+ bcc: 'audit@example.com',
168
+ replyTo: 'support@example.com',
169
+ from: 'Billing <billing@acme.com>', // overrides the default `from`
170
+ subject: 'Your invoice',
171
+ template: 'invoice',
172
+ props: { total: '$99.00' },
173
+ headers: { 'X-Entity-Ref-Id': 'inv_123' },
174
+ tags: { category: 'billing' }, // resend, sendgrid, postmark
175
+ scheduledAt: new Date(Date.now() + 3600_000), // resend, sendgrid
176
+ attachments: [
177
+ {
178
+ filename: 'invoice.pdf',
179
+ content: pdfBuffer, // string or Buffer
180
+ contentType: 'application/pdf',
181
+ },
182
+ ],
183
+ })
184
+ ```
185
+
186
+ Every send returns a structured result (never throws from a provider):
187
+
188
+ ```ts
189
+ interface EmailResponse {
190
+ success: boolean
191
+ messageId?: string
192
+ error?: string
193
+ provider: string
194
+ duration: number // ms
195
+ }
196
+ ```
197
+
198
+ `tags` and `scheduledAt` are applied by the providers that support them and ignored by the rest.
199
+
200
+ ### Batch sending
201
+
202
+ ```ts
203
+ const { sendBatch } = useEmail()
204
+
205
+ const results = await sendBatch(
206
+ users.map(u => ({ to: u.email, subject: 'Newsletter', template: 'newsletter', props: { name: u.name } })),
207
+ { concurrency: 10 }, // default 5
208
+ )
209
+
210
+ const failed = results.filter(r => !r.success)
211
+ ```
212
+
213
+ ### Per-call provider override
214
+
215
+ Override the configured provider for a single send (handy for testing). The override reuses the same credentials, so only providers whose credentials are configured will succeed — `console` always works:
216
+
217
+ ```ts
218
+ await sendEmail({ to: 'me@example.com', subject: 'Test', template: 'welcome', props }, { provider: 'console' })
219
+ ```
220
+
221
+ ## Reliability & validation
222
+
223
+ - **Retries** — failures that look transient (HTTP 429/5xx, timeouts, connection resets) are retried up to `retries` times with a growing delay. Client errors (4xx) are not retried.
224
+ - **Validation** — recipient addresses (`to`/`cc`/`bcc`/`replyTo`) and `from` are validated, `"Name <email>"` form is accepted, and newlines are rejected to prevent header injection. Attachments must have a `filename` and `content`.
225
+ - **Prerendering** — sends are skipped during `nuxi generate` / prerendering and return a no-op success.
226
+
227
+ ## DevTools
228
+
229
+ In dev, an **Email** tab appears in Nuxt DevTools. From it you can browse discovered templates, live-preview them (using their `previewProps`), pick a provider and send a test email, and watch an in-session send log. The panel follows the DevTools light/dark theme.
230
+
231
+ These dev-only routes back the tab (and are handy on their own):
232
+
233
+ | Route | Purpose |
234
+ |--------------------------------|------------------------------------------|
235
+ | `GET /_email/preview/:template`| Render a template to HTML |
236
+ | `GET /_email/templates` | List templates and their preview props |
237
+ | `POST /_email/send-test/:template` | Send a test email |
238
+ | `GET /_email/log` | Recent sends from this dev session |
239
+ | `GET /_email/config` | Configured provider and available list |
240
+
241
+ Set `preview: false` to disable them.
242
+
243
+ ## Configuration
244
+
245
+ | Option | Type | Default | Description |
246
+ |---------------|-----------|-------------------|--------------------------------------|
247
+ | `provider` | string | `'console'` | `console` · `resend` · `sendgrid` · `postmark` · `smtp` |
248
+ | `from` | string | — | Default sender (`"Name <email>"` or `email`) |
249
+ | `apiKey` | string | — | API key for the REST providers |
250
+ | `smtp` | object | — | `{ host, port?, user?, pass?, secure? }` |
251
+ | `providers` | object | — | Per-provider credentials, e.g. `{ resend: { apiKey }, smtp: { smtp: {...} } }` |
252
+ | `templateDir` | string | `'server/emails'` | Directory scanned for `.vue` templates |
253
+ | `preview` | boolean | `true` | Enable dev preview routes + DevTools tab |
254
+ | `retries` | number | `2` | Retry attempts on transient failures |
255
+ | `retryDelay` | number | `1000` | Base delay between retries (ms) |
256
+
257
+ Keep secrets in `.env` and read them via `process.env` in `nuxt.config.ts`, as shown above. Provider credentials live in private runtime config and are never exposed to the client.
258
+
259
+ ## Development
260
+
261
+ ```bash
262
+ npm install # install dependencies
263
+ npm run dev:prepare # build module stubs (run once after cloning)
264
+ npm run dev # playground at http://localhost:3000
265
+ npm run test:unit # fast unit tests
266
+ npm run test:integration # boots Nuxt, slower
267
+ npx tsc --noEmit # type-check
268
+ ```
269
+
270
+ ## License
271
+
272
+ [MIT](./LICENSE)
@@ -0,0 +1,7 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { EmailModuleOptions } from '../dist/runtime/types/index.js';
3
+ export { EmailAttachment, EmailModuleOptions, EmailPayload, EmailProvider, EmailResponse, NormalizedPayload } from '../dist/runtime/types/index.js';
4
+
5
+ declare const _default: _nuxt_schema.NuxtModule<EmailModuleOptions, EmailModuleOptions, false>;
6
+
7
+ export { _default as default };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "nuxt-email",
3
+ "configKey": "email",
4
+ "compatibility": {
5
+ "nuxt": ">=4.0.0"
6
+ },
7
+ "version": "0.1.0",
8
+ "builder": {
9
+ "@nuxt/module-builder": "1.0.2",
10
+ "unbuild": "3.6.1"
11
+ }
12
+ }
@@ -0,0 +1,190 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { resolve, join, relative } from 'node:path';
3
+ import { defineNuxtModule, useLogger, createResolver, addTemplate, addServerImports, addServerHandler, addTypeTemplate } from '@nuxt/kit';
4
+ import { addCustomTab } from '@nuxt/devtools-kit';
5
+ import vuePlugin from 'unplugin-vue/rollup';
6
+
7
+ const MODULE_NAME = "nuxt-email";
8
+ const CONFIG_KEY = "email";
9
+ const VALID_PROVIDERS = ["console", "resend", "sendgrid", "postmark", "smtp"];
10
+ function flattenProviders(providers) {
11
+ if (!providers) return void 0;
12
+ const result = {};
13
+ for (const [name, opts] of Object.entries(providers)) {
14
+ if (!opts) continue;
15
+ result[name] = {
16
+ apiKey: opts.apiKey,
17
+ from: opts.from,
18
+ smtpHost: opts.smtp?.host,
19
+ smtpPort: opts.smtp?.port,
20
+ smtpUser: opts.smtp?.user,
21
+ smtpPass: opts.smtp?.pass,
22
+ smtpSecure: opts.smtp?.secure
23
+ };
24
+ }
25
+ return result;
26
+ }
27
+ function scanTemplates(dir) {
28
+ if (!existsSync(dir)) return [];
29
+ const found = [];
30
+ const walk = (current) => {
31
+ for (const entry of readdirSync(current, { withFileTypes: true })) {
32
+ const full = join(current, entry.name);
33
+ if (entry.isDirectory()) {
34
+ walk(full);
35
+ } else if (entry.isFile() && entry.name.endsWith(".vue")) {
36
+ const name = relative(dir, full).replace(/\\/g, "/").replace(/\.vue$/, "");
37
+ found.push({ name, absPath: full });
38
+ }
39
+ }
40
+ };
41
+ walk(dir);
42
+ return found;
43
+ }
44
+ const module$1 = defineNuxtModule({
45
+ meta: {
46
+ name: MODULE_NAME,
47
+ configKey: CONFIG_KEY,
48
+ compatibility: {
49
+ nuxt: ">=4.0.0"
50
+ }
51
+ },
52
+ defaults: {
53
+ provider: "console",
54
+ from: void 0,
55
+ templateDir: "server/emails",
56
+ preview: true,
57
+ retries: 2,
58
+ retryDelay: 1e3
59
+ },
60
+ setup(options, nuxt) {
61
+ const logger = useLogger(MODULE_NAME);
62
+ const { resolve: resolve$1 } = createResolver(import.meta.url);
63
+ if (!VALID_PROVIDERS.includes(options.provider)) {
64
+ throw new Error(
65
+ `[nuxt-email] Unknown provider "${options.provider}". Valid options: ${VALID_PROVIDERS.join(", ")}`
66
+ );
67
+ }
68
+ if (options.provider !== "console" && !options.from) {
69
+ logger.warn(
70
+ "`email.from` is not set. Emails will fail unless `from` is passed per-call. Set `email.from` in nuxt.config.ts."
71
+ );
72
+ }
73
+ const runtimeConfig = nuxt.options.runtimeConfig;
74
+ runtimeConfig._email = {
75
+ provider: options.provider,
76
+ apiKey: options.apiKey ?? "",
77
+ from: options.from ?? "",
78
+ smtpHost: options.smtp?.host ?? "",
79
+ smtpPort: options.smtp?.port ?? 587,
80
+ smtpUser: options.smtp?.user ?? "",
81
+ smtpPass: options.smtp?.pass ?? "",
82
+ smtpSecure: options.smtp?.secure ?? false,
83
+ retries: options.retries,
84
+ retryDelay: options.retryDelay,
85
+ providers: flattenProviders(options.providers)
86
+ };
87
+ const templatesDir = resolve(
88
+ nuxt.options.rootDir,
89
+ options.templateDir
90
+ );
91
+ const templatesFile = addTemplate({
92
+ filename: "nuxt-email/templates.mjs",
93
+ write: true,
94
+ getContents: () => {
95
+ const templates = scanTemplates(templatesDir);
96
+ const imports = templates.map(
97
+ (t, i) => `import * as t${i} from ${JSON.stringify(t.absPath.replace(/\\/g, "/"))}`
98
+ ).join("\n");
99
+ const entries = templates.map(
100
+ (t, i) => ` ${JSON.stringify(t.name)}: t${i}.default,`
101
+ ).join("\n");
102
+ const previewEntries = templates.map((t, i) => ` ${JSON.stringify(t.name)}: __pp(t${i}),`).join("\n");
103
+ return `${imports}
104
+
105
+ const __pp = m => (m && m.previewProps) ? m.previewProps : {}
106
+
107
+ export const templates = {
108
+ ${entries}
109
+ }
110
+
111
+ export const previewProps = {
112
+ ${previewEntries}
113
+ }
114
+ `;
115
+ }
116
+ });
117
+ const templatesFilePath = templatesFile.dst.replace(/\\/g, "/");
118
+ const templatesDirPath = templatesDir.replace(/\\/g, "/");
119
+ const onNitroConfig = nuxt.hook;
120
+ onNitroConfig("nitro:config", (config) => {
121
+ config.alias = config.alias || {};
122
+ config.alias["#nuxt-email/templates"] = templatesFilePath;
123
+ config.externals = config.externals || {};
124
+ config.externals.inline = config.externals.inline || [];
125
+ config.externals.inline.push(templatesFilePath, templatesDirPath);
126
+ config.rollupConfig = config.rollupConfig || {};
127
+ config.rollupConfig.plugins = config.rollupConfig.plugins || [];
128
+ config.rollupConfig.plugins.push(vuePlugin());
129
+ });
130
+ addServerImports([
131
+ {
132
+ name: "useEmail",
133
+ from: resolve$1("./runtime/server/composables/useEmail")
134
+ }
135
+ ]);
136
+ if (nuxt.options.dev && options.preview) {
137
+ addServerHandler({
138
+ route: "/_email/preview/:template",
139
+ handler: resolve$1("./runtime/server/api/preview")
140
+ });
141
+ addServerHandler({
142
+ route: "/_email/send-test/:template",
143
+ method: "post",
144
+ handler: resolve$1("./runtime/server/api/send-test.post")
145
+ });
146
+ addServerHandler({
147
+ route: "/_email/templates",
148
+ method: "get",
149
+ handler: resolve$1("./runtime/server/api/templates.get")
150
+ });
151
+ addServerHandler({
152
+ route: "/_email/log",
153
+ method: "get",
154
+ handler: resolve$1("./runtime/server/api/log.get")
155
+ });
156
+ addServerHandler({
157
+ route: "/_email/config",
158
+ method: "get",
159
+ handler: resolve$1("./runtime/server/api/config.get")
160
+ });
161
+ addServerHandler({
162
+ route: "/_email/devtools",
163
+ handler: resolve$1("./runtime/server/api/devtools")
164
+ });
165
+ addCustomTab({
166
+ name: "nuxt-email",
167
+ title: "Email",
168
+ icon: "carbon:email",
169
+ view: { type: "iframe", src: "/_email/devtools" }
170
+ });
171
+ }
172
+ addTypeTemplate({
173
+ filename: "types/nuxt-email.d.ts",
174
+ getContents: () => `
175
+ import type { EmailRuntimeConfig } from '${resolve$1("./runtime/types/index.js")}'
176
+
177
+ declare module 'nitropack' {
178
+ interface NitroRuntimeConfig {
179
+ _email: EmailRuntimeConfig
180
+ }
181
+ }
182
+
183
+ export {}
184
+ `
185
+ });
186
+ logger.success(`nuxt-email ready (provider: ${options.provider})`);
187
+ }
188
+ });
189
+
190
+ export { module$1 as default };
@@ -0,0 +1,5 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, {
2
+ provider: string;
3
+ providers: ("resend" | "sendgrid" | "postmark" | "smtp" | "console")[];
4
+ }>;
5
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import { defineEventHandler } from "h3";
2
+ import { useRuntimeConfig } from "nitropack/runtime";
3
+ import { VALID_PROVIDERS } from "../utils/providers/index.js";
4
+ export default defineEventHandler(() => {
5
+ const config = useRuntimeConfig()._email;
6
+ return {
7
+ provider: config.provider,
8
+ providers: VALID_PROVIDERS
9
+ };
10
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Response>;
2
+ export default _default;