@numoteq/emdash-plugin-jetemail 0.3.0 → 0.4.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.
- package/README.md +25 -12
- package/dist/client.d.mts +6 -1
- package/dist/client.mjs +10 -2
- package/dist/{config-DcMo9a49.d.mts → config-BaMQYoEl.d.mts} +5 -2
- package/dist/index.mjs +1 -1
- package/dist/manifest.json +1 -1
- package/dist/native/index.d.mts +11 -2
- package/dist/native/index.mjs +11 -2
- package/dist/native/plugin.d.mts +11 -3
- package/dist/native/plugin.mjs +6 -22
- package/dist/plugin.mjs +1 -1
- package/dist/send-DoICK33S.mjs +70 -0
- package/package.json +1 -1
- package/dist/config-Bdqx5Bs6.mjs +0 -9
package/README.md
CHANGED
|
@@ -11,21 +11,22 @@ pnpm add @numoteq/emdash-plugin-jetemail
|
|
|
11
11
|
Register the package in the site's sandboxed plugin configuration, activate it, then select **JetEmail** under **Settings > Email**. Open the plugin settings and enter:
|
|
12
12
|
|
|
13
13
|
- A JetEmail transactional API key (`transactional_…`) allowed to send from the sender's domain.
|
|
14
|
-
- The sender
|
|
14
|
+
- The sender email. The sender domain must be verified in JetEmail.
|
|
15
|
+
- Optionally the sender name (defaults to the site title) and a Reply-To address.
|
|
15
16
|
|
|
16
17
|
If the domain publishes JetEmail Domain Security (`_jm` TXT), add the API key's UUID to it, otherwise JetEmail rejects the message.
|
|
17
18
|
|
|
18
|
-
The key is stored in the plugin-scoped KV store and is sent only to `https://api.jetemail.com/email`. The plugin requests only the fixed-host network and email transport registration capabilities. Recipients, CC and reply-to are passed through; EmDash email has no attachments.
|
|
19
|
+
The key is stored in the plugin-scoped KV store and is sent only to `https://api.jetemail.com/email`. The plugin requests only the fixed-host network and email transport registration capabilities. Recipients, CC and reply-to are passed through; a message's own reply-to wins over the configured one. EmDash email has no attachments.
|
|
19
20
|
|
|
20
21
|
## Native use (Cloudflare Workers sites)
|
|
21
22
|
|
|
22
|
-
Sites that configure EmDash in code
|
|
23
|
+
Sites that configure EmDash in code register the transport in `astro.config.mjs` instead; the API key lives in a Worker secret and nothing is set in the admin:
|
|
23
24
|
|
|
24
25
|
```js
|
|
25
26
|
import { jetEmail } from "@numoteq/emdash-plugin-jetemail/native";
|
|
26
27
|
|
|
27
28
|
emdash({
|
|
28
|
-
plugins: [jetEmail({ from: { email: "noreply@example.com",
|
|
29
|
+
plugins: [jetEmail({ from: { email: "noreply@example.com" }, replyTo: "info@example.com" })],
|
|
29
30
|
});
|
|
30
31
|
```
|
|
31
32
|
|
|
@@ -33,18 +34,30 @@ emdash({
|
|
|
33
34
|
wrangler secret put JETEMAIL_API_KEY
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
- `from.name` is optional and defaults to the site title (Settings > General).
|
|
38
|
+
- `replyTo` applies when a message sets none.
|
|
39
|
+
- EmDash selects the provider automatically when it is the only one.
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
import { deliverWithJetEmail } from "@numoteq/emdash-plugin-jetemail/client";
|
|
41
|
+
Site code (forms, Workflows) sends through the same sender with `sendEmail`, which also supports attachments. It throws on failure; a `JetEmailError` carries the HTTP status.
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
```ts
|
|
44
|
+
import { sendEmail } from "@numoteq/emdash-plugin-jetemail/native";
|
|
45
|
+
|
|
46
|
+
await sendEmail(mailConfig, {
|
|
47
|
+
to: "team@example.com",
|
|
48
|
+
replyTo: visitorEmail,
|
|
49
|
+
subject: "New enquiry",
|
|
50
|
+
text,
|
|
51
|
+
attachments: [{ filename: "offer.pdf", content: pdfBytes }],
|
|
52
|
+
});
|
|
46
53
|
```
|
|
47
54
|
|
|
55
|
+
Pass the same config object to `jetEmail()` and `sendEmail()`, for example from a shared `src/mail-config.ts`.
|
|
56
|
+
|
|
57
|
+
### E2E and local runs without a key
|
|
58
|
+
|
|
59
|
+
With the Worker variable `JETEMAIL_DRY_RUN` set to exactly `true`, nothing is sent: each message is logged as a warning (from, to, reply-to, subject) and reported as sent. Set it only in the E2E Wrangler config, never in production. Without it, a missing `JETEMAIL_API_KEY` fails the send.
|
|
60
|
+
|
|
48
61
|
## Development
|
|
49
62
|
|
|
50
63
|
```sh
|
package/dist/client.d.mts
CHANGED
|
@@ -19,9 +19,14 @@ interface JetEmailMessage {
|
|
|
19
19
|
attachments?: JetEmailAttachment[];
|
|
20
20
|
}
|
|
21
21
|
type FetchFn = (url: string, init?: RequestInit) => Promise<Response>;
|
|
22
|
+
/** JetEmail answered with a non-2xx status. HTTP 429 means the message was not accepted. */
|
|
23
|
+
declare class JetEmailError extends Error {
|
|
24
|
+
readonly status: number;
|
|
25
|
+
constructor(message: string, status: number);
|
|
26
|
+
}
|
|
22
27
|
declare function formatSender(name: string, email: string): string;
|
|
23
28
|
declare function deliverWithJetEmail(fetchFn: FetchFn, sender: JetEmailSender, message: JetEmailMessage): Promise<{
|
|
24
29
|
id?: string;
|
|
25
30
|
}>;
|
|
26
31
|
//#endregion
|
|
27
|
-
export { FetchFn, JetEmailAttachment, JetEmailMessage, JetEmailSender, deliverWithJetEmail, formatSender };
|
|
32
|
+
export { FetchFn, JetEmailAttachment, JetEmailError, JetEmailMessage, JetEmailSender, deliverWithJetEmail, formatSender };
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
//#region src/client.ts
|
|
2
2
|
const API_URL = "https://api.jetemail.com/email";
|
|
3
|
+
/** JetEmail answered with a non-2xx status. HTTP 429 means the message was not accepted. */
|
|
4
|
+
var JetEmailError = class extends Error {
|
|
5
|
+
constructor(message, status) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.name = "JetEmailError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
3
11
|
function formatSender(name, email) {
|
|
4
12
|
return `${name.replace(/[<>"\r\n]/g, "").trim()} <${email}>`;
|
|
5
13
|
}
|
|
@@ -33,11 +41,11 @@ async function deliverWithJetEmail(fetchFn, sender, message) {
|
|
|
33
41
|
});
|
|
34
42
|
if (!response.ok) {
|
|
35
43
|
const detail = (await response.text()).slice(0, 500);
|
|
36
|
-
throw new
|
|
44
|
+
throw new JetEmailError(`JetEmail rejected the message with HTTP ${response.status}${detail ? `: ${detail}` : ""}`, response.status);
|
|
37
45
|
}
|
|
38
46
|
const result = await response.json().catch(() => ({}));
|
|
39
47
|
return typeof result.id === "string" ? { id: result.id } : {};
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
//#endregion
|
|
43
|
-
export { deliverWithJetEmail, formatSender };
|
|
51
|
+
export { JetEmailError, deliverWithJetEmail, formatSender };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
//#region src/native/config.d.ts
|
|
2
2
|
interface JetEmailConfig {
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Sender. The domain must be verified in JetEmail and allowed for the API key.
|
|
5
|
+
* The name defaults to the site title from EmDash settings.
|
|
6
|
+
*/
|
|
4
7
|
from: {
|
|
5
8
|
email: string;
|
|
6
|
-
name
|
|
9
|
+
name?: string;
|
|
7
10
|
};
|
|
8
11
|
/** Reply-To used when the message sets none. */
|
|
9
12
|
replyTo?: string;
|
package/dist/index.mjs
CHANGED
package/dist/manifest.json
CHANGED
package/dist/native/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JetEmailAttachment, JetEmailError, JetEmailMessage } from "../client.mjs";
|
|
2
|
+
import { t as JetEmailConfig } from "../config-BaMQYoEl.mjs";
|
|
2
3
|
import { PluginDescriptor } from "emdash";
|
|
3
4
|
|
|
4
5
|
//#region src/native/index.d.ts
|
|
@@ -7,5 +8,13 @@ import { PluginDescriptor } from "emdash";
|
|
|
7
8
|
* delivery time from a Worker secret (default `JETEMAIL_API_KEY`), so nothing is configured in the admin.
|
|
8
9
|
*/
|
|
9
10
|
declare function jetEmail(config: JetEmailConfig): PluginDescriptor<JetEmailConfig>;
|
|
11
|
+
/**
|
|
12
|
+
* Sends a message from site code (forms, Workflows) with the same sender as {@link jetEmail}.
|
|
13
|
+
* Supports attachments, which EmDash email cannot carry. Throws on failure; a
|
|
14
|
+
* {@link JetEmailError} carries the HTTP status.
|
|
15
|
+
*/
|
|
16
|
+
declare function sendEmail(config: JetEmailConfig, message: JetEmailMessage): Promise<{
|
|
17
|
+
id?: string;
|
|
18
|
+
}>;
|
|
10
19
|
//#endregion
|
|
11
|
-
export { type JetEmailConfig, jetEmail as default, jetEmail };
|
|
20
|
+
export { type JetEmailAttachment, type JetEmailConfig, JetEmailError, type JetEmailMessage, jetEmail as default, jetEmail, sendEmail };
|
package/dist/native/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JetEmailError } from "../client.mjs";
|
|
2
|
+
import { a as assertValidConfig, i as PLUGIN_VERSION, n as sendWithConfig, r as PLUGIN_ID, t as defaultDeps } from "../send-DoICK33S.mjs";
|
|
2
3
|
|
|
3
4
|
//#region src/native/index.ts
|
|
4
5
|
/**
|
|
@@ -16,6 +17,14 @@ function jetEmail(config) {
|
|
|
16
17
|
capabilities: ["hooks.email-transport:register"]
|
|
17
18
|
};
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Sends a message from site code (forms, Workflows) with the same sender as {@link jetEmail}.
|
|
22
|
+
* Supports attachments, which EmDash email cannot carry. Throws on failure; a
|
|
23
|
+
* {@link JetEmailError} carries the HTTP status.
|
|
24
|
+
*/
|
|
25
|
+
function sendEmail(config, message) {
|
|
26
|
+
return sendWithConfig(config, message, defaultDeps);
|
|
27
|
+
}
|
|
19
28
|
|
|
20
29
|
//#endregion
|
|
21
|
-
export { jetEmail as default, jetEmail };
|
|
30
|
+
export { JetEmailError, jetEmail as default, jetEmail, sendEmail };
|
package/dist/native/plugin.d.mts
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FetchFn } from "../client.mjs";
|
|
2
|
+
import { t as JetEmailConfig } from "../config-BaMQYoEl.mjs";
|
|
2
3
|
import * as emdash from "emdash";
|
|
3
4
|
import { EmailDeliverEvent, PluginContext } from "emdash/plugin";
|
|
4
5
|
|
|
6
|
+
//#region src/native/send.d.ts
|
|
7
|
+
interface SendDeps {
|
|
8
|
+
env: () => Promise<Record<string, unknown>>;
|
|
9
|
+
siteTitle: () => Promise<string | undefined>;
|
|
10
|
+
fetch: FetchFn;
|
|
11
|
+
warn: (message: string, data: Record<string, unknown>) => void;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
5
14
|
//#region src/native/plugin.d.ts
|
|
6
|
-
type LoadEnv = () => Promise<Record<string, unknown>>;
|
|
7
15
|
/** @internal Exported for tests. */
|
|
8
|
-
declare function createJetEmailDeliver(config: JetEmailConfig,
|
|
16
|
+
declare function createJetEmailDeliver(config: JetEmailConfig, deps?: SendDeps): (event: EmailDeliverEvent, ctx: PluginContext) => Promise<void>;
|
|
9
17
|
/** Called by EmDash with the options of the {@link jetEmail} descriptor. */
|
|
10
18
|
declare function createPlugin(config: JetEmailConfig): emdash.ResolvedPlugin<emdash.PluginStorageConfig>;
|
|
11
19
|
//#endregion
|
package/dist/native/plugin.mjs
CHANGED
|
@@ -1,32 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as PLUGIN_VERSION, r as assertValidConfig, t as PLUGIN_ID } from "../config-Bdqx5Bs6.mjs";
|
|
1
|
+
import { a as assertValidConfig, i as PLUGIN_VERSION, n as sendWithConfig, r as PLUGIN_ID, t as defaultDeps } from "../send-DoICK33S.mjs";
|
|
3
2
|
import { definePlugin } from "emdash";
|
|
4
3
|
|
|
5
4
|
//#region src/native/plugin.ts
|
|
6
|
-
async function loadWorkerEnv() {
|
|
7
|
-
try {
|
|
8
|
-
const { env } = await import("../env-DnAfk4Vp.mjs");
|
|
9
|
-
return env;
|
|
10
|
-
} catch {
|
|
11
|
-
throw new Error("[jetemail] cloudflare:workers is not available; this provider runs only on Cloudflare Workers.");
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
5
|
/** @internal Exported for tests. */
|
|
15
|
-
function createJetEmailDeliver(config,
|
|
16
|
-
const secret = config.secret ?? "JETEMAIL_API_KEY";
|
|
6
|
+
function createJetEmailDeliver(config, deps = defaultDeps) {
|
|
17
7
|
return async (event, ctx) => {
|
|
18
|
-
const apiToken = (await loadEnv())[secret];
|
|
19
|
-
if (typeof apiToken !== "string" || !apiToken) throw new Error(`[jetemail] Worker secret "${secret}" is not set (wrangler secret put ${secret}).`);
|
|
20
8
|
const { message } = event;
|
|
21
|
-
const result = await
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
fromEmail: config.from.email
|
|
25
|
-
}, {
|
|
26
|
-
...message,
|
|
27
|
-
replyTo: message.replyTo ?? config.replyTo
|
|
9
|
+
const result = await sendWithConfig(config, message, {
|
|
10
|
+
...deps,
|
|
11
|
+
siteTitle: async () => await deps.siteTitle() || ctx.site.name
|
|
28
12
|
});
|
|
29
|
-
ctx.log.info("Email delivered via JetEmail", {
|
|
13
|
+
if (result.id) ctx.log.info("Email delivered via JetEmail", {
|
|
30
14
|
to: message.to,
|
|
31
15
|
subject: message.subject,
|
|
32
16
|
id: result.id
|
package/dist/plugin.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var e=class extends Error{constructor(e,t){super(e),this.status=t,this.name=`JetEmailError`}};function t(e,t){return`${e.replace(/[<>"\r\n]/g,``).trim()} <${t}>`}function n(e){if(typeof e==`string`)return e;let t=``;for(let n=0;n<e.length;n+=32768)t+=String.fromCharCode(...e.subarray(n,n+32768));return btoa(t)}async function r(r,i,a){let o={from:t(i.fromName,i.fromEmail),to:a.to,subject:a.subject};a.text&&(o.text=a.text),a.html&&(o.html=a.html),a.cc?.length&&(o.cc=a.cc),a.replyTo&&(o.reply_to=a.replyTo),a.attachments?.length&&(o.attachments=a.attachments.map(e=>({filename:e.filename,data:n(e.content)})));let s=await r(`https://api.jetemail.com/email`,{method:`POST`,headers:{Authorization:`Bearer ${i.apiToken}`,"Content-Type":`application/json`},body:JSON.stringify(o)});if(!s.ok){let t=(await s.text()).slice(0,500);throw new e(`JetEmail rejected the message with HTTP ${s.status}${t?`: ${t}`:``}`,s.status)}let c=await s.json().catch(()=>({}));return typeof c.id==`string`?{id:c.id}:{}}async function i(e){let t=await e.kv.get(`settings:apiToken`),n=await e.kv.get(`settings:fromName`)||e.site.name,r=await e.kv.get(`settings:fromEmail`),i=await e.kv.get(`settings:replyTo`)||void 0;if(!t||!n||!r)throw Error(`JetEmail is not configured. Set the API key and sender email.`);return{apiToken:t,fromName:n,fromEmail:r,replyTo:i}}async function a(e){let t=await e.kv.get(`settings:fromName`)??``,n=await e.kv.get(`settings:fromEmail`)??``,r=await e.kv.get(`settings:replyTo`)??``,i=!!await e.kv.get(`settings:apiToken`);return{blocks:[{type:`header`,text:`JetEmail`},{type:`section`,text:`Deliver EmDash transactional email through the JetEmail API. The sender domain must be verified in JetEmail and allowed for the API key.`},{type:`form`,block_id:`jetemail-settings`,fields:[{type:`text_input`,action_id:`fromName`,label:`Sender name (defaults to the site title)`,initial_value:t},{type:`text_input`,action_id:`fromEmail`,label:`Sender email`,initial_value:n},{type:`text_input`,action_id:`replyTo`,label:`Reply-To (optional)`,initial_value:r},{type:`secret_input`,action_id:`apiToken`,label:i?`Transactional API key (leave blank to keep current)`:`Transactional API key`}],submit:{label:`Save settings`,action_id:`save_settings`}}]}}const o=/^[^\s@<>]+@[^\s@<>]+$/;function s(e){return{blocks:[{type:`banner`,style:`error`,text:e}],toast:{message:e,type:`error`}}}async function c(e,t){let n=typeof t.fromName==`string`?t.fromName.trim():``,r=typeof t.fromEmail==`string`?t.fromEmail.trim():``,i=typeof t.replyTo==`string`?t.replyTo.trim():``,c=typeof t.apiToken==`string`?t.apiToken.trim():``;return o.test(r)?i&&!o.test(i)?s(`Enter a valid Reply-To email.`):c&&!c.startsWith(`transactional_`)?s(`Use a JetEmail transactional API key (transactional_…).`):(await e.kv.set(`settings:fromName`,n),await e.kv.set(`settings:fromEmail`,r),await e.kv.set(`settings:replyTo`,i),c&&await e.kv.set(`settings:apiToken`,c),{...await a(e),toast:{message:`JetEmail settings saved`,type:`success`}}):s(`Enter a valid sender email.`)}const l={hooks:{"email:deliver":{exclusive:!0,timeout:3e4,handler:async(e,t)=>{if(!t.http)throw Error(`JetEmail requires network access.`);let{replyTo:n,...a}=await i(t);await r(t.http.fetch.bind(t.http),a,{...e.message,replyTo:e.message.replyTo??n}),t.log.info(`Email delivered via JetEmail`,{to:e.message.to,subject:e.message.subject})}}},routes:{admin:{handler:async(e,t)=>{let n=e.input;return n.type===`page_load`&&n.page===`/settings`?a(t):n.type===`form_submit`&&n.action_id===`save_settings`?c(t,n.values??{}):{blocks:[]}}}}};export{l as default,r as deliverWithJetEmail,t as formatSender};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { deliverWithJetEmail, formatSender } from "./client.mjs";
|
|
2
|
+
|
|
3
|
+
//#region package.json
|
|
4
|
+
var version = "0.4.0";
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/native/config.ts
|
|
8
|
+
const PLUGIN_ID = "jetemail";
|
|
9
|
+
const PLUGIN_VERSION = version;
|
|
10
|
+
function assertValidConfig(config) {
|
|
11
|
+
if (!config.from?.email?.includes("@")) throw new Error("[jetemail] config.from needs an email, e.g. { from: { email: \"noreply@example.com\" } }");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/native/send.ts
|
|
16
|
+
async function loadWorkerEnv() {
|
|
17
|
+
try {
|
|
18
|
+
const { env } = await import("./env-DnAfk4Vp.mjs");
|
|
19
|
+
return env;
|
|
20
|
+
} catch {
|
|
21
|
+
throw new Error("[jetemail] cloudflare:workers is not available; this provider runs only on Cloudflare Workers.");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function loadSiteTitle() {
|
|
25
|
+
try {
|
|
26
|
+
const { getSiteSetting } = await import("emdash");
|
|
27
|
+
return await getSiteSetting("title");
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const defaultDeps = {
|
|
33
|
+
env: loadWorkerEnv,
|
|
34
|
+
siteTitle: loadSiteTitle,
|
|
35
|
+
fetch: (url, init) => fetch(url, init),
|
|
36
|
+
warn: (message, data) => console.warn(message, data)
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Sends one message with the configured sender. With the Worker variable `JETEMAIL_DRY_RUN=true`
|
|
40
|
+
* the message is only logged; E2E runs use it because they have no API key.
|
|
41
|
+
*/
|
|
42
|
+
async function sendWithConfig(config, message, deps) {
|
|
43
|
+
const fromName = config.from.name?.trim() || (await deps.siteTitle())?.trim();
|
|
44
|
+
if (!fromName) throw new Error("[jetemail] No sender name: set config.from.name or the site title.");
|
|
45
|
+
const replyTo = message.replyTo ?? config.replyTo;
|
|
46
|
+
const env = await deps.env();
|
|
47
|
+
if (env.JETEMAIL_DRY_RUN === "true") {
|
|
48
|
+
deps.warn("[jetemail] JETEMAIL_DRY_RUN=true, email not sent", {
|
|
49
|
+
from: formatSender(fromName, config.from.email),
|
|
50
|
+
to: message.to,
|
|
51
|
+
replyTo,
|
|
52
|
+
subject: message.subject
|
|
53
|
+
});
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
const secret = config.secret ?? "JETEMAIL_API_KEY";
|
|
57
|
+
const apiToken = env[secret];
|
|
58
|
+
if (typeof apiToken !== "string" || !apiToken) throw new Error(`[jetemail] Worker secret "${secret}" is not set (wrangler secret put ${secret}).`);
|
|
59
|
+
return deliverWithJetEmail(deps.fetch, {
|
|
60
|
+
apiToken,
|
|
61
|
+
fromName,
|
|
62
|
+
fromEmail: config.from.email
|
|
63
|
+
}, {
|
|
64
|
+
...message,
|
|
65
|
+
replyTo
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
export { assertValidConfig as a, PLUGIN_VERSION as i, sendWithConfig as n, PLUGIN_ID as r, defaultDeps as t };
|
package/package.json
CHANGED
package/dist/config-Bdqx5Bs6.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//#region src/native/config.ts
|
|
2
|
-
const PLUGIN_ID = "jetemail";
|
|
3
|
-
const PLUGIN_VERSION = "1.0.0";
|
|
4
|
-
function assertValidConfig(config) {
|
|
5
|
-
if (!config.from?.email?.includes("@") || !config.from.name?.trim()) throw new Error("[jetemail] config.from needs an email and a name, e.g. { from: { email: \"noreply@example.com\", name: \"Example\" } }");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
//#endregion
|
|
9
|
-
export { PLUGIN_VERSION as n, assertValidConfig as r, PLUGIN_ID as t };
|