alepha 0.9.4 → 0.10.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/email.cjs ADDED
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+ var m = require('@alepha/email');
3
+ Object.keys(m).forEach(function (k) {
4
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
5
+ enumerable: true,
6
+ get: function () { return m[k]; }
7
+ });
8
+ });
package/email.d.ts ADDED
@@ -0,0 +1,328 @@
1
+ import * as _alepha_core1 from "alepha";
2
+ import { Descriptor, KIND, Service, Static, TSchema } from "alepha";
3
+ import * as _alepha_logger1 from "alepha/logger";
4
+ import { Transporter } from "nodemailer";
5
+
6
+ //#region src/providers/EmailProvider.d.ts
7
+ /**
8
+ * Email provider interface.
9
+ *
10
+ * All methods are asynchronous and return promises.
11
+ */
12
+ declare abstract class EmailProvider {
13
+ /**
14
+ * Send an email.
15
+ *
16
+ * @param to The recipient email address.
17
+ * @param subject The email subject.
18
+ * @param body The email body (HTML content).
19
+ *
20
+ * @return Promise that resolves when the email is sent.
21
+ */
22
+ abstract send(to: string, subject: string, body: string): Promise<void>;
23
+ }
24
+ //#endregion
25
+ //#region src/providers/MemoryEmailProvider.d.ts
26
+ interface EmailRecord {
27
+ to: string;
28
+ subject: string;
29
+ body: string;
30
+ sentAt: Date;
31
+ }
32
+ declare class MemoryEmailProvider implements EmailProvider {
33
+ protected readonly log: _alepha_logger1.Logger;
34
+ protected emails: EmailRecord[];
35
+ send(to: string, subject: string, body: string): Promise<void>;
36
+ /**
37
+ * Get all emails sent through this provider (for testing purposes).
38
+ */
39
+ getEmails(): EmailRecord[];
40
+ /**
41
+ * Clear all stored emails (for testing purposes).
42
+ */
43
+ clearEmails(): void;
44
+ /**
45
+ * Get the last email sent (for testing purposes).
46
+ */
47
+ getLastEmail(): EmailRecord | undefined;
48
+ }
49
+ //#endregion
50
+ //#region src/services/TemplateService.d.ts
51
+ /**
52
+ * Minimal template service with Handlebars-like syntax for email templating.
53
+ * Supports simple variable substitution with {{variableName}} syntax.
54
+ */
55
+ declare class TemplateService {
56
+ /**
57
+ * Compile a template string with the provided values.
58
+ *
59
+ * @param template Template string with {{variableName}} placeholders
60
+ * @param values Object containing values to substitute
61
+ * @returns Compiled template string with values substituted
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const service = new TemplateService();
66
+ * const result = service.compile("Hello {{name}}!", { name: "John" });
67
+ * // Result: "Hello John!"
68
+ * ```
69
+ */
70
+ compile(template: string, values: Record<string, unknown>): string;
71
+ /**
72
+ * Validate that all required template variables are provided.
73
+ *
74
+ * @param template Template string
75
+ * @param values Values object
76
+ * @returns Array of missing variable names
77
+ */
78
+ validateTemplate(template: string, values: Record<string, unknown>): string[];
79
+ /**
80
+ * Extract all variable names from a template.
81
+ *
82
+ * @param template Template string
83
+ * @returns Array of variable names found in the template
84
+ */
85
+ extractVariables(template: string): string[];
86
+ }
87
+ //#endregion
88
+ //#region src/descriptors/$email.d.ts
89
+ /**
90
+ * Creates an email descriptor for sending type-safe templated emails.
91
+ *
92
+ * The $email descriptor provides a powerful templating system for creating and sending emails
93
+ * with full type safety and validation. It supports multiple email providers, template variable
94
+ * validation, and automatic HTML rendering.
95
+ *
96
+ * **Template Engine**
97
+ * - Simple {{variable}} syntax for dynamic content
98
+ * - Automatic template variable validation at runtime
99
+ * - Support for nested object properties in templates
100
+ * - HTML email support with rich formatting
101
+ *
102
+ * **Type Safety**
103
+ * - Full TypeScript support with schema validation using TypeBox
104
+ * - Compile-time type checking for template variables
105
+ * - Runtime validation of email data before sending
106
+ * - Automatic type inference from schema definitions
107
+ *
108
+ * **Provider Flexibility**
109
+ * - Memory provider for development and testing
110
+ * - Support for SMTP, SendGrid, AWS SES, and other providers
111
+ * - Custom provider implementation for specialized services
112
+ * - Automatic fallback and error handling
113
+ *
114
+ * **Template Management**
115
+ * - Reusable email templates across your application
116
+ * - Centralized template configuration and maintenance
117
+ * - Template variable documentation through schemas
118
+ * - Easy testing and preview capabilities
119
+ *
120
+ * **Development Experience**
121
+ * - Clear error messages for missing template variables
122
+ * - Comprehensive logging for debugging email delivery
123
+ * - Memory provider captures emails for testing
124
+ * - Template validation before sending
125
+ *
126
+ * @example Welcome email template
127
+ * ```typescript
128
+ * const welcomeEmail = $email({
129
+ * subject: "Welcome to {{companyName}}, {{firstName}}!",
130
+ * body: `
131
+ * <h1>Welcome {{firstName}} {{lastName}}!</h1>
132
+ * <p>Thank you for joining {{companyName}}.</p>
133
+ * <p>Your account role is: <strong>{{role}}</strong></p>
134
+ * <p>Get started by visiting your <a href="{{dashboardUrl}}">dashboard</a>.</p>
135
+ * `,
136
+ * schema: t.object({
137
+ * firstName: t.string(),
138
+ * lastName: t.string(),
139
+ * companyName: t.string(),
140
+ * role: t.enum(["admin", "user", "manager"]),
141
+ * dashboardUrl: t.string()
142
+ * })
143
+ * });
144
+ *
145
+ * // Send with full type safety
146
+ * await welcomeEmail.send("user@example.com", {
147
+ * firstName: "John",
148
+ * lastName: "Doe",
149
+ * companyName: "Acme Corp",
150
+ * role: "user",
151
+ * dashboardUrl: "https://app.acme.com/dashboard"
152
+ * });
153
+ * ```
154
+ *
155
+ * @example Order confirmation email
156
+ * ```typescript
157
+ * const orderConfirmation = $email({
158
+ * subject: "Order #{{orderNumber}} confirmed - {{totalAmount}}",
159
+ * body: `
160
+ * <h1>Order Confirmed!</h1>
161
+ * <p>Hi {{customerName}},</p>
162
+ * <p>Your order #{{orderNumber}} has been confirmed.</p>
163
+ * <h2>Order Details:</h2>
164
+ * <p><strong>Total: {{totalAmount}}</strong></p>
165
+ * <p>Estimated delivery: {{deliveryDate}}</p>
166
+ * `,
167
+ * schema: t.object({
168
+ * customerName: t.string(),
169
+ * orderNumber: t.string(),
170
+ * totalAmount: t.string(),
171
+ * deliveryDate: t.string()
172
+ * })
173
+ * });
174
+ * ```
175
+ *
176
+ * @example Development with memory provider
177
+ * ```typescript
178
+ * const testEmail = $email({
179
+ * subject: "Test: {{subject}}",
180
+ * body: "<p>{{message}}</p>",
181
+ * provider: "memory", // Captures emails for testing
182
+ * schema: t.object({
183
+ * subject: t.string(),
184
+ * message: t.string()
185
+ * })
186
+ * });
187
+ *
188
+ * // In tests - emails are captured, not actually sent
189
+ * await testEmail.send("test@example.com", {
190
+ * subject: "Unit Test",
191
+ * message: "This email was captured for testing"
192
+ * });
193
+ * ```
194
+ */
195
+ declare const $email: {
196
+ <T extends TSchema>(options: EmailDescriptorOptions<T>): EmailDescriptor<T>;
197
+ [KIND]: typeof EmailDescriptor;
198
+ };
199
+ interface EmailDescriptorOptions<T extends TSchema> {
200
+ /**
201
+ * Email subject template. Supports {{variableName}} syntax.
202
+ */
203
+ subject: string;
204
+ /**
205
+ * Email body template (HTML content). Supports {{variableName}} syntax.
206
+ */
207
+ body: string;
208
+ /**
209
+ * Schema defining the structure of template variables.
210
+ */
211
+ schema: T;
212
+ /**
213
+ * Optional name of the email template.
214
+ * @default Descriptor key
215
+ */
216
+ name?: string;
217
+ /**
218
+ * Optional description of the email template.
219
+ */
220
+ description?: string;
221
+ /**
222
+ * Email provider to use. If not provided, the default provider will be used.
223
+ */
224
+ provider?: Service<EmailProvider> | "memory";
225
+ }
226
+ declare class EmailDescriptor<T extends TSchema> extends Descriptor<EmailDescriptorOptions<T>> {
227
+ protected readonly log: _alepha_logger1.Logger;
228
+ protected readonly templateService: TemplateService;
229
+ readonly provider: EmailProvider | MemoryEmailProvider;
230
+ get name(): string;
231
+ /**
232
+ * Send an email using the template with the provided values.
233
+ *
234
+ * @param to Recipient email address
235
+ * @param values Template variable values
236
+ */
237
+ send(to: string, values: Static<T>): Promise<void>;
238
+ protected $provider(): EmailProvider | MemoryEmailProvider;
239
+ }
240
+ //#endregion
241
+ //#region src/errors/EmailError.d.ts
242
+ declare class EmailError extends Error {
243
+ constructor(message: string, cause?: Error);
244
+ }
245
+ //#endregion
246
+ //#region src/providers/LocalEmailProvider.d.ts
247
+ interface LocalEmailProviderOptions {
248
+ /**
249
+ * Directory to save email files.
250
+ * @default "email" (relative to project root)
251
+ */
252
+ directory?: string;
253
+ }
254
+ declare class LocalEmailProvider implements EmailProvider {
255
+ protected readonly log: _alepha_logger1.Logger;
256
+ protected readonly directory: string;
257
+ constructor(options?: LocalEmailProviderOptions);
258
+ send(to: string, subject: string, body: string): Promise<void>;
259
+ protected createEmailHtml(to: string, subject: string, body: string): string;
260
+ protected escapeHtml(text: string): string;
261
+ }
262
+ //#endregion
263
+ //#region src/providers/NodemailerEmailProvider.d.ts
264
+ interface NodemailerEmailProviderOptions {
265
+ /**
266
+ * Custom transporter configuration.
267
+ * If provided, will override environment variables.
268
+ */
269
+ transporter?: Transporter;
270
+ /**
271
+ * Custom from email address.
272
+ * If not provided, will use EMAIL_FROM from environment.
273
+ */
274
+ from?: string;
275
+ /**
276
+ * Additional nodemailer options.
277
+ */
278
+ options?: {
279
+ pool?: boolean;
280
+ maxConnections?: number;
281
+ maxMessages?: number;
282
+ rateDelta?: number;
283
+ rateLimit?: number;
284
+ };
285
+ }
286
+ declare class NodemailerEmailProvider implements EmailProvider {
287
+ protected readonly env: {
288
+ EMAIL_HOST: string;
289
+ EMAIL_PORT: number;
290
+ EMAIL_USER: string;
291
+ EMAIL_PASS: string;
292
+ EMAIL_FROM: string;
293
+ EMAIL_SECURE: boolean;
294
+ };
295
+ protected readonly log: _alepha_logger1.Logger;
296
+ protected transporter: Transporter;
297
+ protected fromAddress: string;
298
+ readonly options: NodemailerEmailProviderOptions;
299
+ constructor();
300
+ send(to: string, subject: string, body: string): Promise<void>;
301
+ protected createTransporter(): Transporter;
302
+ /**
303
+ * Verify the connection to the email server.
304
+ */
305
+ verify(): Promise<boolean>;
306
+ /**
307
+ * Close the transporter connection.
308
+ */
309
+ close(): void;
310
+ protected readonly onStart: _alepha_core1.HookDescriptor<"start">;
311
+ protected readonly onStop: _alepha_core1.HookDescriptor<"stop">;
312
+ }
313
+ //#endregion
314
+ //#region src/index.d.ts
315
+ /**
316
+ * Provides email sending capabilities for Alepha applications with multiple provider backends.
317
+ *
318
+ * The email module enables declarative email sending through the `$email` descriptor, allowing you to send
319
+ * emails through different providers: memory (for testing), local file system, or SMTP via Nodemailer.
320
+ * It supports HTML email content and automatic provider selection based on environment configuration.
321
+ *
322
+ * @see {@link EmailProvider}
323
+ * @module alepha.email
324
+ */
325
+ declare const AlephaEmail: _alepha_core1.Service<_alepha_core1.Module>;
326
+ //#endregion
327
+ export { $email, AlephaEmail, EmailDescriptor, EmailDescriptorOptions, EmailError, EmailProvider, EmailRecord, LocalEmailProvider, LocalEmailProviderOptions, MemoryEmailProvider, NodemailerEmailProvider, NodemailerEmailProviderOptions, TemplateService };
328
+ //# sourceMappingURL=index.d.ts.map
package/email.js ADDED
@@ -0,0 +1 @@
1
+ export * from '@alepha/email'