@geekmidas/emailkit 10.0.0-alpha.98 → 10.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.
- package/CHANGELOG.md +42 -0
- package/dist/client-BkN5BGeJ.mjs +58 -0
- package/dist/client-BkN5BGeJ.mjs.map +1 -0
- package/dist/client-BrzAoy26.d.mts +21 -0
- package/dist/client-BrzAoy26.d.mts.map +1 -0
- package/dist/client-CGKPzbG7.d.cts +21 -0
- package/dist/client-CGKPzbG7.d.cts.map +1 -0
- package/dist/client-sZNHPYYg.cjs +92 -0
- package/dist/client-sZNHPYYg.cjs.map +1 -0
- package/dist/client.cjs +3 -124
- package/dist/client.d.cts +3 -23
- package/dist/client.d.mts +3 -23
- package/dist/client.mjs +2 -99
- package/dist/index.cjs +3 -9
- package/dist/index.d.cts +3 -5
- package/dist/index.d.mts +3 -5
- package/dist/index.mjs +3 -4
- package/dist/types-CLVcanCB.d.cts +83 -0
- package/dist/types-CLVcanCB.d.cts.map +1 -0
- package/dist/types-FrE6exSX.d.mts +83 -0
- package/dist/types-FrE6exSX.d.mts.map +1 -0
- package/dist/types.d.cts +2 -88
- package/dist/types.d.mts +2 -88
- package/dist/types.mjs +0 -1
- package/package.json +9 -25
- package/src/__tests__/client.spec.ts +372 -0
- package/src/__tests__/client.spec.tsx +185 -0
- package/src/client.ts +90 -0
- package/src/index.ts +11 -0
- package/src/types.ts +99 -0
- package/tsconfig.json +10 -0
- package/dist/client.cjs.map +0 -1
- package/dist/client.d.cts.map +0 -1
- package/dist/client.d.mts.map +0 -1
- package/dist/client.mjs.map +0 -1
- package/dist/errors.cjs +0 -53
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -39
- package/dist/errors.d.cts.map +0 -1
- package/dist/errors.d.mts +0 -39
- package/dist/errors.d.mts.map +0 -1
- package/dist/errors.mjs +0 -50
- package/dist/errors.mjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/dist/url.cjs +0 -61
- package/dist/url.cjs.map +0 -1
- package/dist/url.d.cts +0 -16
- package/dist/url.d.cts.map +0 -1
- package/dist/url.d.mts +0 -16
- package/dist/url.d.mts.map +0 -1
- package/dist/url.mjs +0 -60
- package/dist/url.mjs.map +0 -1
package/src/types.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { Address } from 'nodemailer/lib/mailer';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
export interface EmailOptions {
|
|
5
|
+
from: string | Address;
|
|
6
|
+
to: string | string[] | Address[];
|
|
7
|
+
cc?: string | string[] | Address[];
|
|
8
|
+
bcc?: string | string[] | Address[];
|
|
9
|
+
subject: string;
|
|
10
|
+
replyTo?: string | Address;
|
|
11
|
+
attachments?: Attachment[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface Attachment {
|
|
15
|
+
filename: string;
|
|
16
|
+
content?: string | Buffer;
|
|
17
|
+
path?: string;
|
|
18
|
+
contentType?: string;
|
|
19
|
+
cid?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface PlainEmailOptions extends EmailOptions {
|
|
23
|
+
text?: string;
|
|
24
|
+
html?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type SendOptions = Omit<PlainEmailOptions, 'from'> & {
|
|
28
|
+
from?: string | Address;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface SMTPConfig {
|
|
32
|
+
host: string;
|
|
33
|
+
port: number;
|
|
34
|
+
secure?: boolean;
|
|
35
|
+
auth?: {
|
|
36
|
+
user: string;
|
|
37
|
+
pass: string;
|
|
38
|
+
};
|
|
39
|
+
tls?: {
|
|
40
|
+
rejectUnauthorized?: boolean;
|
|
41
|
+
servername?: string;
|
|
42
|
+
};
|
|
43
|
+
pool?: boolean;
|
|
44
|
+
maxConnections?: number;
|
|
45
|
+
maxMessages?: number;
|
|
46
|
+
rateLimit?: number;
|
|
47
|
+
logger?: boolean;
|
|
48
|
+
debug?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface SendResult {
|
|
52
|
+
messageId: string;
|
|
53
|
+
accepted: string[];
|
|
54
|
+
rejected: string[];
|
|
55
|
+
response: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type EmailTemplate<T = any> = (props: T) => ReactElement;
|
|
59
|
+
|
|
60
|
+
// Extract props type from a template function
|
|
61
|
+
export type TemplateProps<T> = T extends EmailTemplate<infer P> ? P : never;
|
|
62
|
+
|
|
63
|
+
// Template record type for type safety
|
|
64
|
+
export type TemplateRecord = Record<string, EmailTemplate<any>>;
|
|
65
|
+
|
|
66
|
+
// Extract template names from template record
|
|
67
|
+
export type TemplateNames<T extends TemplateRecord> = keyof T;
|
|
68
|
+
|
|
69
|
+
// Extract props for a specific template
|
|
70
|
+
export type TemplatePropsFor<
|
|
71
|
+
T extends TemplateRecord,
|
|
72
|
+
K extends TemplateNames<T>,
|
|
73
|
+
> = TemplateProps<T[K]>;
|
|
74
|
+
|
|
75
|
+
export interface EmailClientConfig<T extends TemplateRecord = TemplateRecord> {
|
|
76
|
+
smtp: SMTPConfig;
|
|
77
|
+
templates: T;
|
|
78
|
+
dkim?: {
|
|
79
|
+
domainName: string;
|
|
80
|
+
keySelector: string;
|
|
81
|
+
privateKey: string;
|
|
82
|
+
};
|
|
83
|
+
defaults: {
|
|
84
|
+
from?: string | Address;
|
|
85
|
+
replyTo?: string | Address;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface EmailClient<T extends TemplateRecord = TemplateRecord> {
|
|
90
|
+
send(options: SendOptions): Promise<SendResult>;
|
|
91
|
+
sendTemplate<K extends TemplateNames<T>>(
|
|
92
|
+
template: K,
|
|
93
|
+
options: SendOptions & {
|
|
94
|
+
props: TemplatePropsFor<T, K>;
|
|
95
|
+
},
|
|
96
|
+
): Promise<SendResult>;
|
|
97
|
+
verify(): Promise<boolean>;
|
|
98
|
+
close(): Promise<void>;
|
|
99
|
+
}
|
package/tsconfig.json
ADDED
package/dist/client.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.cjs","names":["render","trace","SpanKind","SpanStatusCode"],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype Attributes,\n\tSpanKind,\n\tSpanStatusCode,\n\ttrace,\n} from '@opentelemetry/api';\nimport { render } from '@react-email/components';\nimport nodemailer, { type Transporter } from 'nodemailer';\nimport type {\n\tEmailClient,\n\tEmailClientConfig,\n\tSendOptions,\n\tSendResult,\n\tTemplateNames,\n\tTemplatePropsFor,\n\tTemplateRecord,\n} from './types';\n\nexport class SMTPClient<T extends TemplateRecord> implements EmailClient<T> {\n\tprivate transporter: Transporter;\n\tprivate config: EmailClientConfig<T>;\n\n\tconstructor(config: EmailClientConfig<T>) {\n\t\tthis.config = config;\n\t\tthis.transporter = nodemailer.createTransport(config.smtp as any);\n\t}\n\n\t/**\n\t * Send one message. An `email.send` span covers it, through the global\n\t * OpenTelemetry tracer: the transport and how many were accepted or\n\t * rejected, never an address, subject or body.\n\t */\n\tasync send(options: SendOptions): Promise<SendResult> {\n\t\treturn traceSend({ 'email.recipients': recipients(options) }, () =>\n\t\t\tthis.deliver(options),\n\t\t);\n\t}\n\n\tprivate async deliver(options: SendOptions): Promise<SendResult> {\n\t\tconst mailOptions = {\n\t\t\t...this.config.defaults,\n\t\t\t...options,\n\t\t};\n\n\t\tif (!mailOptions.from) {\n\t\t\tthrow new Error(\n\t\t\t\t'The \"from\" field is required in email options or defaults',\n\t\t\t);\n\t\t}\n\n\t\tif (!mailOptions.text && !mailOptions.html) {\n\t\t\tthrow new Error('Either text or html content must be provided');\n\t\t}\n\n\t\tconst info = await this.transporter.sendMail(mailOptions);\n\n\t\treturn {\n\t\t\tmessageId: info.messageId,\n\t\t\taccepted: info.accepted || [],\n\t\t\trejected: info.rejected || [],\n\t\t\tresponse: info.response,\n\t\t};\n\t}\n\n\tasync sendTemplate<K extends TemplateNames<T>>(\n\t\ttemplate: K,\n\t\toptions: Omit<SendOptions, 'template'> & {\n\t\t\tprops: TemplatePropsFor<T, K>;\n\t\t},\n\t): Promise<SendResult> {\n\t\tconst Component = this.config.templates[template];\n\t\tif (!Component) {\n\t\t\tthrow new Error(`Template \"${String(template)}\" not found`);\n\t\t}\n\n\t\tconst element = Component(options.props);\n\t\tconst html = await render(element);\n\n\t\treturn traceSend(\n\t\t\t{\n\t\t\t\t'email.template': String(template),\n\t\t\t\t'email.recipients': recipients(options),\n\t\t\t},\n\t\t\t() => this.deliver({ ...options, html }),\n\t\t);\n\t}\n\n\tasync verify(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.transporter.verify();\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.transporter.close();\n\t}\n\n\tgetTemplateNames(): TemplateNames<T>[] {\n\t\treturn Object.keys(this.config.templates) as TemplateNames<T>[];\n\t}\n}\n\nexport function createEmailClient<T extends TemplateRecord>(\n\tconfig: EmailClientConfig<T>,\n): SMTPClient<T> {\n\treturn new SMTPClient(config);\n}\n\n/** How many addresses a message is for: to, cc and bcc. */\nfunction recipients(options: {\n\tto?: unknown;\n\tcc?: unknown;\n\tbcc?: unknown;\n}): number {\n\treturn count(options.to) + count(options.cc) + count(options.bcc);\n}\n\nfunction count(value: unknown): number {\n\tif (!value) return 0;\n\treturn Array.isArray(value) ? value.length : 1;\n}\n\nasync function traceSend(\n\tattributes: Attributes,\n\tsend: () => Promise<SendResult>,\n): Promise<SendResult> {\n\tconst span = trace.getTracer('@geekmidas/emailkit').startSpan('email.send', {\n\t\tkind: SpanKind.CLIENT,\n\t\tattributes: { 'email.transport': 'smtp', ...attributes },\n\t});\n\ttry {\n\t\tconst result = await send();\n\t\t// What the server said, when the transport reports it.\n\t\tif (result.accepted.length || result.rejected.length) {\n\t\t\tspan.setAttributes({\n\t\t\t\t'email.accepted': count(result.accepted),\n\t\t\t\t'email.rejected': count(result.rejected),\n\t\t\t});\n\t\t}\n\t\treturn result;\n\t} catch (error) {\n\t\tif (error instanceof Error) span.recordException(error);\n\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\tthrow error;\n\t} finally {\n\t\tspan.end();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,IAAa,aAAb,MAA4E;CAC3E;CACA;CAEA,YAAY,QAA8B;EACzC,KAAK,SAAS;EACd,KAAK,cAAc,WAAA,QAAW,gBAAgB,OAAO,IAAW;CACjE;;;;;;CAOA,MAAM,KAAK,SAA2C;EACrD,OAAO,UAAU,EAAE,oBAAoB,WAAW,OAAO,EAAE,SAC1D,KAAK,QAAQ,OAAO,CACrB;CACD;CAEA,MAAc,QAAQ,SAA2C;EAChE,MAAM,cAAc;GACnB,GAAG,KAAK,OAAO;GACf,GAAG;EACJ;EAEA,IAAI,CAAC,YAAY,MAChB,MAAM,IAAI,MACT,6DACD;EAGD,IAAI,CAAC,YAAY,QAAQ,CAAC,YAAY,MACrC,MAAM,IAAI,MAAM,8CAA8C;EAG/D,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS,WAAW;EAExD,OAAO;GACN,WAAW,KAAK;GAChB,UAAU,KAAK,YAAY,CAAC;GAC5B,UAAU,KAAK,YAAY,CAAC;GAC5B,UAAU,KAAK;EAChB;CACD;CAEA,MAAM,aACL,UACA,SAGsB;EACtB,MAAM,YAAY,KAAK,OAAO,UAAU;EACxC,IAAI,CAAC,WACJ,MAAM,IAAI,MAAM,aAAa,OAAO,QAAQ,EAAE,YAAY;EAG3D,MAAM,UAAU,UAAU,QAAQ,KAAK;EACvC,MAAM,OAAO,OAAA,GAAMA,wBAAAA,OAAAA,CAAO,OAAO;EAEjC,OAAO,UACN;GACC,kBAAkB,OAAO,QAAQ;GACjC,oBAAoB,WAAW,OAAO;EACvC,SACM,KAAK,QAAQ;GAAE,GAAG;GAAS;EAAK,CAAC,CACxC;CACD;CAEA,MAAM,SAA2B;EAChC,IAAI;GACH,MAAM,KAAK,YAAY,OAAO;GAC9B,OAAO;EACR,QAAQ;GACP,OAAO;EACR;CACD;CAEA,MAAM,QAAuB;EAC5B,KAAK,YAAY,MAAM;CACxB;CAEA,mBAAuC;EACtC,OAAO,OAAO,KAAK,KAAK,OAAO,SAAS;CACzC;AACD;AAEA,SAAgB,kBACf,QACgB;CAChB,OAAO,IAAI,WAAW,MAAM;AAC7B;;AAGA,SAAS,WAAW,SAIT;CACV,OAAO,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,GAAG;AACjE;AAEA,SAAS,MAAM,OAAwB;CACtC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS;AAC9C;AAEA,eAAe,UACd,YACA,MACsB;CACtB,MAAM,OAAOC,mBAAAA,MAAM,UAAU,qBAAqB,CAAC,CAAC,UAAU,cAAc;EAC3E,MAAMC,mBAAAA,SAAS;EACf,YAAY;GAAE,mBAAmB;GAAQ,GAAG;EAAW;CACxD,CAAC;CACD,IAAI;EACH,MAAM,SAAS,MAAM,KAAK;EAE1B,IAAI,OAAO,SAAS,UAAU,OAAO,SAAS,QAC7C,KAAK,cAAc;GAClB,kBAAkB,MAAM,OAAO,QAAQ;GACvC,kBAAkB,MAAM,OAAO,QAAQ;EACxC,CAAC;EAEF,OAAO;CACR,SAAS,OAAO;EACf,IAAI,iBAAiB,OAAO,KAAK,gBAAgB,KAAK;EACtD,KAAK,UAAU,EAAE,MAAMC,mBAAAA,eAAe,MAAM,CAAC;EAC7C,MAAM;CACP,UAAU;EACT,KAAK,IAAI;CACV;AACD"}
|
package/dist/client.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.cts","names":[],"sources":["../src/client.ts"],"mappings":";;qBAkBa,WAAW,UAAU,2BAA2B,YAAY;UAChE;UACA;EAER,YAAY,QAAQ,kBAAkB;;;;;;EAUhC,KAAK,SAAS,cAAc,QAAQ;UAM5B;EA0BR,aAAa,UAAU,cAAc,IAC1C,UAAU,GACV,SAAS,KAAK;IACb,OAAO,iBAAiB,GAAG;MAE1B,QAAQ;EAkBL,UAAU;EASV,SAAS;EAIf,oBAAoB,cAAc;;wBAKnB,kBAAkB,UAAU,gBAC3C,QAAQ,kBAAkB,KACxB,WAAW"}
|
package/dist/client.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;qBAkBa,WAAW,UAAU,2BAA2B,YAAY;UAChE;UACA;EAER,YAAY,QAAQ,kBAAkB;;;;;;EAUhC,KAAK,SAAS,cAAc,QAAQ;UAM5B;EA0BR,aAAa,UAAU,cAAc,IAC1C,UAAU,GACV,SAAS,KAAK;IACb,OAAO,iBAAiB,GAAG;MAE1B,QAAQ;EAkBL,UAAU;EASV,SAAS;EAIf,oBAAoB,cAAc;;wBAKnB,kBAAkB,UAAU,gBAC3C,QAAQ,kBAAkB,KACxB,WAAW"}
|
package/dist/client.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n\ttype Attributes,\n\tSpanKind,\n\tSpanStatusCode,\n\ttrace,\n} from '@opentelemetry/api';\nimport { render } from '@react-email/components';\nimport nodemailer, { type Transporter } from 'nodemailer';\nimport type {\n\tEmailClient,\n\tEmailClientConfig,\n\tSendOptions,\n\tSendResult,\n\tTemplateNames,\n\tTemplatePropsFor,\n\tTemplateRecord,\n} from './types';\n\nexport class SMTPClient<T extends TemplateRecord> implements EmailClient<T> {\n\tprivate transporter: Transporter;\n\tprivate config: EmailClientConfig<T>;\n\n\tconstructor(config: EmailClientConfig<T>) {\n\t\tthis.config = config;\n\t\tthis.transporter = nodemailer.createTransport(config.smtp as any);\n\t}\n\n\t/**\n\t * Send one message. An `email.send` span covers it, through the global\n\t * OpenTelemetry tracer: the transport and how many were accepted or\n\t * rejected, never an address, subject or body.\n\t */\n\tasync send(options: SendOptions): Promise<SendResult> {\n\t\treturn traceSend({ 'email.recipients': recipients(options) }, () =>\n\t\t\tthis.deliver(options),\n\t\t);\n\t}\n\n\tprivate async deliver(options: SendOptions): Promise<SendResult> {\n\t\tconst mailOptions = {\n\t\t\t...this.config.defaults,\n\t\t\t...options,\n\t\t};\n\n\t\tif (!mailOptions.from) {\n\t\t\tthrow new Error(\n\t\t\t\t'The \"from\" field is required in email options or defaults',\n\t\t\t);\n\t\t}\n\n\t\tif (!mailOptions.text && !mailOptions.html) {\n\t\t\tthrow new Error('Either text or html content must be provided');\n\t\t}\n\n\t\tconst info = await this.transporter.sendMail(mailOptions);\n\n\t\treturn {\n\t\t\tmessageId: info.messageId,\n\t\t\taccepted: info.accepted || [],\n\t\t\trejected: info.rejected || [],\n\t\t\tresponse: info.response,\n\t\t};\n\t}\n\n\tasync sendTemplate<K extends TemplateNames<T>>(\n\t\ttemplate: K,\n\t\toptions: Omit<SendOptions, 'template'> & {\n\t\t\tprops: TemplatePropsFor<T, K>;\n\t\t},\n\t): Promise<SendResult> {\n\t\tconst Component = this.config.templates[template];\n\t\tif (!Component) {\n\t\t\tthrow new Error(`Template \"${String(template)}\" not found`);\n\t\t}\n\n\t\tconst element = Component(options.props);\n\t\tconst html = await render(element);\n\n\t\treturn traceSend(\n\t\t\t{\n\t\t\t\t'email.template': String(template),\n\t\t\t\t'email.recipients': recipients(options),\n\t\t\t},\n\t\t\t() => this.deliver({ ...options, html }),\n\t\t);\n\t}\n\n\tasync verify(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.transporter.verify();\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.transporter.close();\n\t}\n\n\tgetTemplateNames(): TemplateNames<T>[] {\n\t\treturn Object.keys(this.config.templates) as TemplateNames<T>[];\n\t}\n}\n\nexport function createEmailClient<T extends TemplateRecord>(\n\tconfig: EmailClientConfig<T>,\n): SMTPClient<T> {\n\treturn new SMTPClient(config);\n}\n\n/** How many addresses a message is for: to, cc and bcc. */\nfunction recipients(options: {\n\tto?: unknown;\n\tcc?: unknown;\n\tbcc?: unknown;\n}): number {\n\treturn count(options.to) + count(options.cc) + count(options.bcc);\n}\n\nfunction count(value: unknown): number {\n\tif (!value) return 0;\n\treturn Array.isArray(value) ? value.length : 1;\n}\n\nasync function traceSend(\n\tattributes: Attributes,\n\tsend: () => Promise<SendResult>,\n): Promise<SendResult> {\n\tconst span = trace.getTracer('@geekmidas/emailkit').startSpan('email.send', {\n\t\tkind: SpanKind.CLIENT,\n\t\tattributes: { 'email.transport': 'smtp', ...attributes },\n\t});\n\ttry {\n\t\tconst result = await send();\n\t\t// What the server said, when the transport reports it.\n\t\tif (result.accepted.length || result.rejected.length) {\n\t\t\tspan.setAttributes({\n\t\t\t\t'email.accepted': count(result.accepted),\n\t\t\t\t'email.rejected': count(result.rejected),\n\t\t\t});\n\t\t}\n\t\treturn result;\n\t} catch (error) {\n\t\tif (error instanceof Error) span.recordException(error);\n\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\tthrow error;\n\t} finally {\n\t\tspan.end();\n\t}\n}\n"],"mappings":";;;;AAkBA,IAAa,aAAb,MAA4E;CAC3E;CACA;CAEA,YAAY,QAA8B;EACzC,KAAK,SAAS;EACd,KAAK,cAAc,WAAW,gBAAgB,OAAO,IAAW;CACjE;;;;;;CAOA,MAAM,KAAK,SAA2C;EACrD,OAAO,UAAU,EAAE,oBAAoB,WAAW,OAAO,EAAE,SAC1D,KAAK,QAAQ,OAAO,CACrB;CACD;CAEA,MAAc,QAAQ,SAA2C;EAChE,MAAM,cAAc;GACnB,GAAG,KAAK,OAAO;GACf,GAAG;EACJ;EAEA,IAAI,CAAC,YAAY,MAChB,MAAM,IAAI,MACT,6DACD;EAGD,IAAI,CAAC,YAAY,QAAQ,CAAC,YAAY,MACrC,MAAM,IAAI,MAAM,8CAA8C;EAG/D,MAAM,OAAO,MAAM,KAAK,YAAY,SAAS,WAAW;EAExD,OAAO;GACN,WAAW,KAAK;GAChB,UAAU,KAAK,YAAY,CAAC;GAC5B,UAAU,KAAK,YAAY,CAAC;GAC5B,UAAU,KAAK;EAChB;CACD;CAEA,MAAM,aACL,UACA,SAGsB;EACtB,MAAM,YAAY,KAAK,OAAO,UAAU;EACxC,IAAI,CAAC,WACJ,MAAM,IAAI,MAAM,aAAa,OAAO,QAAQ,EAAE,YAAY;EAG3D,MAAM,UAAU,UAAU,QAAQ,KAAK;EACvC,MAAM,OAAO,MAAM,OAAO,OAAO;EAEjC,OAAO,UACN;GACC,kBAAkB,OAAO,QAAQ;GACjC,oBAAoB,WAAW,OAAO;EACvC,SACM,KAAK,QAAQ;GAAE,GAAG;GAAS;EAAK,CAAC,CACxC;CACD;CAEA,MAAM,SAA2B;EAChC,IAAI;GACH,MAAM,KAAK,YAAY,OAAO;GAC9B,OAAO;EACR,QAAQ;GACP,OAAO;EACR;CACD;CAEA,MAAM,QAAuB;EAC5B,KAAK,YAAY,MAAM;CACxB;CAEA,mBAAuC;EACtC,OAAO,OAAO,KAAK,KAAK,OAAO,SAAS;CACzC;AACD;AAEA,SAAgB,kBACf,QACgB;CAChB,OAAO,IAAI,WAAW,MAAM;AAC7B;;AAGA,SAAS,WAAW,SAIT;CACV,OAAO,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,GAAG;AACjE;AAEA,SAAS,MAAM,OAAwB;CACtC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS;AAC9C;AAEA,eAAe,UACd,YACA,MACsB;CACtB,MAAM,OAAO,MAAM,UAAU,qBAAqB,CAAC,CAAC,UAAU,cAAc;EAC3E,MAAM,SAAS;EACf,YAAY;GAAE,mBAAmB;GAAQ,GAAG;EAAW;CACxD,CAAC;CACD,IAAI;EACH,MAAM,SAAS,MAAM,KAAK;EAE1B,IAAI,OAAO,SAAS,UAAU,OAAO,SAAS,QAC7C,KAAK,cAAc;GAClB,kBAAkB,MAAM,OAAO,QAAQ;GACvC,kBAAkB,MAAM,OAAO,QAAQ;EACxC,CAAC;EAEF,OAAO;CACR,SAAS,OAAO;EACf,IAAI,iBAAiB,OAAO,KAAK,gBAAgB,KAAK;EACtD,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;EAC7C,MAAM;CACP,UAAU;EACT,KAAK,IAAI;CACV;AACD"}
|
package/dist/errors.cjs
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
//#region src/errors.ts
|
|
3
|
-
/**
|
|
4
|
-
* Email URL errors.
|
|
5
|
-
*
|
|
6
|
-
* Every provider is reached over SMTP, so there are only two problems a URL can
|
|
7
|
-
* have: it is not a URL, or it names a scheme this transport cannot speak. Both
|
|
8
|
-
* carry the offending value as a field.
|
|
9
|
-
*
|
|
10
|
-
* Messages state the rule, which is constant, and never interpolate the value.
|
|
11
|
-
* An interpolated message cannot be matched on, reads differently every time it
|
|
12
|
-
* is thrown, and carries user input into every log line that touches it — and a
|
|
13
|
-
* mail URL's userinfo is a credential, which makes that leak a real one here.
|
|
14
|
-
*/
|
|
15
|
-
/** Base for anything wrong with an email URL, so callers may catch broadly. */
|
|
16
|
-
var EmailUrlError = class extends Error {
|
|
17
|
-
/** The URL that could not be used. Carries credentials — do not log it. */
|
|
18
|
-
url;
|
|
19
|
-
constructor(url, message) {
|
|
20
|
-
super(message);
|
|
21
|
-
this.url = url;
|
|
22
|
-
this.name = new.target.name;
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
/** The string is not a URL at all. */
|
|
26
|
-
var MalformedEmailUrl = class extends EmailUrlError {
|
|
27
|
-
constructor(url) {
|
|
28
|
-
super(url, "Not a valid URL");
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* A URL, but naming a scheme that is not SMTP.
|
|
33
|
-
*
|
|
34
|
-
* Almost always `ses://` or `resend://` — a provider written where a protocol
|
|
35
|
-
* belongs. Mail is delivered over SMTP whoever is delivering it, so the provider
|
|
36
|
-
* shows up as the URL's host and credentials, never as its scheme.
|
|
37
|
-
*/
|
|
38
|
-
var UnsupportedEmailScheme = class extends EmailUrlError {
|
|
39
|
-
/** The scheme the URL carried, e.g. `'ses:'`. */
|
|
40
|
-
actual;
|
|
41
|
-
/** The schemes this transport speaks. */
|
|
42
|
-
expected = ["smtp:", "smtps:"];
|
|
43
|
-
constructor(url, actual) {
|
|
44
|
-
super(url, "Email URL scheme must be smtp: or smtps:");
|
|
45
|
-
this.actual = actual;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
//#endregion
|
|
49
|
-
exports.EmailUrlError = EmailUrlError;
|
|
50
|
-
exports.MalformedEmailUrl = MalformedEmailUrl;
|
|
51
|
-
exports.UnsupportedEmailScheme = UnsupportedEmailScheme;
|
|
52
|
-
|
|
53
|
-
//# sourceMappingURL=errors.cjs.map
|
package/dist/errors.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Email URL errors.\n *\n * Every provider is reached over SMTP, so there are only two problems a URL can\n * have: it is not a URL, or it names a scheme this transport cannot speak. Both\n * carry the offending value as a field.\n *\n * Messages state the rule, which is constant, and never interpolate the value.\n * An interpolated message cannot be matched on, reads differently every time it\n * is thrown, and carries user input into every log line that touches it — and a\n * mail URL's userinfo is a credential, which makes that leak a real one here.\n */\n\n/** Base for anything wrong with an email URL, so callers may catch broadly. */\nexport abstract class EmailUrlError extends Error {\n\t/** The URL that could not be used. Carries credentials — do not log it. */\n\treadonly url: string;\n\n\tconstructor(url: string, message: string) {\n\t\tsuper(message);\n\t\tthis.url = url;\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** The string is not a URL at all. */\nexport class MalformedEmailUrl extends EmailUrlError {\n\tconstructor(url: string) {\n\t\tsuper(url, 'Not a valid URL');\n\t}\n}\n\n/**\n * A URL, but naming a scheme that is not SMTP.\n *\n * Almost always `ses://` or `resend://` — a provider written where a protocol\n * belongs. Mail is delivered over SMTP whoever is delivering it, so the provider\n * shows up as the URL's host and credentials, never as its scheme.\n */\nexport class UnsupportedEmailScheme extends EmailUrlError {\n\t/** The scheme the URL carried, e.g. `'ses:'`. */\n\treadonly actual: string;\n\t/** The schemes this transport speaks. */\n\treadonly expected: readonly string[] = ['smtp:', 'smtps:'];\n\n\tconstructor(url: string, actual: string) {\n\t\tsuper(url, 'Email URL scheme must be smtp: or smtps:');\n\t\tthis.actual = actual;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;AAcA,IAAsB,gBAAtB,cAA4C,MAAM;;CAEjD;CAEA,YAAY,KAAa,SAAiB;EACzC,MAAM,OAAO;EACb,KAAK,MAAM;EACX,KAAK,OAAO,WAAW;CACxB;AACD;;AAGA,IAAa,oBAAb,cAAuC,cAAc;CACpD,YAAY,KAAa;EACxB,MAAM,KAAK,iBAAiB;CAC7B;AACD;;;;;;;;AASA,IAAa,yBAAb,cAA4C,cAAc;;CAEzD;;CAEA,WAAuC,CAAC,SAAS,QAAQ;CAEzD,YAAY,KAAa,QAAgB;EACxC,MAAM,KAAK,0CAA0C;EACrD,KAAK,SAAS;CACf;AACD"}
|
package/dist/errors.d.cts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
//#region src/errors.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Email URL errors.
|
|
4
|
-
*
|
|
5
|
-
* Every provider is reached over SMTP, so there are only two problems a URL can
|
|
6
|
-
* have: it is not a URL, or it names a scheme this transport cannot speak. Both
|
|
7
|
-
* carry the offending value as a field.
|
|
8
|
-
*
|
|
9
|
-
* Messages state the rule, which is constant, and never interpolate the value.
|
|
10
|
-
* An interpolated message cannot be matched on, reads differently every time it
|
|
11
|
-
* is thrown, and carries user input into every log line that touches it — and a
|
|
12
|
-
* mail URL's userinfo is a credential, which makes that leak a real one here.
|
|
13
|
-
*/
|
|
14
|
-
/** Base for anything wrong with an email URL, so callers may catch broadly. */
|
|
15
|
-
export declare abstract class EmailUrlError extends Error {
|
|
16
|
-
/** The URL that could not be used. Carries credentials — do not log it. */
|
|
17
|
-
readonly url: string;
|
|
18
|
-
constructor(url: string, message: string);
|
|
19
|
-
}
|
|
20
|
-
/** The string is not a URL at all. */
|
|
21
|
-
export declare class MalformedEmailUrl extends EmailUrlError {
|
|
22
|
-
constructor(url: string);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* A URL, but naming a scheme that is not SMTP.
|
|
26
|
-
*
|
|
27
|
-
* Almost always `ses://` or `resend://` — a provider written where a protocol
|
|
28
|
-
* belongs. Mail is delivered over SMTP whoever is delivering it, so the provider
|
|
29
|
-
* shows up as the URL's host and credentials, never as its scheme.
|
|
30
|
-
*/
|
|
31
|
-
export declare class UnsupportedEmailScheme extends EmailUrlError {
|
|
32
|
-
/** The scheme the URL carried, e.g. `'ses:'`. */
|
|
33
|
-
readonly actual: string;
|
|
34
|
-
/** The schemes this transport speaks. */
|
|
35
|
-
readonly expected: readonly string[];
|
|
36
|
-
constructor(url: string, actual: string);
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
|
-
//# sourceMappingURL=errors.d.cts.map
|
package/dist/errors.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.cts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;;;;;;;;;;;8BAcsB,sBAAsB;;WAElC;EAET,YAAY,aAAa;;;qBAQb,0BAA0B;EACtC,YAAY;;;;;;;;;qBAYA,+BAA+B;;WAElC;;WAEA;EAET,YAAY,aAAa"}
|
package/dist/errors.d.mts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
//#region src/errors.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Email URL errors.
|
|
4
|
-
*
|
|
5
|
-
* Every provider is reached over SMTP, so there are only two problems a URL can
|
|
6
|
-
* have: it is not a URL, or it names a scheme this transport cannot speak. Both
|
|
7
|
-
* carry the offending value as a field.
|
|
8
|
-
*
|
|
9
|
-
* Messages state the rule, which is constant, and never interpolate the value.
|
|
10
|
-
* An interpolated message cannot be matched on, reads differently every time it
|
|
11
|
-
* is thrown, and carries user input into every log line that touches it — and a
|
|
12
|
-
* mail URL's userinfo is a credential, which makes that leak a real one here.
|
|
13
|
-
*/
|
|
14
|
-
/** Base for anything wrong with an email URL, so callers may catch broadly. */
|
|
15
|
-
export declare abstract class EmailUrlError extends Error {
|
|
16
|
-
/** The URL that could not be used. Carries credentials — do not log it. */
|
|
17
|
-
readonly url: string;
|
|
18
|
-
constructor(url: string, message: string);
|
|
19
|
-
}
|
|
20
|
-
/** The string is not a URL at all. */
|
|
21
|
-
export declare class MalformedEmailUrl extends EmailUrlError {
|
|
22
|
-
constructor(url: string);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* A URL, but naming a scheme that is not SMTP.
|
|
26
|
-
*
|
|
27
|
-
* Almost always `ses://` or `resend://` — a provider written where a protocol
|
|
28
|
-
* belongs. Mail is delivered over SMTP whoever is delivering it, so the provider
|
|
29
|
-
* shows up as the URL's host and credentials, never as its scheme.
|
|
30
|
-
*/
|
|
31
|
-
export declare class UnsupportedEmailScheme extends EmailUrlError {
|
|
32
|
-
/** The scheme the URL carried, e.g. `'ses:'`. */
|
|
33
|
-
readonly actual: string;
|
|
34
|
-
/** The schemes this transport speaks. */
|
|
35
|
-
readonly expected: readonly string[];
|
|
36
|
-
constructor(url: string, actual: string);
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
|
-
//# sourceMappingURL=errors.d.mts.map
|
package/dist/errors.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../src/errors.ts"],"mappings":";;;;;;;;;;;;;;8BAcsB,sBAAsB;;WAElC;EAET,YAAY,aAAa;;;qBAQb,0BAA0B;EACtC,YAAY;;;;;;;;;qBAYA,+BAA+B;;WAElC;;WAEA;EAET,YAAY,aAAa"}
|
package/dist/errors.mjs
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
//#region src/errors.ts
|
|
2
|
-
/**
|
|
3
|
-
* Email URL errors.
|
|
4
|
-
*
|
|
5
|
-
* Every provider is reached over SMTP, so there are only two problems a URL can
|
|
6
|
-
* have: it is not a URL, or it names a scheme this transport cannot speak. Both
|
|
7
|
-
* carry the offending value as a field.
|
|
8
|
-
*
|
|
9
|
-
* Messages state the rule, which is constant, and never interpolate the value.
|
|
10
|
-
* An interpolated message cannot be matched on, reads differently every time it
|
|
11
|
-
* is thrown, and carries user input into every log line that touches it — and a
|
|
12
|
-
* mail URL's userinfo is a credential, which makes that leak a real one here.
|
|
13
|
-
*/
|
|
14
|
-
/** Base for anything wrong with an email URL, so callers may catch broadly. */
|
|
15
|
-
var EmailUrlError = class extends Error {
|
|
16
|
-
/** The URL that could not be used. Carries credentials — do not log it. */
|
|
17
|
-
url;
|
|
18
|
-
constructor(url, message) {
|
|
19
|
-
super(message);
|
|
20
|
-
this.url = url;
|
|
21
|
-
this.name = new.target.name;
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
/** The string is not a URL at all. */
|
|
25
|
-
var MalformedEmailUrl = class extends EmailUrlError {
|
|
26
|
-
constructor(url) {
|
|
27
|
-
super(url, "Not a valid URL");
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* A URL, but naming a scheme that is not SMTP.
|
|
32
|
-
*
|
|
33
|
-
* Almost always `ses://` or `resend://` — a provider written where a protocol
|
|
34
|
-
* belongs. Mail is delivered over SMTP whoever is delivering it, so the provider
|
|
35
|
-
* shows up as the URL's host and credentials, never as its scheme.
|
|
36
|
-
*/
|
|
37
|
-
var UnsupportedEmailScheme = class extends EmailUrlError {
|
|
38
|
-
/** The scheme the URL carried, e.g. `'ses:'`. */
|
|
39
|
-
actual;
|
|
40
|
-
/** The schemes this transport speaks. */
|
|
41
|
-
expected = ["smtp:", "smtps:"];
|
|
42
|
-
constructor(url, actual) {
|
|
43
|
-
super(url, "Email URL scheme must be smtp: or smtps:");
|
|
44
|
-
this.actual = actual;
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
//#endregion
|
|
48
|
-
export { EmailUrlError, MalformedEmailUrl, UnsupportedEmailScheme };
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=errors.mjs.map
|
package/dist/errors.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Email URL errors.\n *\n * Every provider is reached over SMTP, so there are only two problems a URL can\n * have: it is not a URL, or it names a scheme this transport cannot speak. Both\n * carry the offending value as a field.\n *\n * Messages state the rule, which is constant, and never interpolate the value.\n * An interpolated message cannot be matched on, reads differently every time it\n * is thrown, and carries user input into every log line that touches it — and a\n * mail URL's userinfo is a credential, which makes that leak a real one here.\n */\n\n/** Base for anything wrong with an email URL, so callers may catch broadly. */\nexport abstract class EmailUrlError extends Error {\n\t/** The URL that could not be used. Carries credentials — do not log it. */\n\treadonly url: string;\n\n\tconstructor(url: string, message: string) {\n\t\tsuper(message);\n\t\tthis.url = url;\n\t\tthis.name = new.target.name;\n\t}\n}\n\n/** The string is not a URL at all. */\nexport class MalformedEmailUrl extends EmailUrlError {\n\tconstructor(url: string) {\n\t\tsuper(url, 'Not a valid URL');\n\t}\n}\n\n/**\n * A URL, but naming a scheme that is not SMTP.\n *\n * Almost always `ses://` or `resend://` — a provider written where a protocol\n * belongs. Mail is delivered over SMTP whoever is delivering it, so the provider\n * shows up as the URL's host and credentials, never as its scheme.\n */\nexport class UnsupportedEmailScheme extends EmailUrlError {\n\t/** The scheme the URL carried, e.g. `'ses:'`. */\n\treadonly actual: string;\n\t/** The schemes this transport speaks. */\n\treadonly expected: readonly string[] = ['smtp:', 'smtps:'];\n\n\tconstructor(url: string, actual: string) {\n\t\tsuper(url, 'Email URL scheme must be smtp: or smtps:');\n\t\tthis.actual = actual;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,IAAsB,gBAAtB,cAA4C,MAAM;;CAEjD;CAEA,YAAY,KAAa,SAAiB;EACzC,MAAM,OAAO;EACb,KAAK,MAAM;EACX,KAAK,OAAO,WAAW;CACxB;AACD;;AAGA,IAAa,oBAAb,cAAuC,cAAc;CACpD,YAAY,KAAa;EACxB,MAAM,KAAK,iBAAiB;CAC7B;AACD;;;;;;;;AASA,IAAa,yBAAb,cAA4C,cAAc;;CAEzD;;CAEA,WAAuC,CAAC,SAAS,QAAQ;CAEzD,YAAY,KAAa,QAAgB;EACxC,MAAM,KAAK,0CAA0C;EACrD,KAAK,SAAS;CACf;AACD"}
|
package/dist/types.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAMK,UAAU,KAAK;iBAEH;EAChB,eAAe;EACf,wBAAwB;EACxB,yBAAyB;EACzB,0BAA0B;EAC1B;EACA,mBAAmB;EACnB,cAAc;;iBAGE;EAChB;EACA,mBAAmB;EACnB;EACA;EACA;;iBAGgB,0BAA0B;EAC1C;EACA;;YAGW,cAAc,KAAK;EAC9B,gBAAgB;;iBAGA;EAChB;EACA;EACA;EACA;IACC;IACA;;EAED;IACC;IACA;;EAED;EACA;EACA;EACA;EACA;EACA;;iBAGgB;EAChB;EACA;EACA;;;;;;;;;EASA;;YAGW,cAAc,YAAY,OAAO,MAAM;YAGvC,cAAc,KAAK,UAAU,oBAAoB,KAAK;YAGtD,iBAAiB,eAAe;YAGhC,cAAc,UAAU,wBAAwB;YAGhD,iBACX,UAAU,gBACV,UAAU,cAAc,MACrB,cAAc,EAAE;iBAEH,kBAAkB,UAAU,iBAAiB;EAC7D,MAAM;EACN,WAAW;EACX;IACC;IACA;IACA;;EAED;IACC,gBAAgB;IAChB,mBAAmB;;;iBAIJ,YAAY,UAAU,iBAAiB;EACvD,KAAK,SAAS,cAAc,QAAQ;EACpC,aAAa,UAAU,cAAc,IACpC,UAAU,GACV,SAAS;IACR,OAAO,iBAAiB,GAAG;MAE1B,QAAQ;EACX,UAAU;EACV,SAAS"}
|
package/dist/types.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;KAMK,UAAU,KAAK;iBAEH;EAChB,eAAe;EACf,wBAAwB;EACxB,yBAAyB;EACzB,0BAA0B;EAC1B;EACA,mBAAmB;EACnB,cAAc;;iBAGE;EAChB;EACA,mBAAmB;EACnB;EACA;EACA;;iBAGgB,0BAA0B;EAC1C;EACA;;YAGW,cAAc,KAAK;EAC9B,gBAAgB;;iBAGA;EAChB;EACA;EACA;EACA;IACC;IACA;;EAED;IACC;IACA;;EAED;EACA;EACA;EACA;EACA;EACA;;iBAGgB;EAChB;EACA;EACA;;;;;;;;;EASA;;YAGW,cAAc,YAAY,OAAO,MAAM;YAGvC,cAAc,KAAK,UAAU,oBAAoB,KAAK;YAGtD,iBAAiB,eAAe;YAGhC,cAAc,UAAU,wBAAwB;YAGhD,iBACX,UAAU,gBACV,UAAU,cAAc,MACrB,cAAc,EAAE;iBAEH,kBAAkB,UAAU,iBAAiB;EAC7D,MAAM;EACN,WAAW;EACX;IACC;IACA;IACA;;EAED;IACC,gBAAgB;IAChB,mBAAmB;;;iBAIJ,YAAY,UAAU,iBAAiB;EACvD,KAAK,SAAS,cAAc,QAAQ;EACpC,aAAa,UAAU,cAAc,IACpC,UAAU,GACV,SAAS;IACR,OAAO,iBAAiB,GAAG;MAE1B,QAAQ;EACX,UAAU;EACV,SAAS"}
|
package/dist/url.cjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_errors = require("./errors.cjs");
|
|
3
|
-
//#region src/url.ts
|
|
4
|
-
/**
|
|
5
|
-
* `smtp://` — the one URL shape an email construct ever provides.
|
|
6
|
-
*
|
|
7
|
-
* Every provider is reached the same way: Mailpit locally, SES through its SMTP
|
|
8
|
-
* interface, Resend and Postmark through theirs. So there is no scheme-keyed
|
|
9
|
-
* driver registry here as there is in `@geekmidas/storage` — one transport, one
|
|
10
|
-
* parser, and the client never branches on who is delivering the mail.
|
|
11
|
-
*
|
|
12
|
-
* What varies between providers is confined to the URL: host, port, and
|
|
13
|
-
* credentials. That is what lets the same handler source run against Mailpit and
|
|
14
|
-
* against SES without a conditional.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* The port to use when the URL names none.
|
|
18
|
-
*
|
|
19
|
-
* 587 is submission-with-STARTTLS, which is what SES, Resend, and Postmark all
|
|
20
|
-
* document; 465 is implicit TLS, which is what `smtps://` means.
|
|
21
|
-
*/
|
|
22
|
-
const DEFAULT_PORT = {
|
|
23
|
-
"smtp:": 587,
|
|
24
|
-
"smtps:": 465
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Build an SMTP transport config from a `<NAME>_URL`.
|
|
28
|
-
*
|
|
29
|
-
* `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on
|
|
30
|
-
* connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,
|
|
31
|
-
* and the reason the scheme is worth having rather than inferring from the port.
|
|
32
|
-
*
|
|
33
|
-
* @example parseEmailUrl('smtp://mailpit:1025')
|
|
34
|
-
* @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')
|
|
35
|
-
* @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')
|
|
36
|
-
*/
|
|
37
|
-
function parseEmailUrl(url) {
|
|
38
|
-
let parsed;
|
|
39
|
-
try {
|
|
40
|
-
parsed = new URL(url);
|
|
41
|
-
} catch {
|
|
42
|
-
throw new require_errors.MalformedEmailUrl(url);
|
|
43
|
-
}
|
|
44
|
-
if (parsed.protocol !== "smtp:" && parsed.protocol !== "smtps:") throw new require_errors.UnsupportedEmailScheme(url, parsed.protocol);
|
|
45
|
-
const secure = parsed.protocol === "smtps:";
|
|
46
|
-
const config = {
|
|
47
|
-
host: parsed.hostname,
|
|
48
|
-
port: parsed.port ? Number(parsed.port) : DEFAULT_PORT[parsed.protocol],
|
|
49
|
-
secure
|
|
50
|
-
};
|
|
51
|
-
if (parsed.username) config.auth = {
|
|
52
|
-
user: decodeURIComponent(parsed.username),
|
|
53
|
-
pass: decodeURIComponent(parsed.password)
|
|
54
|
-
};
|
|
55
|
-
if (parsed.searchParams.get("insecure") === "true") config.tls = { rejectUnauthorized: false };
|
|
56
|
-
return config;
|
|
57
|
-
}
|
|
58
|
-
//#endregion
|
|
59
|
-
exports.parseEmailUrl = parseEmailUrl;
|
|
60
|
-
|
|
61
|
-
//# sourceMappingURL=url.cjs.map
|
package/dist/url.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.cjs","names":["MalformedEmailUrl","UnsupportedEmailScheme"],"sources":["../src/url.ts"],"sourcesContent":["/**\n * `smtp://` — the one URL shape an email construct ever provides.\n *\n * Every provider is reached the same way: Mailpit locally, SES through its SMTP\n * interface, Resend and Postmark through theirs. So there is no scheme-keyed\n * driver registry here as there is in `@geekmidas/storage` — one transport, one\n * parser, and the client never branches on who is delivering the mail.\n *\n * What varies between providers is confined to the URL: host, port, and\n * credentials. That is what lets the same handler source run against Mailpit and\n * against SES without a conditional.\n */\n\nimport { MalformedEmailUrl, UnsupportedEmailScheme } from './errors';\nimport type { SMTPConfig } from './types';\n\n/**\n * The port to use when the URL names none.\n *\n * 587 is submission-with-STARTTLS, which is what SES, Resend, and Postmark all\n * document; 465 is implicit TLS, which is what `smtps://` means.\n */\nconst DEFAULT_PORT = { 'smtp:': 587, 'smtps:': 465 } as const;\n\n/**\n * Build an SMTP transport config from a `<NAME>_URL`.\n *\n * `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on\n * connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,\n * and the reason the scheme is worth having rather than inferring from the port.\n *\n * @example parseEmailUrl('smtp://mailpit:1025')\n * @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')\n * @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')\n */\nexport function parseEmailUrl(url: string): SMTPConfig {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new MalformedEmailUrl(url);\n\t}\n\n\tif (parsed.protocol !== 'smtp:' && parsed.protocol !== 'smtps:') {\n\t\tthrow new UnsupportedEmailScheme(url, parsed.protocol);\n\t}\n\n\tconst secure = parsed.protocol === 'smtps:';\n\tconst config: SMTPConfig = {\n\t\thost: parsed.hostname,\n\t\tport: parsed.port ? Number(parsed.port) : DEFAULT_PORT[parsed.protocol],\n\t\tsecure,\n\t};\n\n\t// Mailpit accepts mail unauthenticated, so credentials are optional rather\n\t// than required — omitting `auth` entirely is what nodemailer expects, where\n\t// empty strings would be sent as a real (failing) AUTH exchange.\n\tif (parsed.username) {\n\t\tconfig.auth = {\n\t\t\tuser: decodeURIComponent(parsed.username),\n\t\t\tpass: decodeURIComponent(parsed.password),\n\t\t};\n\t}\n\n\t// Local containers present a self-signed certificate. Rather than have every\n\t// project set this, read it off the URL — the adapter that knows it is\n\t// pointing at a container is the one that can say so.\n\tif (parsed.searchParams.get('insecure') === 'true') {\n\t\tconfig.tls = { rejectUnauthorized: false };\n\t}\n\n\treturn config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,MAAM,eAAe;CAAE,SAAS;CAAK,UAAU;AAAI;;;;;;;;;;;;AAanD,SAAgB,cAAc,KAAyB;CACtD,IAAI;CACJ,IAAI;EACH,SAAS,IAAI,IAAI,GAAG;CACrB,QAAQ;EACP,MAAM,IAAIA,eAAAA,kBAAkB,GAAG;CAChC;CAEA,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UACtD,MAAM,IAAIC,eAAAA,uBAAuB,KAAK,OAAO,QAAQ;CAGtD,MAAM,SAAS,OAAO,aAAa;CACnC,MAAM,SAAqB;EAC1B,MAAM,OAAO;EACb,MAAM,OAAO,OAAO,OAAO,OAAO,IAAI,IAAI,aAAa,OAAO;EAC9D;CACD;CAKA,IAAI,OAAO,UACV,OAAO,OAAO;EACb,MAAM,mBAAmB,OAAO,QAAQ;EACxC,MAAM,mBAAmB,OAAO,QAAQ;CACzC;CAMD,IAAI,OAAO,aAAa,IAAI,UAAU,MAAM,QAC3C,OAAO,MAAM,EAAE,oBAAoB,MAAM;CAG1C,OAAO;AACR"}
|
package/dist/url.d.cts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { SMTPConfig } from "./types.cjs";
|
|
2
|
-
//#region src/url.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Build an SMTP transport config from a `<NAME>_URL`.
|
|
5
|
-
*
|
|
6
|
-
* `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on
|
|
7
|
-
* connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,
|
|
8
|
-
* and the reason the scheme is worth having rather than inferring from the port.
|
|
9
|
-
*
|
|
10
|
-
* @example parseEmailUrl('smtp://mailpit:1025')
|
|
11
|
-
* @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')
|
|
12
|
-
* @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseEmailUrl(url: string): SMTPConfig;
|
|
15
|
-
//#endregion
|
|
16
|
-
//# sourceMappingURL=url.d.cts.map
|
package/dist/url.d.cts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.cts","names":[],"sources":["../src/url.ts"],"mappings":";;;;;;;;;;;;;wBAmCgB,cAAc,cAAc"}
|
package/dist/url.d.mts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { SMTPConfig } from "./types.mjs";
|
|
2
|
-
//#region src/url.d.ts
|
|
3
|
-
/**
|
|
4
|
-
* Build an SMTP transport config from a `<NAME>_URL`.
|
|
5
|
-
*
|
|
6
|
-
* `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on
|
|
7
|
-
* connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,
|
|
8
|
-
* and the reason the scheme is worth having rather than inferring from the port.
|
|
9
|
-
*
|
|
10
|
-
* @example parseEmailUrl('smtp://mailpit:1025')
|
|
11
|
-
* @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')
|
|
12
|
-
* @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseEmailUrl(url: string): SMTPConfig;
|
|
15
|
-
//#endregion
|
|
16
|
-
//# sourceMappingURL=url.d.mts.map
|
package/dist/url.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.mts","names":[],"sources":["../src/url.ts"],"mappings":";;;;;;;;;;;;;wBAmCgB,cAAc,cAAc"}
|
package/dist/url.mjs
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { MalformedEmailUrl, UnsupportedEmailScheme } from "./errors.mjs";
|
|
2
|
-
//#region src/url.ts
|
|
3
|
-
/**
|
|
4
|
-
* `smtp://` — the one URL shape an email construct ever provides.
|
|
5
|
-
*
|
|
6
|
-
* Every provider is reached the same way: Mailpit locally, SES through its SMTP
|
|
7
|
-
* interface, Resend and Postmark through theirs. So there is no scheme-keyed
|
|
8
|
-
* driver registry here as there is in `@geekmidas/storage` — one transport, one
|
|
9
|
-
* parser, and the client never branches on who is delivering the mail.
|
|
10
|
-
*
|
|
11
|
-
* What varies between providers is confined to the URL: host, port, and
|
|
12
|
-
* credentials. That is what lets the same handler source run against Mailpit and
|
|
13
|
-
* against SES without a conditional.
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* The port to use when the URL names none.
|
|
17
|
-
*
|
|
18
|
-
* 587 is submission-with-STARTTLS, which is what SES, Resend, and Postmark all
|
|
19
|
-
* document; 465 is implicit TLS, which is what `smtps://` means.
|
|
20
|
-
*/
|
|
21
|
-
const DEFAULT_PORT = {
|
|
22
|
-
"smtp:": 587,
|
|
23
|
-
"smtps:": 465
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Build an SMTP transport config from a `<NAME>_URL`.
|
|
27
|
-
*
|
|
28
|
-
* `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on
|
|
29
|
-
* connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,
|
|
30
|
-
* and the reason the scheme is worth having rather than inferring from the port.
|
|
31
|
-
*
|
|
32
|
-
* @example parseEmailUrl('smtp://mailpit:1025')
|
|
33
|
-
* @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')
|
|
34
|
-
* @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')
|
|
35
|
-
*/
|
|
36
|
-
function parseEmailUrl(url) {
|
|
37
|
-
let parsed;
|
|
38
|
-
try {
|
|
39
|
-
parsed = new URL(url);
|
|
40
|
-
} catch {
|
|
41
|
-
throw new MalformedEmailUrl(url);
|
|
42
|
-
}
|
|
43
|
-
if (parsed.protocol !== "smtp:" && parsed.protocol !== "smtps:") throw new UnsupportedEmailScheme(url, parsed.protocol);
|
|
44
|
-
const secure = parsed.protocol === "smtps:";
|
|
45
|
-
const config = {
|
|
46
|
-
host: parsed.hostname,
|
|
47
|
-
port: parsed.port ? Number(parsed.port) : DEFAULT_PORT[parsed.protocol],
|
|
48
|
-
secure
|
|
49
|
-
};
|
|
50
|
-
if (parsed.username) config.auth = {
|
|
51
|
-
user: decodeURIComponent(parsed.username),
|
|
52
|
-
pass: decodeURIComponent(parsed.password)
|
|
53
|
-
};
|
|
54
|
-
if (parsed.searchParams.get("insecure") === "true") config.tls = { rejectUnauthorized: false };
|
|
55
|
-
return config;
|
|
56
|
-
}
|
|
57
|
-
//#endregion
|
|
58
|
-
export { parseEmailUrl };
|
|
59
|
-
|
|
60
|
-
//# sourceMappingURL=url.mjs.map
|
package/dist/url.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"url.mjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * `smtp://` — the one URL shape an email construct ever provides.\n *\n * Every provider is reached the same way: Mailpit locally, SES through its SMTP\n * interface, Resend and Postmark through theirs. So there is no scheme-keyed\n * driver registry here as there is in `@geekmidas/storage` — one transport, one\n * parser, and the client never branches on who is delivering the mail.\n *\n * What varies between providers is confined to the URL: host, port, and\n * credentials. That is what lets the same handler source run against Mailpit and\n * against SES without a conditional.\n */\n\nimport { MalformedEmailUrl, UnsupportedEmailScheme } from './errors';\nimport type { SMTPConfig } from './types';\n\n/**\n * The port to use when the URL names none.\n *\n * 587 is submission-with-STARTTLS, which is what SES, Resend, and Postmark all\n * document; 465 is implicit TLS, which is what `smtps://` means.\n */\nconst DEFAULT_PORT = { 'smtp:': 587, 'smtps:': 465 } as const;\n\n/**\n * Build an SMTP transport config from a `<NAME>_URL`.\n *\n * `smtps://` sets `secure`, which is nodemailer's flag for implicit TLS on\n * connect rather than STARTTLS after `EHLO` — the distinction 465 and 587 carry,\n * and the reason the scheme is worth having rather than inferring from the port.\n *\n * @example parseEmailUrl('smtp://mailpit:1025')\n * @example parseEmailUrl('smtps://AKIA…:…@email-smtp.eu-west-1.amazonaws.com:465')\n * @example parseEmailUrl('smtp://resend:re_123@smtp.resend.com:587')\n */\nexport function parseEmailUrl(url: string): SMTPConfig {\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(url);\n\t} catch {\n\t\tthrow new MalformedEmailUrl(url);\n\t}\n\n\tif (parsed.protocol !== 'smtp:' && parsed.protocol !== 'smtps:') {\n\t\tthrow new UnsupportedEmailScheme(url, parsed.protocol);\n\t}\n\n\tconst secure = parsed.protocol === 'smtps:';\n\tconst config: SMTPConfig = {\n\t\thost: parsed.hostname,\n\t\tport: parsed.port ? Number(parsed.port) : DEFAULT_PORT[parsed.protocol],\n\t\tsecure,\n\t};\n\n\t// Mailpit accepts mail unauthenticated, so credentials are optional rather\n\t// than required — omitting `auth` entirely is what nodemailer expects, where\n\t// empty strings would be sent as a real (failing) AUTH exchange.\n\tif (parsed.username) {\n\t\tconfig.auth = {\n\t\t\tuser: decodeURIComponent(parsed.username),\n\t\t\tpass: decodeURIComponent(parsed.password),\n\t\t};\n\t}\n\n\t// Local containers present a self-signed certificate. Rather than have every\n\t// project set this, read it off the URL — the adapter that knows it is\n\t// pointing at a container is the one that can say so.\n\tif (parsed.searchParams.get('insecure') === 'true') {\n\t\tconfig.tls = { rejectUnauthorized: false };\n\t}\n\n\treturn config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,MAAM,eAAe;CAAE,SAAS;CAAK,UAAU;AAAI;;;;;;;;;;;;AAanD,SAAgB,cAAc,KAAyB;CACtD,IAAI;CACJ,IAAI;EACH,SAAS,IAAI,IAAI,GAAG;CACrB,QAAQ;EACP,MAAM,IAAI,kBAAkB,GAAG;CAChC;CAEA,IAAI,OAAO,aAAa,WAAW,OAAO,aAAa,UACtD,MAAM,IAAI,uBAAuB,KAAK,OAAO,QAAQ;CAGtD,MAAM,SAAS,OAAO,aAAa;CACnC,MAAM,SAAqB;EAC1B,MAAM,OAAO;EACb,MAAM,OAAO,OAAO,OAAO,OAAO,IAAI,IAAI,aAAa,OAAO;EAC9D;CACD;CAKA,IAAI,OAAO,UACV,OAAO,OAAO;EACb,MAAM,mBAAmB,OAAO,QAAQ;EACxC,MAAM,mBAAmB,OAAO,QAAQ;CACzC;CAMD,IAAI,OAAO,aAAa,IAAI,UAAU,MAAM,QAC3C,OAAO,MAAM,EAAE,oBAAoB,MAAM;CAG1C,OAAO;AACR"}
|