fix(types): Fix TypeScript build errors and improve API type safety across platformservice interfaces
This commit is contained in:
@ -5,6 +5,10 @@ import { logger } from '../../logger.js';
|
||||
// Import MTA classes
|
||||
import { MtaService } from './classes.mta.js';
|
||||
import { Email as MtaEmail } from '../core/classes.email.js';
|
||||
import { DeliveryStatus } from './classes.emailsendjob.js';
|
||||
|
||||
// Re-export for use in index.ts
|
||||
export { DeliveryStatus };
|
||||
|
||||
// Import Email types
|
||||
export interface IEmailOptions {
|
||||
@ -19,14 +23,6 @@ export interface IEmailOptions {
|
||||
headers?: { [key: string]: string };
|
||||
}
|
||||
|
||||
// Reuse the DeliveryStatus from the email send job
|
||||
export enum DeliveryStatus {
|
||||
PENDING = 'pending',
|
||||
PROCESSING = 'processing',
|
||||
DELIVERED = 'delivered',
|
||||
DEFERRED = 'deferred',
|
||||
FAILED = 'failed'
|
||||
}
|
||||
|
||||
// Reuse the IAttachment interface
|
||||
export interface IAttachment {
|
||||
@ -37,6 +33,66 @@ export interface IAttachment {
|
||||
encoding?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email status details
|
||||
*/
|
||||
export interface IEmailStatusDetails {
|
||||
/** Number of delivery attempts */
|
||||
attempts?: number;
|
||||
/** Timestamp of last delivery attempt */
|
||||
lastAttempt?: Date;
|
||||
/** Timestamp of next scheduled attempt */
|
||||
nextAttempt?: Date;
|
||||
/** Error message if delivery failed */
|
||||
error?: string;
|
||||
/** Message explaining the status */
|
||||
message?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Email status response
|
||||
*/
|
||||
export interface IEmailStatusResponse {
|
||||
/** Current status of the email */
|
||||
status: DeliveryStatus | 'unknown' | 'error';
|
||||
/** Additional status details */
|
||||
details?: IEmailStatusDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for sending an email via MTA
|
||||
*/
|
||||
export interface ISendEmailOptions {
|
||||
/** Whether to use MIME format conversion */
|
||||
useMimeFormat?: boolean;
|
||||
/** Whether to track clicks */
|
||||
trackClicks?: boolean;
|
||||
/** Whether to track opens */
|
||||
trackOpens?: boolean;
|
||||
/** Message priority (1-5, where 1 is highest) */
|
||||
priority?: number;
|
||||
/** Message scheduling options */
|
||||
schedule?: {
|
||||
/** Time to send the email */
|
||||
sendAt?: Date | string;
|
||||
/** Time the message expires */
|
||||
expireAt?: Date | string;
|
||||
};
|
||||
/** DKIM signing options */
|
||||
dkim?: {
|
||||
/** Whether to sign the message */
|
||||
sign?: boolean;
|
||||
/** Domain to use for signing */
|
||||
domain?: string;
|
||||
/** Key selector to use */
|
||||
selector?: string;
|
||||
};
|
||||
/** Additional headers */
|
||||
headers?: Record<string, string>;
|
||||
/** Message tags for categorization */
|
||||
tags?: string[];
|
||||
}
|
||||
|
||||
export class MtaConnector {
|
||||
public emailRef: EmailService;
|
||||
private mtaService: MtaService;
|
||||
@ -46,6 +102,13 @@ export class MtaConnector {
|
||||
this.mtaService = mtaService || this.emailRef.mtaService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email using the MTA service
|
||||
* @param smartmail The email to send
|
||||
* @param toAddresses Recipients (comma-separated or array)
|
||||
* @param options Additional options
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send an email using the MTA service
|
||||
* @param smartmail The email to send
|
||||
@ -55,7 +118,7 @@ export class MtaConnector {
|
||||
public async sendEmail(
|
||||
smartmail: plugins.smartmail.Smartmail<any>,
|
||||
toAddresses: string | string[],
|
||||
options: any = {}
|
||||
options: ISendEmailOptions = {}
|
||||
): Promise<string> {
|
||||
// Check if recipients are on the suppression list
|
||||
const recipients = Array.isArray(toAddresses)
|
||||
@ -101,7 +164,7 @@ export class MtaConnector {
|
||||
const emailOptions: Record<string, any> = { ...options };
|
||||
|
||||
// Check if we should use MIME format
|
||||
const useMimeFormat = options.useMimeFormat ?? true;
|
||||
const useMimeFormat = options.useMimeFormat !== false; // Default to true
|
||||
|
||||
if (useMimeFormat) {
|
||||
// Use smartmail's MIME conversion for improved handling
|
||||
@ -521,28 +584,28 @@ export class MtaConnector {
|
||||
/**
|
||||
* Check the status of a sent email
|
||||
* @param emailId The email ID to check
|
||||
* @returns Current status and details
|
||||
*/
|
||||
public async checkEmailStatus(emailId: string): Promise<{
|
||||
status: string;
|
||||
details?: any;
|
||||
}> {
|
||||
public async checkEmailStatus(emailId: string): Promise<IEmailStatusResponse> {
|
||||
try {
|
||||
const status = this.mtaService.getEmailStatus(emailId);
|
||||
|
||||
if (!status) {
|
||||
return {
|
||||
status: 'unknown',
|
||||
status: 'unknown' as const,
|
||||
details: { message: 'Email not found' }
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: status.status,
|
||||
// Use type assertion to ensure this passes type check
|
||||
status: status.status as DeliveryStatus,
|
||||
details: {
|
||||
attempts: status.attempts,
|
||||
lastAttempt: status.lastAttempt,
|
||||
nextAttempt: status.nextAttempt,
|
||||
error: status.error?.message
|
||||
error: status.error?.message,
|
||||
message: `Status: ${status.status}${status.error ? `, Error: ${status.error.message}` : ''}`
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
@ -554,7 +617,7 @@ export class MtaConnector {
|
||||
});
|
||||
|
||||
return {
|
||||
status: 'error',
|
||||
status: 'error' as const,
|
||||
details: { message: error.message }
|
||||
};
|
||||
}
|
||||
|
@ -65,8 +65,18 @@ export class ApiManager {
|
||||
new plugins.typedrequest.TypedHandler('checkEmailStatus', async (requestData) => {
|
||||
// If MTA is enabled, use it to check status
|
||||
if (this.emailRef.mtaConnector) {
|
||||
const status = await this.emailRef.mtaConnector.checkEmailStatus(requestData.emailId);
|
||||
return status;
|
||||
const detailedStatus = await this.emailRef.mtaConnector.checkEmailStatus(requestData.emailId);
|
||||
|
||||
// Convert to the expected API response format
|
||||
const apiResponse: plugins.servezoneInterfaces.platformservice.mta.IReq_CheckEmailStatus['response'] = {
|
||||
status: detailedStatus.status.toString(), // Convert enum to string
|
||||
details: {
|
||||
message: detailedStatus.details?.message ||
|
||||
(detailedStatus.details?.error ? `Error: ${detailedStatus.details.error}` :
|
||||
`Status: ${detailedStatus.status}`)
|
||||
}
|
||||
};
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
// Status tracking not available if MTA is not configured
|
||||
|
@ -24,6 +24,107 @@ export interface IEmailConstructorOptions {
|
||||
loadTemplatesFromDir?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for sending an email
|
||||
* @see ISendEmailOptions in MtaConnector
|
||||
*/
|
||||
export type ISendEmailOptions = import('../delivery/classes.connector.mta.js').ISendEmailOptions;
|
||||
|
||||
/**
|
||||
* Template context data for email templates
|
||||
* @see ITemplateContext in TemplateManager
|
||||
*/
|
||||
export type ITemplateContext = import('../core/classes.templatemanager.js').ITemplateContext;
|
||||
|
||||
/**
|
||||
* Validation options for email addresses
|
||||
* Compatible with EmailValidator.validate options
|
||||
*/
|
||||
export interface IValidateEmailOptions {
|
||||
/** Check MX records for the domain */
|
||||
checkMx?: boolean;
|
||||
/** Check if the domain is disposable (temporary email) */
|
||||
checkDisposable?: boolean;
|
||||
/** Check if the email is a role account (e.g., info@, support@) */
|
||||
checkRole?: boolean;
|
||||
/** Only check syntax without DNS lookups */
|
||||
checkSyntaxOnly?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of email validation
|
||||
* @see IEmailValidationResult from EmailValidator
|
||||
*/
|
||||
export type IValidationResult = import('../core/classes.emailvalidator.js').IEmailValidationResult;
|
||||
|
||||
/**
|
||||
* Email service statistics
|
||||
*/
|
||||
export interface IEmailServiceStats {
|
||||
/** Active email providers */
|
||||
activeProviders: string[];
|
||||
/** MTA statistics, if MTA is active */
|
||||
mta?: {
|
||||
/** Service start time */
|
||||
startTime: Date;
|
||||
/** Total emails received */
|
||||
emailsReceived: number;
|
||||
/** Total emails sent */
|
||||
emailsSent: number;
|
||||
/** Total emails that failed to send */
|
||||
emailsFailed: number;
|
||||
/** Active SMTP connections */
|
||||
activeConnections: number;
|
||||
/** Current email queue size */
|
||||
queueSize: number;
|
||||
/** Certificate information */
|
||||
certificateInfo?: {
|
||||
/** Domain for the certificate */
|
||||
domain: string;
|
||||
/** Certificate expiration date */
|
||||
expiresAt: Date;
|
||||
/** Days until certificate expires */
|
||||
daysUntilExpiry: number;
|
||||
};
|
||||
/** IP warmup information */
|
||||
warmupInfo?: {
|
||||
/** Whether IP warmup is enabled */
|
||||
enabled: boolean;
|
||||
/** Number of active IPs */
|
||||
activeIPs: number;
|
||||
/** Number of IPs in warmup phase */
|
||||
inWarmupPhase: number;
|
||||
/** Number of IPs that completed warmup */
|
||||
completedWarmup: number;
|
||||
};
|
||||
/** Reputation monitoring information */
|
||||
reputationInfo?: {
|
||||
/** Whether reputation monitoring is enabled */
|
||||
enabled: boolean;
|
||||
/** Number of domains being monitored */
|
||||
monitoredDomains: number;
|
||||
/** Average reputation score across domains */
|
||||
averageScore: number;
|
||||
/** Number of domains with reputation issues */
|
||||
domainsWithIssues: number;
|
||||
};
|
||||
/** Rate limiting information */
|
||||
rateLimiting?: {
|
||||
/** Global rate limit statistics */
|
||||
global: {
|
||||
/** Current available tokens */
|
||||
availableTokens: number;
|
||||
/** Maximum tokens per period */
|
||||
maxTokens: number;
|
||||
/** Current consumption rate */
|
||||
consumptionRate: number;
|
||||
/** Number of rate limiting events */
|
||||
rateLimitEvents: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Email service with MTA support
|
||||
*/
|
||||
@ -136,7 +237,7 @@ export class EmailService {
|
||||
public async sendEmail(
|
||||
email: plugins.smartmail.Smartmail<any>,
|
||||
to: string | string[],
|
||||
options: any = {}
|
||||
options: ISendEmailOptions = {}
|
||||
): Promise<string> {
|
||||
// Determine which connector to use
|
||||
if (this.config.useMta && this.mtaConnector) {
|
||||
@ -156,8 +257,8 @@ export class EmailService {
|
||||
public async sendTemplateEmail(
|
||||
templateId: string,
|
||||
to: string | string[],
|
||||
context: any = {},
|
||||
options: any = {}
|
||||
context: ITemplateContext = {},
|
||||
options: ISendEmailOptions = {}
|
||||
): Promise<string> {
|
||||
try {
|
||||
// Get email from template
|
||||
@ -183,28 +284,35 @@ export class EmailService {
|
||||
*/
|
||||
public async validateEmail(
|
||||
email: string,
|
||||
options: {
|
||||
checkMx?: boolean;
|
||||
checkDisposable?: boolean;
|
||||
checkRole?: boolean;
|
||||
} = {}
|
||||
): Promise<any> {
|
||||
options: IValidateEmailOptions = {}
|
||||
): Promise<IValidationResult> {
|
||||
return this.emailValidator.validate(email, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get email service statistics
|
||||
* @returns Service statistics in the format expected by the API
|
||||
*/
|
||||
public getStats() {
|
||||
const stats: any = {
|
||||
public getStats(): plugins.servezoneInterfaces.platformservice.mta.IReq_GetEMailStats['response'] {
|
||||
// First generate detailed internal stats
|
||||
const detailedStats: IEmailServiceStats = {
|
||||
activeProviders: []
|
||||
};
|
||||
|
||||
if (this.config.useMta) {
|
||||
stats.activeProviders.push('mta');
|
||||
stats.mta = this.mtaService.getStats();
|
||||
detailedStats.activeProviders.push('mta');
|
||||
detailedStats.mta = this.mtaService.getStats();
|
||||
}
|
||||
|
||||
return stats;
|
||||
// Convert detailed stats to the format expected by the API
|
||||
const apiStats: plugins.servezoneInterfaces.platformservice.mta.IReq_GetEMailStats['response'] = {
|
||||
totalEmailsSent: detailedStats.mta?.emailsSent || 0,
|
||||
totalEmailsDelivered: detailedStats.mta?.emailsSent || 0, // Default to emails sent if we don't track delivery separately
|
||||
totalEmailsBounced: detailedStats.mta?.emailsFailed || 0,
|
||||
averageDeliveryTimeMs: 0, // We don't track this yet
|
||||
lastUpdated: new Date().toISOString()
|
||||
};
|
||||
|
||||
return apiStats;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user