bunderstack 0.7.0 → 0.9.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/src/email.ts CHANGED
@@ -1,4 +1,5 @@
1
- // src/email.ts — email sending: resend / smtp / console / custom adapter.
1
+ // src/email.ts — email sending: console / resend / custom adapters.
2
+ // SMTP is provided by the static `bunderstack/email/smtp` factory subpath.
2
3
 
3
4
  export type EmailMessage = {
4
5
  to: string | string[]
@@ -20,7 +21,7 @@ export type EmailAdapter = {
20
21
 
21
22
  export type EmailConfigInput = {
22
23
  from: string
23
- provider?: 'resend' | 'smtp' | 'console' | EmailAdapter | EmailAdapter['send']
24
+ provider?: 'resend' | 'console' | EmailAdapter | EmailAdapter['send']
24
25
  }
25
26
 
26
27
  export type EmailFacade = {
@@ -31,11 +32,9 @@ export type CreateEmailOptions = {
31
32
  env: { RESEND_API_KEY?: string; SMTP_URL?: string; NODE_ENV?: string }
32
33
  /** Test seam for the resend adapter. */
33
34
  fetchFn?: typeof fetch
34
- /** Test seam for the nodemailer presence check. */
35
- canResolveModule?: (specifier: string) => boolean
36
35
  }
37
36
 
38
- /** String provider tag ('resend' | 'smtp' | 'console') or undefined. */
37
+ /** Root string provider tag ('resend' | 'console') or undefined. */
39
38
  export function emailProviderTag(
40
39
  config: EmailConfigInput | undefined,
41
40
  ): string | undefined {
@@ -98,54 +97,6 @@ function createResendAdapter(
98
97
  }
99
98
  }
100
99
 
101
- function createSmtpAdapter(
102
- smtpUrl: string,
103
- canResolve: (specifier: string) => boolean,
104
- ): EmailAdapter {
105
- if (!canResolve('nodemailer')) {
106
- throw new Error(
107
- "email provider 'smtp' requires nodemailer — install it with: bun add nodemailer",
108
- )
109
- }
110
- // Lazy import so boot stays sync; cached across sends. Variable specifier
111
- // keeps TS from resolving the optional peer's types at compile time.
112
- const specifier = 'nodemailer'
113
- let transportPromise: Promise<{
114
- sendMail(opts: Record<string, unknown>): Promise<{ messageId?: string }>
115
- }> | null = null
116
- const getTransport = () => {
117
- transportPromise ??= import(/* @vite-ignore */ specifier).then((mod) =>
118
- (mod.default ?? mod).createTransport(smtpUrl),
119
- )
120
- return transportPromise
121
- }
122
- return {
123
- async send(msg) {
124
- const transport = await getTransport()
125
- const info = await transport.sendMail({
126
- from: msg.from,
127
- to: toArray(msg.to)!.join(', '),
128
- subject: msg.subject,
129
- html: msg.html,
130
- text: msg.text,
131
- replyTo: msg.replyTo,
132
- cc: toArray(msg.cc)?.join(', '),
133
- bcc: toArray(msg.bcc)?.join(', '),
134
- })
135
- return { id: info.messageId }
136
- },
137
- }
138
- }
139
-
140
- function defaultCanResolve(specifier: string): boolean {
141
- try {
142
- Bun.resolveSync(specifier, import.meta.dir)
143
- return true
144
- } catch {
145
- return false
146
- }
147
- }
148
-
149
100
  function resolveAdapter(
150
101
  config: EmailConfigInput,
151
102
  opts: CreateEmailOptions,
@@ -157,18 +108,21 @@ function resolveAdapter(
157
108
  switch (provider) {
158
109
  case 'resend':
159
110
  return createResendAdapter(opts.env.RESEND_API_KEY ?? '', fetchFn)
160
- case 'smtp':
161
- return createSmtpAdapter(
162
- opts.env.SMTP_URL ?? '',
163
- opts.canResolveModule ?? defaultCanResolve,
164
- )
111
+
165
112
  case 'console':
166
113
  return createConsoleAdapter()
167
114
  case undefined:
168
115
  if (opts.env.NODE_ENV === 'production') {
169
116
  throw new Error(
170
117
  'email is configured without a provider — set email.provider ' +
171
- "('resend' | 'smtp' | a custom adapter) for production",
118
+ "('resend' | a custom adapter) for production",
119
+ )
120
+ }
121
+ return createConsoleAdapter()
122
+ default:
123
+ if (provider === 'smtp') {
124
+ throw new Error(
125
+ "email provider 'smtp' was removed. Import `smtp` from 'bunderstack/email/smtp' instead.",
172
126
  )
173
127
  }
174
128
  return createConsoleAdapter()