@bloomneo/appkit 1.2.9
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/LICENSE +21 -0
- package/README.md +902 -0
- package/bin/appkit.js +71 -0
- package/bin/commands/generate.js +1050 -0
- package/bin/templates/backend/README.md.template +39 -0
- package/bin/templates/backend/api.http.template +0 -0
- package/bin/templates/backend/docs/APPKIT_CLI.md +507 -0
- package/bin/templates/backend/docs/APPKIT_COMMENTS_GUIDELINES.md +61 -0
- package/bin/templates/backend/docs/APPKIT_LLM_GUIDE.md +2539 -0
- package/bin/templates/backend/package.json.template +34 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.http.template +29 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.route.ts.template +36 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.service.ts.template +88 -0
- package/bin/templates/backend/src/api/features/welcome/welcome.types.ts.template +18 -0
- package/bin/templates/backend/src/api/lib/api-router.ts.template +84 -0
- package/bin/templates/backend/src/api/server.ts.template +188 -0
- package/bin/templates/backend/tsconfig.api.json.template +24 -0
- package/bin/templates/backend/tsconfig.json.template +40 -0
- package/bin/templates/feature/feature.http.template +63 -0
- package/bin/templates/feature/feature.route.ts.template +36 -0
- package/bin/templates/feature/feature.service.ts.template +81 -0
- package/bin/templates/feature/feature.types.ts.template +23 -0
- package/bin/templates/feature-db/feature.http.template +63 -0
- package/bin/templates/feature-db/feature.model.ts.template +74 -0
- package/bin/templates/feature-db/feature.route.ts.template +58 -0
- package/bin/templates/feature-db/feature.service.ts.template +231 -0
- package/bin/templates/feature-db/feature.types.ts.template +25 -0
- package/bin/templates/feature-db/schema-addition.prisma.template +9 -0
- package/bin/templates/feature-db/seeding/README.md.template +57 -0
- package/bin/templates/feature-db/seeding/feature.seed.js.template +67 -0
- package/bin/templates/feature-user/schema-addition.prisma.template +19 -0
- package/bin/templates/feature-user/user.http.template +157 -0
- package/bin/templates/feature-user/user.model.ts.template +244 -0
- package/bin/templates/feature-user/user.route.ts.template +379 -0
- package/bin/templates/feature-user/user.seed.js.template +182 -0
- package/bin/templates/feature-user/user.service.ts.template +426 -0
- package/bin/templates/feature-user/user.types.ts.template +127 -0
- package/dist/auth/auth.d.ts +182 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +477 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/defaults.d.ts +104 -0
- package/dist/auth/defaults.d.ts.map +1 -0
- package/dist/auth/defaults.js +374 -0
- package/dist/auth/defaults.js.map +1 -0
- package/dist/auth/index.d.ts +70 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +94 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/cache/cache.d.ts +118 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +249 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/defaults.d.ts +63 -0
- package/dist/cache/defaults.d.ts.map +1 -0
- package/dist/cache/defaults.js +193 -0
- package/dist/cache/defaults.js.map +1 -0
- package/dist/cache/index.d.ts +101 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +203 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/strategies/memory.d.ts +138 -0
- package/dist/cache/strategies/memory.d.ts.map +1 -0
- package/dist/cache/strategies/memory.js +348 -0
- package/dist/cache/strategies/memory.js.map +1 -0
- package/dist/cache/strategies/redis.d.ts +105 -0
- package/dist/cache/strategies/redis.d.ts.map +1 -0
- package/dist/cache/strategies/redis.js +318 -0
- package/dist/cache/strategies/redis.js.map +1 -0
- package/dist/config/config.d.ts +62 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +107 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/defaults.d.ts +44 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +217 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +105 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +163 -0
- package/dist/config/index.js.map +1 -0
- package/dist/database/adapters/mongoose.d.ts +106 -0
- package/dist/database/adapters/mongoose.d.ts.map +1 -0
- package/dist/database/adapters/mongoose.js +480 -0
- package/dist/database/adapters/mongoose.js.map +1 -0
- package/dist/database/adapters/prisma.d.ts +106 -0
- package/dist/database/adapters/prisma.d.ts.map +1 -0
- package/dist/database/adapters/prisma.js +494 -0
- package/dist/database/adapters/prisma.js.map +1 -0
- package/dist/database/defaults.d.ts +87 -0
- package/dist/database/defaults.d.ts.map +1 -0
- package/dist/database/defaults.js +271 -0
- package/dist/database/defaults.js.map +1 -0
- package/dist/database/index.d.ts +137 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +490 -0
- package/dist/database/index.js.map +1 -0
- package/dist/email/defaults.d.ts +100 -0
- package/dist/email/defaults.d.ts.map +1 -0
- package/dist/email/defaults.js +400 -0
- package/dist/email/defaults.js.map +1 -0
- package/dist/email/email.d.ts +139 -0
- package/dist/email/email.d.ts.map +1 -0
- package/dist/email/email.js +316 -0
- package/dist/email/email.js.map +1 -0
- package/dist/email/index.d.ts +176 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +251 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/strategies/console.d.ts +90 -0
- package/dist/email/strategies/console.d.ts.map +1 -0
- package/dist/email/strategies/console.js +268 -0
- package/dist/email/strategies/console.js.map +1 -0
- package/dist/email/strategies/resend.d.ts +84 -0
- package/dist/email/strategies/resend.d.ts.map +1 -0
- package/dist/email/strategies/resend.js +266 -0
- package/dist/email/strategies/resend.js.map +1 -0
- package/dist/email/strategies/smtp.d.ts +77 -0
- package/dist/email/strategies/smtp.d.ts.map +1 -0
- package/dist/email/strategies/smtp.js +286 -0
- package/dist/email/strategies/smtp.js.map +1 -0
- package/dist/error/defaults.d.ts +40 -0
- package/dist/error/defaults.d.ts.map +1 -0
- package/dist/error/defaults.js +75 -0
- package/dist/error/defaults.js.map +1 -0
- package/dist/error/error.d.ts +140 -0
- package/dist/error/error.d.ts.map +1 -0
- package/dist/error/error.js +200 -0
- package/dist/error/error.js.map +1 -0
- package/dist/error/index.d.ts +145 -0
- package/dist/error/index.d.ts.map +1 -0
- package/dist/error/index.js +145 -0
- package/dist/error/index.js.map +1 -0
- package/dist/event/defaults.d.ts +111 -0
- package/dist/event/defaults.d.ts.map +1 -0
- package/dist/event/defaults.js +378 -0
- package/dist/event/defaults.js.map +1 -0
- package/dist/event/event.d.ts +171 -0
- package/dist/event/event.d.ts.map +1 -0
- package/dist/event/event.js +391 -0
- package/dist/event/event.js.map +1 -0
- package/dist/event/index.d.ts +173 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +302 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/strategies/memory.d.ts +122 -0
- package/dist/event/strategies/memory.d.ts.map +1 -0
- package/dist/event/strategies/memory.js +331 -0
- package/dist/event/strategies/memory.js.map +1 -0
- package/dist/event/strategies/redis.d.ts +115 -0
- package/dist/event/strategies/redis.d.ts.map +1 -0
- package/dist/event/strategies/redis.js +434 -0
- package/dist/event/strategies/redis.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/defaults.d.ts +67 -0
- package/dist/logger/defaults.d.ts.map +1 -0
- package/dist/logger/defaults.js +213 -0
- package/dist/logger/defaults.js.map +1 -0
- package/dist/logger/index.d.ts +84 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +101 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/logger.d.ts +165 -0
- package/dist/logger/logger.d.ts.map +1 -0
- package/dist/logger/logger.js +843 -0
- package/dist/logger/logger.js.map +1 -0
- package/dist/logger/transports/console.d.ts +102 -0
- package/dist/logger/transports/console.d.ts.map +1 -0
- package/dist/logger/transports/console.js +276 -0
- package/dist/logger/transports/console.js.map +1 -0
- package/dist/logger/transports/database.d.ts +153 -0
- package/dist/logger/transports/database.d.ts.map +1 -0
- package/dist/logger/transports/database.js +539 -0
- package/dist/logger/transports/database.js.map +1 -0
- package/dist/logger/transports/file.d.ts +146 -0
- package/dist/logger/transports/file.d.ts.map +1 -0
- package/dist/logger/transports/file.js +464 -0
- package/dist/logger/transports/file.js.map +1 -0
- package/dist/logger/transports/http.d.ts +128 -0
- package/dist/logger/transports/http.d.ts.map +1 -0
- package/dist/logger/transports/http.js +401 -0
- package/dist/logger/transports/http.js.map +1 -0
- package/dist/logger/transports/webhook.d.ts +152 -0
- package/dist/logger/transports/webhook.d.ts.map +1 -0
- package/dist/logger/transports/webhook.js +485 -0
- package/dist/logger/transports/webhook.js.map +1 -0
- package/dist/queue/defaults.d.ts +66 -0
- package/dist/queue/defaults.d.ts.map +1 -0
- package/dist/queue/defaults.js +205 -0
- package/dist/queue/defaults.js.map +1 -0
- package/dist/queue/index.d.ts +124 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +116 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/queue.d.ts +156 -0
- package/dist/queue/queue.d.ts.map +1 -0
- package/dist/queue/queue.js +387 -0
- package/dist/queue/queue.js.map +1 -0
- package/dist/queue/transports/database.d.ts +165 -0
- package/dist/queue/transports/database.d.ts.map +1 -0
- package/dist/queue/transports/database.js +595 -0
- package/dist/queue/transports/database.js.map +1 -0
- package/dist/queue/transports/memory.d.ts +143 -0
- package/dist/queue/transports/memory.d.ts.map +1 -0
- package/dist/queue/transports/memory.js +415 -0
- package/dist/queue/transports/memory.js.map +1 -0
- package/dist/queue/transports/redis.d.ts +203 -0
- package/dist/queue/transports/redis.d.ts.map +1 -0
- package/dist/queue/transports/redis.js +744 -0
- package/dist/queue/transports/redis.js.map +1 -0
- package/dist/security/defaults.d.ts +64 -0
- package/dist/security/defaults.d.ts.map +1 -0
- package/dist/security/defaults.js +159 -0
- package/dist/security/defaults.js.map +1 -0
- package/dist/security/index.d.ts +110 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +160 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security.d.ts +138 -0
- package/dist/security/security.d.ts.map +1 -0
- package/dist/security/security.js +419 -0
- package/dist/security/security.js.map +1 -0
- package/dist/storage/defaults.d.ts +79 -0
- package/dist/storage/defaults.d.ts.map +1 -0
- package/dist/storage/defaults.js +358 -0
- package/dist/storage/defaults.js.map +1 -0
- package/dist/storage/index.d.ts +153 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +242 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/storage.d.ts +151 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +439 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/storage/strategies/local.d.ts +117 -0
- package/dist/storage/strategies/local.d.ts.map +1 -0
- package/dist/storage/strategies/local.js +368 -0
- package/dist/storage/strategies/local.js.map +1 -0
- package/dist/storage/strategies/r2.d.ts +130 -0
- package/dist/storage/strategies/r2.d.ts.map +1 -0
- package/dist/storage/strategies/r2.js +470 -0
- package/dist/storage/strategies/r2.js.map +1 -0
- package/dist/storage/strategies/s3.d.ts +121 -0
- package/dist/storage/strategies/s3.d.ts.map +1 -0
- package/dist/storage/strategies/s3.js +461 -0
- package/dist/storage/strategies/s3.js.map +1 -0
- package/dist/util/defaults.d.ts +77 -0
- package/dist/util/defaults.d.ts.map +1 -0
- package/dist/util/defaults.js +193 -0
- package/dist/util/defaults.js.map +1 -0
- package/dist/util/index.d.ts +97 -0
- package/dist/util/index.d.ts.map +1 -0
- package/dist/util/index.js +165 -0
- package/dist/util/index.js.map +1 -0
- package/dist/util/util.d.ts +145 -0
- package/dist/util/util.d.ts.map +1 -0
- package/dist/util/util.js +481 -0
- package/dist/util/util.js.map +1 -0
- package/package.json +234 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core email class with automatic strategy selection and ultra-simple API
|
|
3
|
+
* @module @bloomneo/appkit/email
|
|
4
|
+
* @file src/email/email.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Building apps that need email sending with automatic provider selection
|
|
7
|
+
* @llm-rule AVOID: Using directly - always get instance via emailClass.get()
|
|
8
|
+
* @llm-rule NOTE: Auto-detects Resend → SMTP → Console based on environment variables
|
|
9
|
+
*/
|
|
10
|
+
import { ResendStrategy } from './strategies/resend.js';
|
|
11
|
+
import { SmtpStrategy } from './strategies/smtp.js';
|
|
12
|
+
import { ConsoleStrategy } from './strategies/console.js';
|
|
13
|
+
/**
|
|
14
|
+
* Email class with automatic strategy selection and ultra-simple API
|
|
15
|
+
*/
|
|
16
|
+
export class EmailClass {
|
|
17
|
+
config;
|
|
18
|
+
strategy;
|
|
19
|
+
connected = false;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.strategy = this.createStrategy();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Creates appropriate strategy based on configuration
|
|
26
|
+
* @llm-rule WHEN: Email initialization - selects Resend, SMTP, or Console based on environment
|
|
27
|
+
* @llm-rule AVOID: Manual strategy creation - configuration handles strategy selection
|
|
28
|
+
*/
|
|
29
|
+
createStrategy() {
|
|
30
|
+
switch (this.config.strategy) {
|
|
31
|
+
case 'resend':
|
|
32
|
+
return new ResendStrategy(this.config);
|
|
33
|
+
case 'smtp':
|
|
34
|
+
return new SmtpStrategy(this.config);
|
|
35
|
+
case 'console':
|
|
36
|
+
return new ConsoleStrategy(this.config);
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Unknown email strategy: ${this.config.strategy}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sends email with automatic strategy handling
|
|
43
|
+
* @llm-rule WHEN: Sending any email - this is the main email sending method
|
|
44
|
+
* @llm-rule AVOID: Manual strategy calls - this handles all email complexity
|
|
45
|
+
* @llm-rule NOTE: Auto-fills FROM address from config if not provided
|
|
46
|
+
*/
|
|
47
|
+
async send(data) {
|
|
48
|
+
try {
|
|
49
|
+
// Validate email data
|
|
50
|
+
this.validateEmailData(data);
|
|
51
|
+
// Auto-fill FROM address if not provided
|
|
52
|
+
const emailData = this.prepareEmailData(data);
|
|
53
|
+
// Send via strategy
|
|
54
|
+
const result = await this.strategy.send(emailData);
|
|
55
|
+
// Log success in development
|
|
56
|
+
if (this.config.environment.isDevelopment && result.success) {
|
|
57
|
+
console.log(`✅ [AppKit] Email sent successfully${result.messageId ? ` (ID: ${result.messageId})` : ''}`);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const errorMessage = error.message;
|
|
63
|
+
console.error(`❌ [AppKit] Email send failed:`, errorMessage);
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: errorMessage,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Sends multiple emails efficiently (batch operation)
|
|
72
|
+
* @llm-rule WHEN: Sending multiple emails like newsletters or notifications
|
|
73
|
+
* @llm-rule AVOID: Multiple individual send() calls - this handles batching efficiently
|
|
74
|
+
* @llm-rule NOTE: Processes in batches to avoid overwhelming email providers
|
|
75
|
+
*/
|
|
76
|
+
async sendBatch(emails, batchSize = 10) {
|
|
77
|
+
const results = [];
|
|
78
|
+
// Process in batches
|
|
79
|
+
for (let i = 0; i < emails.length; i += batchSize) {
|
|
80
|
+
const batch = emails.slice(i, i + batchSize);
|
|
81
|
+
// Send batch concurrently
|
|
82
|
+
const batchPromises = batch.map(email => this.send(email));
|
|
83
|
+
const batchResults = await Promise.allSettled(batchPromises);
|
|
84
|
+
// Process results
|
|
85
|
+
for (const result of batchResults) {
|
|
86
|
+
if (result.status === 'fulfilled') {
|
|
87
|
+
results.push(result.value);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
results.push({
|
|
91
|
+
success: false,
|
|
92
|
+
error: result.reason?.message || 'Unknown error',
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Small delay between batches to be respectful to email providers
|
|
97
|
+
if (i + batchSize < emails.length) {
|
|
98
|
+
await this.sleep(100);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return results;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Sends simple text email (convenience method)
|
|
105
|
+
* @llm-rule WHEN: Sending simple text-only emails quickly
|
|
106
|
+
* @llm-rule AVOID: Complex EmailData object for simple emails - this is more convenient
|
|
107
|
+
*/
|
|
108
|
+
async sendText(to, subject, text) {
|
|
109
|
+
return await this.send({
|
|
110
|
+
to,
|
|
111
|
+
subject,
|
|
112
|
+
text,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Sends HTML email (convenience method)
|
|
117
|
+
* @llm-rule WHEN: Sending HTML emails with formatting
|
|
118
|
+
* @llm-rule AVOID: Manual HTML/text preparation - this handles both formats
|
|
119
|
+
*/
|
|
120
|
+
async sendHtml(to, subject, html, text) {
|
|
121
|
+
return await this.send({
|
|
122
|
+
to,
|
|
123
|
+
subject,
|
|
124
|
+
html,
|
|
125
|
+
text: text || this.htmlToText(html),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Sends email with template (future extension point)
|
|
130
|
+
* @llm-rule WHEN: Sending templated emails with data substitution
|
|
131
|
+
* @llm-rule AVOID: Manual template processing - this will handle template rendering
|
|
132
|
+
* @llm-rule NOTE: Basic implementation - can be extended with template engines
|
|
133
|
+
*/
|
|
134
|
+
async sendTemplate(templateName, data) {
|
|
135
|
+
// Simple template processing (can be extended)
|
|
136
|
+
const template = this.loadTemplate(templateName);
|
|
137
|
+
const processedHtml = this.processTemplate(template.html, data);
|
|
138
|
+
const processedText = this.processTemplate(template.text, data);
|
|
139
|
+
return await this.send({
|
|
140
|
+
to: data.to,
|
|
141
|
+
subject: this.processTemplate(template.subject, data),
|
|
142
|
+
html: processedHtml,
|
|
143
|
+
text: processedText,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Disconnects email strategy gracefully
|
|
148
|
+
* @llm-rule WHEN: App shutdown or email cleanup
|
|
149
|
+
* @llm-rule AVOID: Abrupt disconnection - graceful shutdown prevents connection issues
|
|
150
|
+
*/
|
|
151
|
+
async disconnect() {
|
|
152
|
+
if (!this.connected)
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
await this.strategy.disconnect();
|
|
156
|
+
this.connected = false;
|
|
157
|
+
if (this.config.environment.isDevelopment) {
|
|
158
|
+
console.log(`👋 [AppKit] Email disconnected`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.error(`⚠️ [AppKit] Email disconnect error:`, error.message);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Gets current email strategy name for debugging
|
|
167
|
+
* @llm-rule WHEN: Debugging or health checks to see which strategy is active
|
|
168
|
+
* @llm-rule AVOID: Using for application logic - email should be transparent
|
|
169
|
+
*/
|
|
170
|
+
getStrategy() {
|
|
171
|
+
return this.config.strategy;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Gets email configuration summary for debugging
|
|
175
|
+
* @llm-rule WHEN: Health checks or debugging email configuration
|
|
176
|
+
* @llm-rule AVOID: Exposing sensitive details - this only shows safe info
|
|
177
|
+
*/
|
|
178
|
+
getConfig() {
|
|
179
|
+
return {
|
|
180
|
+
strategy: this.config.strategy,
|
|
181
|
+
fromName: this.config.from.name,
|
|
182
|
+
fromEmail: this.config.from.email,
|
|
183
|
+
connected: this.connected,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// Private helper methods
|
|
187
|
+
/**
|
|
188
|
+
* Validates email data before sending
|
|
189
|
+
*/
|
|
190
|
+
validateEmailData(data) {
|
|
191
|
+
if (!data.to) {
|
|
192
|
+
throw new Error('Email "to" field is required');
|
|
193
|
+
}
|
|
194
|
+
if (!data.subject) {
|
|
195
|
+
throw new Error('Email "subject" field is required');
|
|
196
|
+
}
|
|
197
|
+
if (!data.text && !data.html) {
|
|
198
|
+
throw new Error('Email must have either "text" or "html" content');
|
|
199
|
+
}
|
|
200
|
+
// Validate email addresses
|
|
201
|
+
const recipients = Array.isArray(data.to) ? data.to : [data.to];
|
|
202
|
+
for (const recipient of recipients) {
|
|
203
|
+
const email = typeof recipient === 'string' ? recipient : recipient.email;
|
|
204
|
+
if (!this.isValidEmail(email)) {
|
|
205
|
+
throw new Error(`Invalid email address: ${email}`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Validate FROM address if provided
|
|
209
|
+
if (data.from) {
|
|
210
|
+
const fromEmail = typeof data.from === 'string' ? data.from : data.from.email;
|
|
211
|
+
if (!this.isValidEmail(fromEmail)) {
|
|
212
|
+
throw new Error(`Invalid FROM email address: ${fromEmail}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Prepares email data with defaults
|
|
218
|
+
*/
|
|
219
|
+
prepareEmailData(data) {
|
|
220
|
+
const prepared = { ...data };
|
|
221
|
+
// Auto-fill FROM address if not provided
|
|
222
|
+
if (!prepared.from) {
|
|
223
|
+
prepared.from = {
|
|
224
|
+
name: this.config.from.name,
|
|
225
|
+
email: this.config.from.email,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return prepared;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Validates email address format
|
|
232
|
+
*/
|
|
233
|
+
isValidEmail(email) {
|
|
234
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
235
|
+
return emailRegex.test(email);
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Converts HTML to plain text (basic implementation)
|
|
239
|
+
*/
|
|
240
|
+
htmlToText(html) {
|
|
241
|
+
return html
|
|
242
|
+
.replace(/<br\s*\/?>/gi, '\n')
|
|
243
|
+
.replace(/<\/p>/gi, '\n\n')
|
|
244
|
+
.replace(/<[^>]+>/g, '')
|
|
245
|
+
.replace(/\s+/g, ' ')
|
|
246
|
+
.trim();
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Loads email template (basic implementation)
|
|
250
|
+
*/
|
|
251
|
+
loadTemplate(templateName) {
|
|
252
|
+
// Basic built-in templates
|
|
253
|
+
const templates = {
|
|
254
|
+
welcome: {
|
|
255
|
+
subject: 'Welcome to {{appName}}!',
|
|
256
|
+
html: `
|
|
257
|
+
<h1>Welcome {{name}}!</h1>
|
|
258
|
+
<p>Thanks for joining {{appName}}. We're excited to have you!</p>
|
|
259
|
+
<p>Best regards,<br>The {{appName}} Team</p>
|
|
260
|
+
`,
|
|
261
|
+
text: `
|
|
262
|
+
Welcome {{name}}!
|
|
263
|
+
|
|
264
|
+
Thanks for joining {{appName}}. We're excited to have you!
|
|
265
|
+
|
|
266
|
+
Best regards,
|
|
267
|
+
The {{appName}} Team
|
|
268
|
+
`,
|
|
269
|
+
},
|
|
270
|
+
reset: {
|
|
271
|
+
subject: 'Reset your {{appName}} password',
|
|
272
|
+
html: `
|
|
273
|
+
<h1>Reset your password</h1>
|
|
274
|
+
<p>Hi {{name}},</p>
|
|
275
|
+
<p>Click the link below to reset your password:</p>
|
|
276
|
+
<a href="{{resetUrl}}">Reset Password</a>
|
|
277
|
+
<p>If you didn't request this, please ignore this email.</p>
|
|
278
|
+
`,
|
|
279
|
+
text: `
|
|
280
|
+
Reset your password
|
|
281
|
+
|
|
282
|
+
Hi {{name}},
|
|
283
|
+
|
|
284
|
+
Click the link below to reset your password:
|
|
285
|
+
{{resetUrl}}
|
|
286
|
+
|
|
287
|
+
If you didn't request this, please ignore this email.
|
|
288
|
+
`,
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
const template = templates[templateName];
|
|
292
|
+
if (!template) {
|
|
293
|
+
throw new Error(`Template not found: ${templateName}`);
|
|
294
|
+
}
|
|
295
|
+
return template;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Processes template with data substitution
|
|
299
|
+
*/
|
|
300
|
+
processTemplate(template, data) {
|
|
301
|
+
let processed = template;
|
|
302
|
+
// Simple {{key}} substitution
|
|
303
|
+
for (const [key, value] of Object.entries(data)) {
|
|
304
|
+
const regex = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
|
|
305
|
+
processed = processed.replace(regex, String(value));
|
|
306
|
+
}
|
|
307
|
+
return processed.trim();
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Sleep for specified milliseconds
|
|
311
|
+
*/
|
|
312
|
+
sleep(ms) {
|
|
313
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/email/email.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ultra-simple email sending that just works with automatic provider detection
|
|
3
|
+
* @module @bloomneo/appkit/email
|
|
4
|
+
* @file src/email/index.ts
|
|
5
|
+
*
|
|
6
|
+
* @llm-rule WHEN: Building apps that need email sending with zero configuration
|
|
7
|
+
* @llm-rule AVOID: Complex email setups - this auto-detects Resend/SMTP/Console from environment
|
|
8
|
+
* @llm-rule NOTE: Uses emailClass.get() pattern like auth - get() → email.send() → done
|
|
9
|
+
* @llm-rule NOTE: Common pattern - emailClass.get() → email.send({ to, subject, text }) → sent
|
|
10
|
+
*/
|
|
11
|
+
import { type EmailConfig } from './defaults.js';
|
|
12
|
+
export interface Email {
|
|
13
|
+
send(data: EmailData): Promise<EmailResult>;
|
|
14
|
+
sendBatch(emails: EmailData[], batchSize?: number): Promise<EmailResult[]>;
|
|
15
|
+
sendText(to: string, subject: string, text: string): Promise<EmailResult>;
|
|
16
|
+
sendHtml(to: string, subject: string, html: string, text?: string): Promise<EmailResult>;
|
|
17
|
+
sendTemplate(templateName: string, data: any): Promise<EmailResult>;
|
|
18
|
+
disconnect(): Promise<void>;
|
|
19
|
+
getStrategy(): string;
|
|
20
|
+
getConfig(): any;
|
|
21
|
+
}
|
|
22
|
+
export interface EmailData {
|
|
23
|
+
to: string | EmailAddress | (string | EmailAddress)[];
|
|
24
|
+
from?: string | EmailAddress;
|
|
25
|
+
subject: string;
|
|
26
|
+
text?: string;
|
|
27
|
+
html?: string;
|
|
28
|
+
attachments?: EmailAttachment[];
|
|
29
|
+
replyTo?: string | EmailAddress;
|
|
30
|
+
cc?: string | EmailAddress | (string | EmailAddress)[];
|
|
31
|
+
bcc?: string | EmailAddress | (string | EmailAddress)[];
|
|
32
|
+
}
|
|
33
|
+
export interface EmailAddress {
|
|
34
|
+
name?: string;
|
|
35
|
+
email: string;
|
|
36
|
+
}
|
|
37
|
+
export interface EmailAttachment {
|
|
38
|
+
filename: string;
|
|
39
|
+
content: Buffer | string;
|
|
40
|
+
contentType?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface EmailResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
messageId?: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get email instance - the only function you need to learn
|
|
49
|
+
* Strategy auto-detected from environment (RESEND_API_KEY → Resend, SMTP_HOST → SMTP, default → Console)
|
|
50
|
+
* @llm-rule WHEN: Need email sending in any part of your app - this is your main entry point
|
|
51
|
+
* @llm-rule AVOID: Creating EmailClass directly - always use this function
|
|
52
|
+
* @llm-rule NOTE: Typical flow - get() → email.send() → email delivered/logged
|
|
53
|
+
*/
|
|
54
|
+
declare function get(): Email;
|
|
55
|
+
/**
|
|
56
|
+
* Clear email instance and disconnect - essential for testing
|
|
57
|
+
* @llm-rule WHEN: Testing email logic with different configurations or app shutdown
|
|
58
|
+
* @llm-rule AVOID: Using in production except for graceful shutdown
|
|
59
|
+
*/
|
|
60
|
+
declare function clear(): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Reset email configuration (useful for testing)
|
|
63
|
+
* @llm-rule WHEN: Testing email logic with different environment configurations
|
|
64
|
+
* @llm-rule AVOID: Using in production - only for tests and development
|
|
65
|
+
*/
|
|
66
|
+
declare function reset(newConfig?: Partial<EmailConfig>): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Get active email strategy for debugging
|
|
69
|
+
* @llm-rule WHEN: Debugging or health checks to see which strategy is active (Resend/SMTP/Console)
|
|
70
|
+
* @llm-rule AVOID: Using for application logic - email should be transparent
|
|
71
|
+
*/
|
|
72
|
+
declare function getStrategy(): string;
|
|
73
|
+
/**
|
|
74
|
+
* Get email configuration summary for debugging
|
|
75
|
+
* @llm-rule WHEN: Health checks or debugging email configuration
|
|
76
|
+
* @llm-rule AVOID: Exposing sensitive API keys or passwords - this only shows safe info
|
|
77
|
+
*/
|
|
78
|
+
declare function getConfig(): {
|
|
79
|
+
strategy: string;
|
|
80
|
+
fromName: string;
|
|
81
|
+
fromEmail: string;
|
|
82
|
+
environment: string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Check if Resend is available and configured
|
|
86
|
+
* @llm-rule WHEN: Conditional logic based on email capabilities
|
|
87
|
+
* @llm-rule AVOID: Complex email detection - just use email normally, it handles strategy
|
|
88
|
+
*/
|
|
89
|
+
declare function hasResend(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Check if SMTP is available and configured
|
|
92
|
+
* @llm-rule WHEN: Conditional logic based on email capabilities
|
|
93
|
+
* @llm-rule AVOID: Complex email detection - just use email normally, it handles strategy
|
|
94
|
+
*/
|
|
95
|
+
declare function hasSmtp(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Check if any email provider is configured (not just console)
|
|
98
|
+
* @llm-rule WHEN: Determining if real emails can be sent
|
|
99
|
+
* @llm-rule AVOID: Using for validation - email.send() will return success/error appropriately
|
|
100
|
+
*/
|
|
101
|
+
declare function hasProvider(): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Send simple email (convenience function)
|
|
104
|
+
* @llm-rule WHEN: Quick email sending without getting instance first
|
|
105
|
+
* @llm-rule AVOID: For complex emails - use get() and full EmailData object instead
|
|
106
|
+
*/
|
|
107
|
+
declare function send(data: EmailData): Promise<EmailResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Send simple text email (ultra-convenience function)
|
|
110
|
+
* @llm-rule WHEN: Sending basic notifications or alerts quickly
|
|
111
|
+
* @llm-rule AVOID: For formatted emails - use send() with HTML content instead
|
|
112
|
+
*/
|
|
113
|
+
declare function sendText(to: string, subject: string, text: string): Promise<EmailResult>;
|
|
114
|
+
/**
|
|
115
|
+
* Validate email configuration at startup with detailed feedback
|
|
116
|
+
* @llm-rule WHEN: App startup to ensure email is properly configured
|
|
117
|
+
* @llm-rule AVOID: Skipping validation - missing email config causes runtime issues
|
|
118
|
+
* @llm-rule NOTE: Returns validation results instead of throwing - allows graceful handling
|
|
119
|
+
*/
|
|
120
|
+
declare function validateConfig(): {
|
|
121
|
+
valid: boolean;
|
|
122
|
+
strategy: string;
|
|
123
|
+
warnings: string[];
|
|
124
|
+
errors: string[];
|
|
125
|
+
ready: boolean;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Validate production requirements and throw if critical issues found
|
|
129
|
+
* @llm-rule WHEN: Production deployment validation - ensures email works in production
|
|
130
|
+
* @llm-rule AVOID: Skipping in production - email failures are often silent
|
|
131
|
+
* @llm-rule NOTE: Throws on critical issues, warns on non-critical ones
|
|
132
|
+
*/
|
|
133
|
+
declare function validateProduction(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Get comprehensive health check status for monitoring
|
|
136
|
+
* @llm-rule WHEN: Health check endpoints or monitoring systems
|
|
137
|
+
* @llm-rule AVOID: Using in critical application path - this is for monitoring only
|
|
138
|
+
* @llm-rule NOTE: Returns detailed status without exposing sensitive configuration
|
|
139
|
+
*/
|
|
140
|
+
declare function getHealthStatus(): {
|
|
141
|
+
status: 'healthy' | 'warning' | 'error';
|
|
142
|
+
strategy: string;
|
|
143
|
+
configured: boolean;
|
|
144
|
+
issues: string[];
|
|
145
|
+
ready: boolean;
|
|
146
|
+
timestamp: string;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Graceful shutdown for email instance
|
|
150
|
+
* @llm-rule WHEN: App shutdown or process termination
|
|
151
|
+
* @llm-rule AVOID: Abrupt process exit - graceful shutdown prevents connection issues
|
|
152
|
+
*/
|
|
153
|
+
declare function shutdown(): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Single email export with minimal API (like auth module)
|
|
156
|
+
*/
|
|
157
|
+
export declare const emailClass: {
|
|
158
|
+
readonly get: typeof get;
|
|
159
|
+
readonly clear: typeof clear;
|
|
160
|
+
readonly reset: typeof reset;
|
|
161
|
+
readonly getStrategy: typeof getStrategy;
|
|
162
|
+
readonly getConfig: typeof getConfig;
|
|
163
|
+
readonly hasResend: typeof hasResend;
|
|
164
|
+
readonly hasSmtp: typeof hasSmtp;
|
|
165
|
+
readonly hasProvider: typeof hasProvider;
|
|
166
|
+
readonly send: typeof send;
|
|
167
|
+
readonly sendText: typeof sendText;
|
|
168
|
+
readonly validateConfig: typeof validateConfig;
|
|
169
|
+
readonly validateProduction: typeof validateProduction;
|
|
170
|
+
readonly getHealthStatus: typeof getHealthStatus;
|
|
171
|
+
readonly shutdown: typeof shutdown;
|
|
172
|
+
};
|
|
173
|
+
export type { EmailConfig } from './defaults.js';
|
|
174
|
+
export { EmailClass } from './email.js';
|
|
175
|
+
export default emailClass;
|
|
176
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"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"}
|