start the path to rust

This commit is contained in:
2026-02-10 15:54:09 +00:00
parent 237dba3bab
commit 8bd8c295b0
318 changed files with 28352 additions and 428 deletions

View File

@@ -0,0 +1,200 @@
import type { Email } from './classes.email.js';
/**
* Bounce types for categorizing the reasons for bounces
*/
export declare enum BounceType {
INVALID_RECIPIENT = "invalid_recipient",
DOMAIN_NOT_FOUND = "domain_not_found",
MAILBOX_FULL = "mailbox_full",
MAILBOX_INACTIVE = "mailbox_inactive",
BLOCKED = "blocked",
SPAM_RELATED = "spam_related",
POLICY_RELATED = "policy_related",
SERVER_UNAVAILABLE = "server_unavailable",
TEMPORARY_FAILURE = "temporary_failure",
QUOTA_EXCEEDED = "quota_exceeded",
NETWORK_ERROR = "network_error",
TIMEOUT = "timeout",
AUTO_RESPONSE = "auto_response",
CHALLENGE_RESPONSE = "challenge_response",
UNKNOWN = "unknown"
}
/**
* Hard vs soft bounce classification
*/
export declare enum BounceCategory {
HARD = "hard",
SOFT = "soft",
AUTO_RESPONSE = "auto_response",
UNKNOWN = "unknown"
}
/**
* Bounce data structure
*/
export interface BounceRecord {
id: string;
originalEmailId?: string;
recipient: string;
sender: string;
domain: string;
subject?: string;
bounceType: BounceType;
bounceCategory: BounceCategory;
timestamp: number;
smtpResponse?: string;
diagnosticCode?: string;
statusCode?: string;
headers?: Record<string, string>;
processed: boolean;
retryCount?: number;
nextRetryTime?: number;
}
/**
* Retry strategy configuration for soft bounces
*/
interface RetryStrategy {
maxRetries: number;
initialDelay: number;
maxDelay: number;
backoffFactor: number;
}
/**
* Manager for handling email bounces
*/
export declare class BounceManager {
private retryStrategy;
private bounceStore;
private bounceCache;
private suppressionList;
private storageManager?;
constructor(options?: {
retryStrategy?: Partial<RetryStrategy>;
maxCacheSize?: number;
cacheTTL?: number;
storageManager?: any;
});
/**
* Process a bounce notification
* @param bounceData Bounce data to process
* @returns Processed bounce record
*/
processBounce(bounceData: Partial<BounceRecord>): Promise<BounceRecord>;
/**
* Process an SMTP failure as a bounce
* @param recipient Recipient email
* @param smtpResponse SMTP error response
* @param options Additional options
* @returns Processed bounce record
*/
processSmtpFailure(recipient: string, smtpResponse: string, options?: {
sender?: string;
originalEmailId?: string;
statusCode?: string;
headers?: Record<string, string>;
}): Promise<BounceRecord>;
/**
* Process a bounce notification email
* @param bounceEmail The email containing bounce information
* @returns Processed bounce record or null if not a bounce
*/
processBounceEmail(bounceEmail: Email): Promise<BounceRecord | null>;
/**
* Handle a hard bounce by adding to suppression list
* @param bounce The bounce record
*/
private handleHardBounce;
/**
* Handle a soft bounce by scheduling a retry if eligible
* @param bounce The bounce record
*/
private handleSoftBounce;
/**
* Add an email address to the suppression list
* @param email Email address to suppress
* @param reason Reason for suppression
* @param expiresAt Expiration timestamp (undefined for permanent)
*/
addToSuppressionList(email: string, reason: string, expiresAt?: number): void;
/**
* Remove an email address from the suppression list
* @param email Email address to remove
*/
removeFromSuppressionList(email: string): void;
/**
* Check if an email is on the suppression list
* @param email Email address to check
* @returns Whether the email is suppressed
*/
isEmailSuppressed(email: string): boolean;
/**
* Get suppression information for an email
* @param email Email address to check
* @returns Suppression information or null if not suppressed
*/
getSuppressionInfo(email: string): {
reason: string;
timestamp: number;
expiresAt?: number;
} | null;
/**
* Save suppression list to disk
*/
private saveSuppressionList;
/**
* Load suppression list from disk
*/
private loadSuppressionList;
/**
* Save bounce record to disk
* @param bounce Bounce record to save
*/
private saveBounceRecord;
/**
* Update bounce cache with new bounce information
* @param bounce Bounce record to update cache with
*/
private updateBounceCache;
/**
* Check bounce history for an email address
* @param email Email address to check
* @returns Bounce information or null if no bounces
*/
getBounceInfo(email: string): {
lastBounce: number;
count: number;
type: BounceType;
category: BounceCategory;
} | null;
/**
* Analyze SMTP response and diagnostic codes to determine bounce type
* @param smtpResponse SMTP response string
* @param diagnosticCode Diagnostic code from bounce
* @param statusCode Status code from bounce
* @returns Detected bounce type and category
*/
private detectBounceType;
/**
* Check if text matches any pattern for a bounce type
* @param text Text to check against patterns
* @param bounceType Bounce type to get patterns for
* @returns Whether the text matches any pattern
*/
private matchesPattern;
/**
* Get all known hard bounced addresses
* @returns Array of hard bounced email addresses
*/
getHardBouncedAddresses(): string[];
/**
* Get suppression list
* @returns Array of suppressed email addresses
*/
getSuppressionList(): string[];
/**
* Clear old bounce records (for maintenance)
* @param olderThan Timestamp to remove records older than
* @returns Number of records removed
*/
clearOldBounceRecords(olderThan: number): number;
}
export {};

File diff suppressed because one or more lines are too long

291
dist_ts/mail/core/classes.email.d.ts vendored Normal file
View File

@@ -0,0 +1,291 @@
import * as plugins from '../../plugins.js';
export interface IAttachment {
filename: string;
content: Buffer;
contentType: string;
contentId?: string;
encoding?: string;
}
export interface IEmailOptions {
from: string;
to?: string | string[];
cc?: string | string[];
bcc?: string | string[];
subject: string;
text: string;
html?: string;
attachments?: IAttachment[];
headers?: Record<string, string>;
mightBeSpam?: boolean;
priority?: 'high' | 'normal' | 'low';
skipAdvancedValidation?: boolean;
variables?: Record<string, any>;
}
/**
* Email class represents a complete email message.
*
* This class takes IEmailOptions in the constructor and normalizes the data:
* - 'to', 'cc', 'bcc' are always converted to arrays
* - Optional properties get default values
* - Additional properties like messageId and envelopeFrom are generated
*/
export declare class Email {
from: string;
to: string[];
cc: string[];
bcc: string[];
subject: string;
text: string;
html?: string;
attachments: IAttachment[];
headers: Record<string, string>;
mightBeSpam: boolean;
priority: 'high' | 'normal' | 'low';
variables: Record<string, any>;
private envelopeFrom;
private messageId;
private static emailValidator;
constructor(options: IEmailOptions);
/**
* Validates an email address using smartmail's EmailAddressValidator
* For constructor validation, we only check syntax to avoid delays
* Supports RFC-compliant addresses including display names and bounce addresses.
*
* @param email The email address to validate
* @returns boolean indicating if the email is valid
*/
private isValidEmail;
/**
* Extracts the email address from a string that may contain a display name.
* Handles formats like:
* - simple@example.com
* - "John Doe" <john@example.com>
* - John Doe <john@example.com>
*
* @param emailString The email string to parse
* @returns The extracted email address or null
*/
private extractEmailAddress;
/**
* Parses and validates recipient email addresses
* @param recipients A string or array of recipient emails
* @returns Array of validated email addresses
*/
private parseRecipients;
/**
* Basic sanitization for strings to prevent header injection
* @param input The string to sanitize
* @returns Sanitized string
*/
private sanitizeString;
/**
* Gets the domain part of the from email address
* @returns The domain part of the from email or null if invalid
*/
getFromDomain(): string | null;
/**
* Gets the clean from email address without display name
* @returns The email address without display name
*/
getFromAddress(): string;
/**
* Converts IDN (International Domain Names) to ASCII
* @param email The email address to convert
* @returns The email with ASCII-converted domain
*/
private convertIDNToASCII;
/**
* Gets clean to email addresses without display names
* @returns Array of email addresses without display names
*/
getToAddresses(): string[];
/**
* Gets clean cc email addresses without display names
* @returns Array of email addresses without display names
*/
getCcAddresses(): string[];
/**
* Gets clean bcc email addresses without display names
* @returns Array of email addresses without display names
*/
getBccAddresses(): string[];
/**
* Gets all recipients (to, cc, bcc) as a unique array
* @returns Array of all unique recipient email addresses
*/
getAllRecipients(): string[];
/**
* Gets primary recipient (first in the to field)
* @returns The primary recipient email or null if none exists
*/
getPrimaryRecipient(): string | null;
/**
* Checks if the email has attachments
* @returns Boolean indicating if the email has attachments
*/
hasAttachments(): boolean;
/**
* Add a recipient to the email
* @param email The recipient email address
* @param type The recipient type (to, cc, bcc)
* @returns This instance for method chaining
*/
addRecipient(email: string, type?: 'to' | 'cc' | 'bcc'): this;
/**
* Add an attachment to the email
* @param attachment The attachment to add
* @returns This instance for method chaining
*/
addAttachment(attachment: IAttachment): this;
/**
* Add a custom header to the email
* @param name The header name
* @param value The header value
* @returns This instance for method chaining
*/
addHeader(name: string, value: string): this;
/**
* Set the email priority
* @param priority The priority level
* @returns This instance for method chaining
*/
setPriority(priority: 'high' | 'normal' | 'low'): this;
/**
* Set a template variable
* @param key The variable key
* @param value The variable value
* @returns This instance for method chaining
*/
setVariable(key: string, value: any): this;
/**
* Set multiple template variables at once
* @param variables The variables object
* @returns This instance for method chaining
*/
setVariables(variables: Record<string, any>): this;
/**
* Get the subject with variables applied
* @param variables Optional additional variables to apply
* @returns The processed subject
*/
getSubjectWithVariables(variables?: Record<string, any>): string;
/**
* Get the text content with variables applied
* @param variables Optional additional variables to apply
* @returns The processed text content
*/
getTextWithVariables(variables?: Record<string, any>): string;
/**
* Get the HTML content with variables applied
* @param variables Optional additional variables to apply
* @returns The processed HTML content or undefined if none
*/
getHtmlWithVariables(variables?: Record<string, any>): string | undefined;
/**
* Apply template variables to a string
* @param template The template string
* @param additionalVariables Optional additional variables to apply
* @returns The processed string
*/
private applyVariables;
/**
* Gets the total size of all attachments in bytes
* @returns Total size of all attachments in bytes
*/
getAttachmentsSize(): number;
/**
* Perform advanced validation on sender and recipient email addresses
* This should be called separately after instantiation when ready to check MX records
* @param options Validation options
* @returns Promise resolving to validation results for all addresses
*/
validateAddresses(options?: {
checkMx?: boolean;
checkDisposable?: boolean;
checkSenderOnly?: boolean;
checkFirstRecipientOnly?: boolean;
}): Promise<{
sender: {
email: string;
result: any;
};
recipients: Array<{
email: string;
result: any;
}>;
isValid: boolean;
}>;
/**
* Convert this email to a smartmail instance
* @returns A new Smartmail instance
*/
toSmartmail(): Promise<plugins.smartmail.Smartmail<any>>;
/**
* Get the from email address
* @returns The from email address
*/
getFromEmail(): string;
/**
* Get the subject (Smartmail compatibility method)
* @returns The email subject
*/
getSubject(): string;
/**
* Get the body content (Smartmail compatibility method)
* @param isHtml Whether to return HTML content if available
* @returns The email body (HTML if requested and available, otherwise plain text)
*/
getBody(isHtml?: boolean): string;
/**
* Get the from address (Smartmail compatibility method)
* @returns The sender email address
*/
getFrom(): string;
/**
* Get the message ID
* @returns The message ID
*/
getMessageId(): string;
/**
* Convert the Email instance back to IEmailOptions format.
* Useful for serialization or passing to APIs that expect IEmailOptions.
* Note: This loses some Email-specific properties like messageId and envelopeFrom.
*
* @returns IEmailOptions representation of this email
*/
toEmailOptions(): IEmailOptions;
/**
* Set a custom message ID
* @param id The message ID to set
* @returns This instance for method chaining
*/
setMessageId(id: string): this;
/**
* Get the envelope from address (return-path)
* @returns The envelope from address
*/
getEnvelopeFrom(): string;
/**
* Set the envelope from address (return-path)
* @param address The envelope from address to set
* @returns This instance for method chaining
*/
setEnvelopeFrom(address: string): this;
/**
* Creates an RFC822 compliant email string
* @param variables Optional template variables to apply
* @returns The email formatted as an RFC822 compliant string
*/
toRFC822String(variables?: Record<string, any>): string;
/**
* Convert to simple Smartmail-compatible object (for backward compatibility)
* @returns A Promise with a simple Smartmail-compatible object
*/
toSmartmailBasic(): Promise<any>;
/**
* Create an Email instance from a Smartmail object
* @param smartmail The Smartmail instance to convert
* @returns A new Email instance
*/
static fromSmartmail(smartmail: plugins.smartmail.Smartmail<any>): Email;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,61 @@
export interface IEmailValidationResult {
isValid: boolean;
hasMx: boolean;
hasSpamMarkings: boolean;
score: number;
details?: {
formatValid?: boolean;
mxRecords?: string[];
disposable?: boolean;
role?: boolean;
spamIndicators?: string[];
errorMessage?: string;
};
}
/**
* Advanced email validator class using smartmail's capabilities
*/
export declare class EmailValidator {
private validator;
private dnsCache;
constructor(options?: {
maxCacheSize?: number;
cacheTTL?: number;
});
/**
* Validates an email address using comprehensive checks
* @param email The email to validate
* @param options Validation options
* @returns Validation result with details
*/
validate(email: string, options?: {
checkMx?: boolean;
checkDisposable?: boolean;
checkRole?: boolean;
checkSyntaxOnly?: boolean;
}): Promise<IEmailValidationResult>;
/**
* Gets MX records for a domain with caching
* @param domain Domain to check
* @returns Array of MX records
*/
private getMxRecords;
/**
* Validates multiple email addresses in batch
* @param emails Array of emails to validate
* @param options Validation options
* @returns Object with email addresses as keys and validation results as values
*/
validateBatch(emails: string[], options?: {
checkMx?: boolean;
checkDisposable?: boolean;
checkRole?: boolean;
checkSyntaxOnly?: boolean;
}): Promise<Record<string, IEmailValidationResult>>;
/**
* Quick check if an email format is valid (synchronous, no DNS checks)
* @param email Email to check
* @returns Boolean indicating if format is valid
*/
isValidFormat(email: string): boolean;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,95 @@
import { Email } from './classes.email.js';
/**
* Email template type definition
*/
export interface IEmailTemplate<T = any> {
id: string;
name: string;
description: string;
from: string;
subject: string;
bodyHtml: string;
bodyText?: string;
category?: string;
sampleData?: T;
attachments?: Array<{
name: string;
path: string;
contentType?: string;
}>;
}
/**
* Email template context - data used to render the template
*/
export interface ITemplateContext {
[key: string]: any;
}
/**
* Template category definitions
*/
export declare enum TemplateCategory {
NOTIFICATION = "notification",
TRANSACTIONAL = "transactional",
MARKETING = "marketing",
SYSTEM = "system"
}
/**
* Enhanced template manager using Email class for template rendering
*/
export declare class TemplateManager {
private templates;
private defaultConfig;
constructor(defaultConfig?: {
from?: string;
replyTo?: string;
footerHtml?: string;
footerText?: string;
});
/**
* Register built-in email templates
*/
private registerBuiltinTemplates;
/**
* Register a new email template
* @param template The email template to register
*/
registerTemplate<T = any>(template: IEmailTemplate<T>): void;
/**
* Get an email template by ID
* @param templateId The template ID
* @returns The template or undefined if not found
*/
getTemplate<T = any>(templateId: string): IEmailTemplate<T> | undefined;
/**
* List all available templates
* @param category Optional category filter
* @returns Array of email templates
*/
listTemplates(category?: TemplateCategory): IEmailTemplate[];
/**
* Create an Email instance from a template
* @param templateId The template ID
* @param context The template context data
* @returns A configured Email instance
*/
createEmail<T = any>(templateId: string, context?: ITemplateContext): Promise<Email>;
/**
* Create and completely process an Email instance from a template
* @param templateId The template ID
* @param context The template context data
* @returns A complete, processed Email instance ready to send
*/
prepareEmail<T = any>(templateId: string, context?: ITemplateContext): Promise<Email>;
/**
* Create a MIME-formatted email from a template
* @param templateId The template ID
* @param context The template context data
* @returns A MIME-formatted email string
*/
createMimeEmail(templateId: string, context?: ITemplateContext): Promise<string>;
/**
* Load templates from a directory
* @param directory The directory containing template JSON files
*/
loadTemplatesFromDirectory(directory: string): Promise<void>;
}

File diff suppressed because one or more lines are too long

4
dist_ts/mail/core/index.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
export * from './classes.email.js';
export * from './classes.emailvalidator.js';
export * from './classes.templatemanager.js';
export * from './classes.bouncemanager.js';

View File

@@ -0,0 +1,6 @@
// Core email components
export * from './classes.email.js';
export * from './classes.emailvalidator.js';
export * from './classes.templatemanager.js';
export * from './classes.bouncemanager.js';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9tYWlsL2NvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsd0JBQXdCO0FBQ3hCLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLDhCQUE4QixDQUFDO0FBQzdDLGNBQWMsNEJBQTRCLENBQUMifQ==