@lunora/mail 1.0.0-alpha.50 → 1.0.0-alpha.52
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/inbound/index.mjs +1 -1
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{address-BQ5RUGdT.mjs → address-soPj2Z0j.mjs} +1 -1
- package/dist/packem_shared/{capture-transport.d-_rIl9W6N.d.mts → capture-transport.d-8CDAv51Z.d.mts} +9 -0
- package/dist/packem_shared/{capture-transport.d-_rIl9W6N.d.ts → capture-transport.d-8CDAv51Z.d.ts} +9 -0
- package/dist/packem_shared/consumeQueuedSend-CRfALnCU.mjs +1 -0
- package/dist/packem_shared/{createCaptureSink-CE24od5h.mjs → createCaptureSink-4T2LJOYC.mjs} +1 -1
- package/dist/packem_shared/{createCloudflareTransport-E-UdW8Dc.mjs → createCloudflareTransport-DpfCxn16.mjs} +1 -1
- package/dist/packem_shared/createInboundEmailHandler-CTary3dz.mjs +1 -0
- package/dist/packem_shared/createMailer-BJs2hnV-.mjs +1 -0
- package/dist/packem_shared/{createResendTransport-CG9s8iI9.mjs → createResendTransport-DDkOitck.mjs} +1 -1
- package/dist/packem_shared/{parseInboundEmail-Cxe54g-h.mjs → parseInboundEmail-CqU52y3O.mjs} +1 -1
- package/dist/packem_shared/{provider-transport-DXmTG_xv.mjs → provider-transport-CR4w-R0A.mjs} +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/package.json +2 -2
- package/dist/packem_shared/consumeQueuedSend-8TXPj5o-.mjs +0 -1
- package/dist/packem_shared/createInboundEmailHandler-D2i0mEBB.mjs +0 -1
- package/dist/packem_shared/createMailer-LHgKs5yh.mjs +0 -1
package/dist/inbound/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createInboundEmailHandler as r,dispatchToLunoraFunction as a}from"../packem_shared/createInboundEmailHandler-
|
|
1
|
+
import{createInboundEmailHandler as r,dispatchToLunoraFunction as a}from"../packem_shared/createInboundEmailHandler-CTary3dz.mjs";import{parseInboundEmail as t}from"../packem_shared/parseInboundEmail-CqU52y3O.mjs";export{r as createInboundEmailHandler,a as dispatchToLunoraFunction,t as parseInboundEmail};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MailTransport, L as LunoraMailOptions, a as Mailer, b as MailboxSink, S as SendOptions } from "./packem_shared/capture-transport.d-
|
|
2
|
-
export { type C as CapturedMail, type Q as QueueLike, type c as SendPayload, d as createCaptureTransport } from "./packem_shared/capture-transport.d-
|
|
1
|
+
import { M as MailTransport, L as LunoraMailOptions, a as Mailer, b as MailboxSink, S as SendOptions } from "./packem_shared/capture-transport.d-8CDAv51Z.mjs";
|
|
2
|
+
export { type C as CapturedMail, type Q as QueueLike, type c as SendPayload, d as createCaptureTransport } from "./packem_shared/capture-transport.d-8CDAv51Z.mjs";
|
|
3
3
|
import { D as DurableObjectJurisdiction } from "./packem_shared/shard.d-DVADjmEJ.mjs";
|
|
4
4
|
import { ReactElement } from 'react';
|
|
5
5
|
/**
|
|
@@ -100,6 +100,12 @@ interface QueuedSend {
|
|
|
100
100
|
from?: string;
|
|
101
101
|
headers?: Record<string, string>;
|
|
102
102
|
html?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Stable dedup key, minted at enqueue time by `createMailer(...).queue()` — see
|
|
105
|
+
* `SendOptions.idempotencyKey`. Carried through untouched by `consumeQueuedSend`;
|
|
106
|
+
* a consumer wanting exactly-once delivery dedupes against its own store using it.
|
|
107
|
+
*/
|
|
108
|
+
idempotencyKey?: string;
|
|
103
109
|
replyTo?: string;
|
|
104
110
|
subject: string;
|
|
105
111
|
text?: string;
|
|
@@ -122,6 +128,7 @@ declare const toQueuedPayload: (options: SendOptions) => QueuedSend;
|
|
|
122
128
|
* const mailer = createMailer({ apiKey: env.RESEND_API_KEY, from: "..." });
|
|
123
129
|
* for (const message of batch.messages) {
|
|
124
130
|
* await consumeQueuedSend(mailer, message.body);
|
|
131
|
+
* message.ack();
|
|
125
132
|
* }
|
|
126
133
|
* },
|
|
127
134
|
* };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MailTransport, L as LunoraMailOptions, a as Mailer, b as MailboxSink, S as SendOptions } from "./packem_shared/capture-transport.d-
|
|
2
|
-
export { type C as CapturedMail, type Q as QueueLike, type c as SendPayload, d as createCaptureTransport } from "./packem_shared/capture-transport.d-
|
|
1
|
+
import { M as MailTransport, L as LunoraMailOptions, a as Mailer, b as MailboxSink, S as SendOptions } from "./packem_shared/capture-transport.d-8CDAv51Z.js";
|
|
2
|
+
export { type C as CapturedMail, type Q as QueueLike, type c as SendPayload, d as createCaptureTransport } from "./packem_shared/capture-transport.d-8CDAv51Z.js";
|
|
3
3
|
import { D as DurableObjectJurisdiction } from "./packem_shared/shard.d-DVADjmEJ.js";
|
|
4
4
|
import { ReactElement } from 'react';
|
|
5
5
|
/**
|
|
@@ -100,6 +100,12 @@ interface QueuedSend {
|
|
|
100
100
|
from?: string;
|
|
101
101
|
headers?: Record<string, string>;
|
|
102
102
|
html?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Stable dedup key, minted at enqueue time by `createMailer(...).queue()` — see
|
|
105
|
+
* `SendOptions.idempotencyKey`. Carried through untouched by `consumeQueuedSend`;
|
|
106
|
+
* a consumer wanting exactly-once delivery dedupes against its own store using it.
|
|
107
|
+
*/
|
|
108
|
+
idempotencyKey?: string;
|
|
103
109
|
replyTo?: string;
|
|
104
110
|
subject: string;
|
|
105
111
|
text?: string;
|
|
@@ -122,6 +128,7 @@ declare const toQueuedPayload: (options: SendOptions) => QueuedSend;
|
|
|
122
128
|
* const mailer = createMailer({ apiKey: env.RESEND_API_KEY, from: "..." });
|
|
123
129
|
* for (const message of batch.messages) {
|
|
124
130
|
* await consumeQueuedSend(mailer, message.body);
|
|
131
|
+
* message.ack();
|
|
125
132
|
* }
|
|
126
133
|
* },
|
|
127
134
|
* };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createCaptureTransport as a}from"./packem_shared/createCaptureTransport-CKc6NpZR.mjs";import{createCloudflareTransport as t}from"./packem_shared/createCloudflareTransport-
|
|
1
|
+
import{createCaptureTransport as a}from"./packem_shared/createCaptureTransport-CKc6NpZR.mjs";import{createCloudflareTransport as t}from"./packem_shared/createCloudflareTransport-DpfCxn16.mjs";import{default as u}from"./packem_shared/createMailer-BJs2hnV-.mjs";import{createCaptureSink as f,createMailerFromEnv as l,shouldCaptureMail as m}from"./packem_shared/createCaptureSink-4T2LJOYC.mjs";import{consumeQueuedSend as s,toQueuedPayload as c}from"./packem_shared/consumeQueuedSend-CRfALnCU.mjs";import{default as i}from"./packem_shared/renderEmail-BOUnr6i3.mjs";import{default as M}from"./packem_shared/createResendTransport-DDkOitck.mjs";export{s as consumeQueuedSend,f as createCaptureSink,a as createCaptureTransport,t as createCloudflareTransport,u as createMailer,l as createMailerFromEnv,M as createResendTransport,i as renderEmail,m as shouldCaptureMail,c as toQueuedPayload};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{LunoraError as t}from"@lunora/errors";const n=320,a=256,d=/^([^<]*)<([^>]*)>\s*$/,i=(r,s)=>{if(s.includes("\r")||s.includes(`
|
|
2
2
|
`)||s.includes(","))throw new t("INTERNAL",`@lunora/mail: address ${r} must not contain CR, LF, or comma`)},f=(r,s)=>{if(s.includes("\r")||s.includes(`
|
|
3
|
-
`))throw new t("INTERNAL",`@lunora/mail: ${r} must not contain CR or LF`)},m=(r,s)=>{if(r.length>a)throw new t("INTERNAL",`@lunora/mail: address name must be <= ${String(a)} characters`);if(s.length>n)throw new t("INTERNAL",`@lunora/mail: address email must be <= ${String(n)} characters`);return r&&i("name",r),i("email",s),r?{email:s,name:r}:{email:s}},A=r=>{const s=r.trim();if(s.length>n)throw new t("INTERNAL",`@lunora/mail: address email must be <= ${String(n)} characters`);return i("email",s),{email:s}},c=r=>{const s=d.exec(r),e=(s?.[2]??"").trim();return s&&e?m((s[1]??"").trim(),e):A(r)},o=r=>r===void 0?void 0:(Array.isArray(r)?r:[r]).map(e=>c(e)),u=r=>{o(r.to),o(r.cc),o(r.bcc),r.from!==void 0&&c(r.from),r.replyTo!==void 0&&c(r.replyTo)};export{f as a,
|
|
3
|
+
`))throw new t("INTERNAL",`@lunora/mail: ${r} must not contain CR or LF`)},m=(r,s)=>{if(r.length>a)throw new t("INTERNAL",`@lunora/mail: address name must be <= ${String(a)} characters`);if(s.length>n)throw new t("INTERNAL",`@lunora/mail: address email must be <= ${String(n)} characters`);return r&&i("name",r),i("email",s),r?{email:s,name:r}:{email:s}},A=r=>{const s=r.trim();if(s.length>n)throw new t("INTERNAL",`@lunora/mail: address email must be <= ${String(n)} characters`);return i("email",s),{email:s}},c=r=>{const s=d.exec(r),e=(s?.[2]??"").trim();return s&&e?m((s[1]??"").trim(),e):A(r)},o=r=>r===void 0?void 0:(Array.isArray(r)?r:[r]).map(e=>c(e)),u=r=>{o(r.to),o(r.cc),o(r.bcc),r.from!==void 0&&c(r.from),r.replyTo!==void 0&&c(r.replyTo)};export{f as a,c as b,u as c,o as t};
|
package/dist/packem_shared/{capture-transport.d-_rIl9W6N.d.mts → capture-transport.d-8CDAv51Z.d.mts}
RENAMED
|
@@ -34,6 +34,15 @@ interface SendOptions {
|
|
|
34
34
|
from?: string;
|
|
35
35
|
headers?: Record<string, string>;
|
|
36
36
|
html?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Stable key for deduping a queued send across Cloudflare Queues' at-least-once
|
|
39
|
+
* redelivery. Only meaningful for `mailer.queue()` — `mailer.send()` ignores it.
|
|
40
|
+
* When omitted, `queue()` generates one at enqueue time so it survives redelivery
|
|
41
|
+
* (a key minted in the consumer would change on every retry, defeating the point).
|
|
42
|
+
* Not forwarded to the mail provider — a consumer wanting exactly-once delivery
|
|
43
|
+
* must dedupe against its own store using this key.
|
|
44
|
+
*/
|
|
45
|
+
idempotencyKey?: string;
|
|
37
46
|
react?: ReactElement;
|
|
38
47
|
replyTo?: string;
|
|
39
48
|
subject: string;
|
package/dist/packem_shared/{capture-transport.d-_rIl9W6N.d.ts → capture-transport.d-8CDAv51Z.d.ts}
RENAMED
|
@@ -34,6 +34,15 @@ interface SendOptions {
|
|
|
34
34
|
from?: string;
|
|
35
35
|
headers?: Record<string, string>;
|
|
36
36
|
html?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Stable key for deduping a queued send across Cloudflare Queues' at-least-once
|
|
39
|
+
* redelivery. Only meaningful for `mailer.queue()` — `mailer.send()` ignores it.
|
|
40
|
+
* When omitted, `queue()` generates one at enqueue time so it survives redelivery
|
|
41
|
+
* (a key minted in the consumer would change on every retry, defeating the point).
|
|
42
|
+
* Not forwarded to the mail provider — a consumer wanting exactly-once delivery
|
|
43
|
+
* must dedupe against its own store using this key.
|
|
44
|
+
*/
|
|
45
|
+
idempotencyKey?: string;
|
|
37
46
|
react?: ReactElement;
|
|
38
47
|
replyTo?: string;
|
|
39
48
|
subject: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as c}from"@lunora/errors";const d=n=>{const t={...n};return delete t.react,t},p=async(n,t)=>{if(!t||typeof t!="object"||Array.isArray(t))throw new c("INTERNAL","@lunora/mail: queue message body must be an object");const e=t;if(typeof e.subject!="string")throw new TypeError("@lunora/mail: queue message must have a string `subject`");const y=typeof e.to=="string",m=Array.isArray(e.to)&&e.to.every(o=>typeof o=="string");if(!y&&!m)throw new c("INTERNAL","@lunora/mail: queue message `to` must be a string or string[]");const s=(o,r)=>{if(r!==void 0){if(typeof r!="string")throw new TypeError(`@lunora/mail: queue message \`${o}\` must be a string`);return r}},a=(o,r)=>{if(r!==void 0){if(typeof r=="string")return[r];if(Array.isArray(r)&&r.every(i=>typeof i=="string"))return r;throw new TypeError(`@lunora/mail: queue message \`${o}\` must be a string or string[]`)}};let u;if(e.headers!==void 0){if(!e.headers||typeof e.headers!="object"||Array.isArray(e.headers))throw new TypeError("@lunora/mail: queue message `headers` must be an object of string values");const o=Object.entries(e.headers);for(const[r,i]of o)if(typeof i!="string")throw new TypeError(`@lunora/mail: queue message header "${r}" must be a string`);u=e.headers}const f={bcc:a("bcc",e.bcc),cc:a("cc",e.cc),from:s("from",e.from),headers:u,html:s("html",e.html),idempotencyKey:s("idempotencyKey",e.idempotencyKey),replyTo:s("replyTo",e.replyTo),subject:e.subject,text:s("text",e.text),to:e.to};return n.send(f)};export{p as consumeQueuedSend,d as toQueuedPayload};
|
package/dist/packem_shared/{createCaptureSink-CE24od5h.mjs → createCaptureSink-4T2LJOYC.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createCaptureTransport as d}from"./createCaptureTransport-CKc6NpZR.mjs";import"./createCloudflareTransport-
|
|
1
|
+
import{createCaptureTransport as d}from"./createCaptureTransport-CKc6NpZR.mjs";import"./createCloudflareTransport-DpfCxn16.mjs";import n from"./createMailer-BJs2hnV-.mjs";import{LunoraError as c}from"@lunora/errors";import{D as s,p as l}from"./shard-C0aRRoVy.mjs";import"./consumeQueuedSend-CRfALnCU.mjs";import"./renderEmail-BOUnr6i3.mjs";import"./createResendTransport-DDkOitck.mjs";const E="__lunora_admin__:recordMail",p=/^(?:dev(?:elopment)?|local(?:host)?|test)$/iu,f=["CF_ENV","ENVIRONMENT","NODE_ENV","WORKER_ENV"],_=(t,e)=>{const r=t[e];if(typeof r!="string"||r==="")throw new c("INTERNAL",`@lunora/mail: missing env var \`${e}\` — set it in .dev.vars (and \`wrangler secret put ${e}\` for secrets).`);return r},N=t=>{const e=t.LUNORA_MAIL_CAPTURE;if(typeof e=="string"){const r=e.toLowerCase();if(r==="1"||r==="true")return!0;if(r==="0"||r==="false")return!1;console.warn(`@lunora/mail: unrecognized LUNORA_MAIL_CAPTURE value "${e}" — expected "1"/"true" or "0"/"false"; falling back to environment detection.`)}return f.some(r=>{const o=t[r];return typeof o=="string"&&p.test(o)})},m=(t,e=s,r)=>({record:async o=>{const i=t.SHARD,a=typeof t.LUNORA_ADMIN_TOKEN=="string"?t.LUNORA_ADMIN_TOKEN:void 0;if(i===void 0||a===void 0)return{id:"uncaptured"};try{return{id:(await l(i,{adminToken:a,envelope:{args:o,functionPath:E},jurisdiction:r,label:"@lunora/mail: recording captured mail",shardKey:e})).result?.id??"captured"}}catch(u){return console.error("@lunora/mail: failed to record captured mail into the studio inbox —",u),{id:"uncaptured"}}}}),L=(t,e={})=>{const r=_(t,"MAIL_FROM");if(N(t))return n({from:r,transport:d(m(t,e.rootShard,e.jurisdiction))});if(e.cloudflareSend)return n({cloudflareSend:e.cloudflareSend,from:r});const o=typeof t.RESEND_API_KEY=="string"?t.RESEND_API_KEY:void 0;if(o!==void 0&&o!=="")return n({apiKey:o,from:r});throw new c("INTERNAL","@lunora/mail: no transport configured — provide `cloudflareSend` (a SEND_EMAIL binding) or RESEND_API_KEY, or run in a dev environment to capture.")};export{m as createCaptureSink,L as createMailerFromEnv,N as shouldCaptureMail};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as n}from"@lunora/errors";import{cloudflareEmailProvider as l}from"@visulima/email/providers/cloudflare-email";import{r as d,t as u,i as m}from"./provider-transport-
|
|
1
|
+
import{LunoraError as n}from"@lunora/errors";import{cloudflareEmailProvider as l}from"@visulima/email/providers/cloudflare-email";import{r as d,t as u,i as m}from"./provider-transport-CR4w-R0A.mjs";const E=r=>{const t=l({send:r.send});return{send:async e=>{await t.initialize();const o=e.cc!==void 0&&e.cc.length>0,s=e.bcc!==void 0&&e.bcc.length>0;if(o||s)throw new n("INTERNAL","@lunora/mail: Cloudflare Email Workers does not support cc/bcc — fan out one send per recipient instead");const{first:c,list:i}=d(e.to);if(i.length>1)throw new n("INTERNAL",`@lunora/mail: Cloudflare Email Workers is single-recipient but received ${String(i.length)} \`to\` addresses — fan out one send per recipient instead`);const a=await t.sendEmail(u(e,r.from,c));return m(a)}}};export{E as createCloudflareTransport};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as i}from"@lunora/errors";import{D as c,p as d}from"./shard-C0aRRoVy.mjs";const u=n=>{let r="";for(let e=0;e<n.length;e+=32768)r+=String.fromCharCode(...n.subarray(e,e+32768));return btoa(r)},h="message could not be processed",f=(n,r)=>{console.error("@lunora/mail/inbound: dropping message —",n),r.message.setReject(h)},N=n=>{const r=n.onError??f;return async(t,e,s)=>{const a={ctx:s,env:e,message:t};try{const o=await n.parse(t.raw);if(n.verify&&await n.verify(o,a)===!1)throw new i("INTERNAL","@lunora/mail/inbound: sender verification rejected the message");await n.dispatch(o,a)}catch(o){await r(o,a)}}},l=n=>n.attachments.length===0?n:{...n,attachments:n.attachments.map(r=>{const{content:t}=r;if(typeof t=="string")return r;const e=t instanceof Uint8Array?t:new Uint8Array(t);return{...r,content:u(e),encoding:"base64"}})},g=n=>{const r=n.shardKey??c,t=n.resolveArgs??(e=>l(e));return async(e,s)=>{const a=n.adminToken??(typeof s.env.LUNORA_ADMIN_TOKEN=="string"?s.env.LUNORA_ADMIN_TOKEN:void 0);if(a===void 0||a==="")throw new i("INTERNAL","@lunora/mail/inbound: missing LUNORA_ADMIN_TOKEN — cannot authorize inbound dispatch to the shard RPC.");const o={args:t(e,s),functionPath:n.functionPath,shardKey:r};await d(n.shard,{adminToken:a,envelope:o,jurisdiction:n.jurisdiction,label:`@lunora/mail/inbound: dispatch to \`${n.functionPath}\``,shardKey:r})}};export{N as createInboundEmailHandler,g as dispatchToLunoraFunction};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as l}from"@lunora/errors";import{a as f,c as m}from"./address-soPj2Z0j.mjs";import{isCaptureTransport as s}from"./createCaptureTransport-CKc6NpZR.mjs";import{createCloudflareTransport as y}from"./createCloudflareTransport-DpfCxn16.mjs";import{toQueuedPayload as i}from"./consumeQueuedSend-CRfALnCU.mjs";import w from"./renderEmail-BOUnr6i3.mjs";import b from"./createResendTransport-DDkOitck.mjs";const h=()=>{if(typeof crypto<"u"){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto.getRandomValues=="function"){const r=crypto.getRandomValues(new Uint8Array(16));return Array.from(r,u=>u.toString(16).padStart(2,"0")).join("")}}return Date.now().toString(36)},q=r=>{if(r.cloudflareSend)return y({from:r.from,send:r.cloudflareSend});if(r.apiKey)return b(r.apiKey,r.from);throw new l("INTERNAL","@lunora/mail: a transport is required — pass `transport`, `cloudflareSend` (Cloudflare Email Workers, the default), or `apiKey` (Resend)")},g=r=>{if(!r.from)throw new l("INTERNAL","@lunora/mail: `from` is required");const u=r.transport??q(r),n=async e=>{let{html:a}=e,{text:c}=e;if(e.react){const t=await w(e.react);a=a??t.html,c=c??t.text}if(f("subject",e.subject),e.headers)for(const[t,o]of Object.entries(e.headers))f(`header name "${t}"`,t),f(`header "${t}" value`,o);const d=e.from??r.from;return m({bcc:e.bcc,cc:e.cc,from:d,replyTo:e.replyTo,to:e.to}),{bcc:e.bcc,cc:e.cc,from:d,headers:e.headers,html:a,replyTo:e.replyTo,subject:e.subject,text:c,to:e.to}};return{queue:async e=>{if(!r.queue){if(s(u)){const d=await n(e);return await u.send(d),{queued:!0}}throw new l("INTERNAL","@lunora/mail: `queue` binding is required for mailer.queue()")}const a=await n(e),c=e.idempotencyKey??h();return await r.queue.send(i({...a,idempotencyKey:c})),{queued:!0}},send:async e=>{const a=await n(e);return u.send(a)}}};export{g as default};
|
package/dist/packem_shared/{createResendTransport-CG9s8iI9.mjs → createResendTransport-DDkOitck.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resendProvider as a}from"@visulima/email/providers/resend";import{r as d,t as c,i as l}from"./provider-transport-
|
|
1
|
+
import{resendProvider as a}from"@visulima/email/providers/resend";import{r as d,t as c,i as l}from"./provider-transport-CR4w-R0A.mjs";const u=(i,s)=>{const e=a({apiKey:i});return{send:async r=>{await e.initialize();const{first:n,list:t}=d(r.to),o=await e.sendEmail(c(r,s,t.length===1?n:t));return l(o)}}};export{u as default};
|
package/dist/packem_shared/{parseInboundEmail-Cxe54g-h.mjs → parseInboundEmail-CqU52y3O.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import u from"postal-mime";import{a as r}from"./address-
|
|
1
|
+
import u from"postal-mime";import{a as r}from"./address-soPj2Z0j.mjs";const s=(o,e)=>{if(e!==void 0)return r(`inbound ${o}`,e),e},m=o=>o.address!==void 0&&o.address!==""?o.name?`${o.name} <${o.address}>`:o.address:o.group?o.group.map(e=>e.address??"").filter(e=>e!=="").join(", "):o.name??"",t=(o,e)=>new RegExp(String.raw`\b${e}=([a-zA-Z]+)`,"i").exec(o)?.[1]?.toLowerCase()??null,p=o=>o===void 0||o===""?{dkim:null,dmarc:null,spf:null}:{dkim:t(o,"dkim"),dmarc:t(o,"dmarc"),spf:t(o,"spf")},b=async o=>{const e=await u.parse(o),i={};for(const n of e.headers)r(`inbound header \`${n.key}\``,n.value),i[n.key]=n.value;const c=e.headers.find(n=>n.key==="authentication-results")?.value,f=(e.to??[]).map(n=>{const a=m(n);return r("inbound to",a),a}),d=e.from?m(e.from):"";return r("inbound from",d),{attachments:e.attachments.map(n=>({content:n.content,disposition:n.disposition,...n.encoding===void 0?{}:{encoding:n.encoding},filename:n.filename,mimeType:n.mimeType})),authentication:p(c),from:d,headers:i,...e.html===void 0?{}:{html:e.html},...s("inReplyTo",e.inReplyTo)===void 0?{}:{inReplyTo:e.inReplyTo},...s("messageId",e.messageId)===void 0?{}:{messageId:e.messageId},...s("references",e.references)===void 0?{}:{references:e.references},...s("subject",e.subject)===void 0?{}:{subject:e.subject},...e.text===void 0?{}:{text:e.text},to:f}};export{b as parseInboundEmail};
|
package/dist/packem_shared/{provider-transport-DXmTG_xv.mjs → provider-transport-CR4w-R0A.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as o}from"@lunora/errors";import{t as n,
|
|
1
|
+
import{LunoraError as o}from"@lunora/errors";import{t as n,b as s}from"./address-soPj2Z0j.mjs";const c=e=>e instanceof Error?e.message:e==null?"send failed":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"||typeof e=="bigint"?e.toString():JSON.stringify(e)??"send failed",u=e=>{const t=n(e),[i]=t??[];if(!t||i===void 0)throw new o("INTERNAL","@lunora/mail: at least one recipient is required");return{first:i,list:t}},d=(e,t,i)=>({bcc:n(e.bcc),cc:n(e.cc),from:s(e.from??t),headers:e.headers,html:e.html,replyTo:e.replyTo?s(e.replyTo):void 0,subject:e.subject,text:e.text,to:i}),m=e=>{if(!e.success||!e.data)throw console.error(`@lunora/mail: send failed: ${c(e.error)}`),new o("INTERNAL","@lunora/mail: send failed");return{id:e.data.messageId}};export{m as i,u as r,d as t};
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CapturedMail } from "./packem_shared/capture-transport.d-
|
|
1
|
+
import { C as CapturedMail } from "./packem_shared/capture-transport.d-8CDAv51Z.mjs";
|
|
2
2
|
import 'react';
|
|
3
3
|
/** Minimal `fetch` projection so a test can inject a stub. */
|
|
4
4
|
type FetchLike = (input: string, init?: {
|
package/dist/testing.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CapturedMail } from "./packem_shared/capture-transport.d-
|
|
1
|
+
import { C as CapturedMail } from "./packem_shared/capture-transport.d-8CDAv51Z.js";
|
|
2
2
|
import 'react';
|
|
3
3
|
/** Minimal `fetch` projection so a test can inject a stub. */
|
|
4
4
|
type FetchLike = (input: string, init?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/mail",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.52",
|
|
4
4
|
"description": "Email for Lunora: Resend adapter, TSX templates, and queue-backed sends",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
57
|
+
"@lunora/errors": "1.0.0-alpha.23",
|
|
58
58
|
"@react-email/render": "2.1.0",
|
|
59
59
|
"@visulima/email": "2.1.8",
|
|
60
60
|
"postal-mime": "2.7.6"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as c}from"@lunora/errors";const d=n=>{const t={...n};return delete t.react,t},p=async(n,t)=>{if(!t||typeof t!="object"||Array.isArray(t))throw new c("INTERNAL","@lunora/mail: queue message body must be an object");const e=t;if(typeof e.subject!="string")throw new TypeError("@lunora/mail: queue message must have a string `subject`");const m=typeof e.to=="string",y=Array.isArray(e.to)&&e.to.every(s=>typeof s=="string");if(!m&&!y)throw new c("INTERNAL","@lunora/mail: queue message `to` must be a string or string[]");const o=(s,r)=>{if(r!==void 0){if(typeof r!="string")throw new TypeError(`@lunora/mail: queue message \`${s}\` must be a string`);return r}},a=(s,r)=>{if(r!==void 0){if(typeof r=="string")return[r];if(Array.isArray(r)&&r.every(i=>typeof i=="string"))return r;throw new TypeError(`@lunora/mail: queue message \`${s}\` must be a string or string[]`)}};let u;if(e.headers!==void 0){if(!e.headers||typeof e.headers!="object"||Array.isArray(e.headers))throw new TypeError("@lunora/mail: queue message `headers` must be an object of string values");const s=Object.entries(e.headers);for(const[r,i]of s)if(typeof i!="string")throw new TypeError(`@lunora/mail: queue message header "${r}" must be a string`);u=e.headers}const f={bcc:a("bcc",e.bcc),cc:a("cc",e.cc),from:o("from",e.from),headers:u,html:o("html",e.html),replyTo:o("replyTo",e.replyTo),subject:e.subject,text:o("text",e.text),to:e.to};return n.send(f)};export{p as consumeQueuedSend,d as toQueuedPayload};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as c}from"@lunora/errors";import{D as d,p as u}from"./shard-C0aRRoVy.mjs";const f="message could not be processed",h=(r,e)=>{console.error("@lunora/mail/inbound: dropping message —",r),e.message.setReject(f)},g=r=>{const e=r.onError??h;return async(n,t,s)=>{const a={ctx:s,env:t,message:n};try{const o=await r.parse(n.raw);if(r.verify&&await r.verify(o,a)===!1)throw new c("INTERNAL","@lunora/mail/inbound: sender verification rejected the message");await r.dispatch(o,a)}catch(o){await e(o,a)}}},i=32768,l=r=>{let e="";for(let n=0;n<r.length;n+=i)e+=String.fromCharCode(...r.subarray(n,n+i));return btoa(e)},E=r=>r.attachments.length===0?r:{...r,attachments:r.attachments.map(e=>{const{content:n}=e;if(typeof n=="string")return e;const t=n instanceof Uint8Array?n:new Uint8Array(n);return{...e,content:l(t),encoding:"base64"}})},y=r=>{const e=r.shardKey??d,n=r.resolveArgs??(t=>E(t));return async(t,s)=>{const a=r.adminToken??(typeof s.env.LUNORA_ADMIN_TOKEN=="string"?s.env.LUNORA_ADMIN_TOKEN:void 0);if(a===void 0||a==="")throw new c("INTERNAL","@lunora/mail/inbound: missing LUNORA_ADMIN_TOKEN — cannot authorize inbound dispatch to the shard RPC.");const o={args:n(t,s),functionPath:r.functionPath,shardKey:e};await u(r.shard,{adminToken:a,envelope:o,jurisdiction:r.jurisdiction,label:`@lunora/mail/inbound: dispatch to \`${r.functionPath}\``,shardKey:e})}};export{g as createInboundEmailHandler,y as dispatchToLunoraFunction};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as f}from"@lunora/errors";import{a as l,b as n}from"./address-BQ5RUGdT.mjs";import{isCaptureTransport as o}from"./createCaptureTransport-CKc6NpZR.mjs";import{createCloudflareTransport as i}from"./createCloudflareTransport-E-UdW8Dc.mjs";import{toQueuedPayload as y}from"./consumeQueuedSend-8TXPj5o-.mjs";import b from"./renderEmail-BOUnr6i3.mjs";import h from"./createResendTransport-CG9s8iI9.mjs";const w=r=>{if(r.cloudflareSend)return i({from:r.from,send:r.cloudflareSend});if(r.apiKey)return h(r.apiKey,r.from);throw new f("INTERNAL","@lunora/mail: a transport is required — pass `transport`, `cloudflareSend` (Cloudflare Email Workers, the default), or `apiKey` (Resend)")},x=r=>{if(!r.from)throw new f("INTERNAL","@lunora/mail: `from` is required");const c=r.transport??w(r),d=async e=>{let{html:a}=e,{text:u}=e;if(e.react){const t=await b(e.react);a=a??t.html,u=u??t.text}if(l("subject",e.subject),e.headers)for(const[t,s]of Object.entries(e.headers))l(`header name "${t}"`,t),l(`header "${t}" value`,s);const m=e.from??r.from;return n({bcc:e.bcc,cc:e.cc,from:m,replyTo:e.replyTo,to:e.to}),{bcc:e.bcc,cc:e.cc,from:m,headers:e.headers,html:a,replyTo:e.replyTo,subject:e.subject,text:u,to:e.to}};return{queue:async e=>{if(!r.queue){if(o(c)){const u=await d(e);return await c.send(u),{queued:!0}}throw new f("INTERNAL","@lunora/mail: `queue` binding is required for mailer.queue()")}const a=await d(e);return await r.queue.send(y(a)),{queued:!0}},send:async e=>{const a=await d(e);return c.send(a)}}};export{x as default};
|