mail-time 5.2.1 → 5.3.1
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/README.md +24 -12
- package/adapters/mongo.d.ts +9 -8
- package/adapters/mongo.js +8 -8
- package/adapters/postgres.d.ts +5 -0
- package/adapters/postgres.js +35 -10
- package/adapters/redis.d.ts +1 -1
- package/adapters/redis.js +37 -18
- package/index.cjs +580 -141
- package/index.d.cts +20 -76
- package/index.d.ts +20 -76
- package/index.js +307 -79
- package/package.json +24 -5
- package/recipient-policy-lease.js +40 -8
- package/recipient-policy.js +155 -20
package/index.d.cts
CHANGED
|
@@ -199,6 +199,18 @@ export type MailTimeFromDetails = {
|
|
|
199
199
|
index: number;
|
|
200
200
|
from: string | undefined;
|
|
201
201
|
};
|
|
202
|
+
export type MailTimeDrainResult = {
|
|
203
|
+
failedWrites: number;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* `details` passed to `onError`. `phase` is `'verify'` (transport verification, `email === null`), `'complete'` (a storage write recording a send outcome), or `'checkpoint'` (recipient-policy results written after SMTP). Without `phase` it is the SMTP `info` of the failed attempt.
|
|
207
|
+
*/
|
|
208
|
+
export type MailTimeErrorDetails = {
|
|
209
|
+
phase?: "verify" | "complete" | "checkpoint";
|
|
210
|
+
transportIndex?: number;
|
|
211
|
+
attempt?: number;
|
|
212
|
+
[key: string]: unknown;
|
|
213
|
+
};
|
|
202
214
|
export type MailTimeOptions = {
|
|
203
215
|
queue: RedisQueue | MongoQueue | PostgresQueue | CustomQueue;
|
|
204
216
|
type?: "server" | "client";
|
|
@@ -226,86 +238,17 @@ export type MailTimeOptions = {
|
|
|
226
238
|
strictPayload?: boolean;
|
|
227
239
|
allowedMailFields?: string[];
|
|
228
240
|
verifyTransports?: boolean;
|
|
241
|
+
verifyTimeout?: number;
|
|
229
242
|
template?: string;
|
|
230
243
|
prefix?: string;
|
|
231
244
|
debug?: boolean;
|
|
232
245
|
josk?: MailTimeJoSkOptions;
|
|
233
246
|
recipientPolicies?: MailTimeRecipientPolicy[];
|
|
234
|
-
onError?: (error: unknown, email: MailTimeTask | null, details?:
|
|
247
|
+
onError?: (error: unknown, email: MailTimeTask | null, details?: MailTimeErrorDetails, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
235
248
|
onSent?: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
236
249
|
onSuppressed?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
237
250
|
onRejected?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
238
251
|
};
|
|
239
|
-
/**
|
|
240
|
-
* @typedef {import('./presets.js').MailTimePresetName} MailTimePresetName
|
|
241
|
-
*/
|
|
242
|
-
/**
|
|
243
|
-
* @typedef {import('./presets.js').MailTimePresetConfig} MailTimePresetConfig
|
|
244
|
-
*/
|
|
245
|
-
/**
|
|
246
|
-
* @typedef {{ status: string, code: number, statusCode: number, paused?: boolean, error?: unknown }} MailTimePingResult
|
|
247
|
-
*/
|
|
248
|
-
/**
|
|
249
|
-
* @typedef {{ [key: string]: any, query?: (queryText: string, values?: unknown[]) => Promise<{ rows?: unknown[], rowCount?: number | null }> }} MailTimeStorageClient
|
|
250
|
-
*/
|
|
251
|
-
/**
|
|
252
|
-
* @typedef {{ [key: string]: any }} MailTimeMongoDb
|
|
253
|
-
*/
|
|
254
|
-
/**
|
|
255
|
-
* @typedef {{ [key: string]: any }} MailTimeTransport
|
|
256
|
-
*/
|
|
257
|
-
/**
|
|
258
|
-
* @typedef {{ [key: string]: any, type?: 'mongo' | 'redis' | 'postgres', client?: MailTimeStorageClient, db?: MailTimeMongoDb, prefix?: string, resetOnInit?: boolean, useHashTags?: boolean }} MailTimeJoSkAdapterOptions
|
|
259
|
-
*/
|
|
260
|
-
/**
|
|
261
|
-
* @typedef {{ [key: string]: any, adapter: MailTimeJoSkAdapterOptions | object, debug?: boolean, autoClear?: boolean, zombieTime?: number, lockLeaseTime?: number, minRevolvingDelay?: number, maxRevolvingDelay?: number, execute?: 'batch' | 'one', concurrency?: number, lockOwnerId?: string, resetOnInit?: boolean, onError?: (title: string, details: object) => void, onExecuted?: (uid: string, details: object) => void }} MailTimeJoSkOptions
|
|
262
|
-
*/
|
|
263
|
-
/**
|
|
264
|
-
* @typedef {{ [key: string]: any, ping: () => Promise<MailTimePingResult>, setInterval: (func: (...args: any[]) => unknown, delay: number, uid: string) => Promise<string>, destroy: () => boolean, shutdown: (opts?: { timeout?: number }) => Promise<boolean>, pause: (timerId?: string) => boolean, resume: (timerId?: string) => boolean }} MailTimeScheduler
|
|
265
|
-
*/
|
|
266
|
-
/**
|
|
267
|
-
* @typedef {string | { address: string, name?: string }} MailTimeMailbox
|
|
268
|
-
*/
|
|
269
|
-
/**
|
|
270
|
-
* @typedef {{ address: string, sources: Array<'envelope' | 'to' | 'cc' | 'bcc'> }} MailTimePolicyRecipient
|
|
271
|
-
* @typedef {{ address: string, status: 'suppressed' | 'rejected' | 'retry', reason: string }} MailTimePolicyDecision
|
|
272
|
-
* @typedef {{ decisions?: MailTimePolicyDecision[] }} MailTimePolicyResult
|
|
273
|
-
* @typedef {{ index: number, name?: string }} MailTimePolicyTransport
|
|
274
|
-
* @typedef {{ from?: string, to: string[] }} MailTimePolicyEnvelope
|
|
275
|
-
* @typedef {{ task: MailTimeTask, attempt: number, transport: MailTimePolicyTransport, envelope: MailTimePolicyEnvelope, recipients: MailTimePolicyRecipient[] }} MailTimePolicyContext
|
|
276
|
-
* @typedef {MailTimePolicyContext} MailTimeBeforeSendPolicyContext
|
|
277
|
-
* @typedef {{ address: string | null, command?: string, responseCode?: number, response?: string, message?: string, transportIndex: number, transportName?: string }} MailTimeStructuredRejection
|
|
278
|
-
* @typedef {MailTimePolicyContext & { error?: unknown, info?: unknown, rejections: MailTimeStructuredRejection[] }} MailTimeRejectionPolicyContext
|
|
279
|
-
* @typedef {{ address: string, status: 'sent' | 'error' | 'suppressed' | 'rejected', sources?: Array<'envelope' | 'to' | 'cc' | 'bcc'>, reasons: Array<{ provider: string, reason: string }>, attempt: number, transportIndex?: number, transportName?: string, command?: string, responseCode?: number, response?: string, message?: string }} MailTimeRecipientResult
|
|
280
|
-
* @typedef {MailTimeRejectionPolicyContext & { decisions: MailTimeRecipientResult[] }} MailTimeRecipientAttemptContext
|
|
281
|
-
* @typedef {{ uuid: string, tries: number, isSettled: boolean, recipients: { sent: MailTimeRecipientResult[], error: MailTimeRecipientResult[], suppressed: MailTimeRecipientResult[], rejected: MailTimeRecipientResult[] } }} MailTimeRecipientSummary
|
|
282
|
-
* @typedef {{ name: string, failureMode?: 'retry' | 'continue', beforeSend?: (context: MailTimeBeforeSendPolicyContext) => void | MailTimePolicyResult | Promise<void | MailTimePolicyResult>, classifyRejections?: (context: MailTimeRejectionPolicyContext) => void | MailTimePolicyResult | Promise<void | MailTimePolicyResult>, observeAttempt?: (context: MailTimeRecipientAttemptContext) => void | Promise<void> }} MailTimeRecipientPolicy
|
|
283
|
-
* @description Policy contexts are read-only by contract. Providers must bound their own I/O; renewal budgets do not limit hook duration.
|
|
284
|
-
*/
|
|
285
|
-
/**
|
|
286
|
-
* @typedef {{ uuid: string, to?: MailTimeMailbox | MailTimeMailbox[], tries: number, sendAt: number, isSent: boolean, isSettled?: boolean, recipientResults?: MailTimeRecipientResult[], isCancelled: boolean, isFailed: boolean, isSending?: boolean, sendingAt?: number, template?: string | false, transport: number, concatSubject?: string | false, mailOptions: MailTimeMailOptions[] }} MailTimeTask
|
|
287
|
-
*/
|
|
288
|
-
/**
|
|
289
|
-
* @typedef {{ limit?: number, sendingTimeout?: number }} MailTimeIterateOptions
|
|
290
|
-
*/
|
|
291
|
-
/**
|
|
292
|
-
* @typedef {{ ping: () => Promise<MailTimePingResult>, iterate: (opts?: MailTimeIterateOptions) => Promise<void> | void, getPendingTo: (to: string, sendAt: number) => Promise<MailTimeTask | object | null>, push: (email: MailTimeTask) => Promise<void> | void, cancel: (uuid: string) => Promise<boolean>, remove: (email: MailTimeTask | object, opts?: { leaseTries: number, leaseSendingAt: number }) => Promise<boolean>, update: (email: MailTimeTask | object, updateObj: object) => Promise<boolean>, ready?: () => Promise<void>, supportsRecipientPolicies?: boolean }} CustomQueue
|
|
293
|
-
*/
|
|
294
|
-
/**
|
|
295
|
-
* @typedef {{ address: string, error: string }} MailTimeRejectedRecipient
|
|
296
|
-
*/
|
|
297
|
-
/**
|
|
298
|
-
* @typedef {{ [key: string]: any, to: MailTimeMailbox | MailTimeMailbox[], cc?: MailTimeMailbox | MailTimeMailbox[], bcc?: MailTimeMailbox | MailTimeMailbox[], sendAt?: Date | number, template?: string, concatSubject?: string, text?: string | false, html?: string | false, subject?: string, accepted?: string[], rejected?: MailTimeRejectedRecipient[] }} MailTimeMailOptions
|
|
299
|
-
*/
|
|
300
|
-
/**
|
|
301
|
-
* @typedef {{ subject?: string }} MailTimeConcatEmailsOptions
|
|
302
|
-
*/
|
|
303
|
-
/**
|
|
304
|
-
* @typedef {{ index: number, from: string | undefined }} MailTimeFromDetails
|
|
305
|
-
*/
|
|
306
|
-
/**
|
|
307
|
-
* @typedef {{ queue: RedisQueue | MongoQueue | PostgresQueue | CustomQueue, type?: 'server' | 'client', from?: string | ((transport: MailTimeTransport, details: MailTimeFromDetails) => string), transports?: MailTimeTransport[], strategy?: 'backup' | 'balancer', failsToNext?: number, shouldFailOver?: (error: unknown, info: object | undefined, email: MailTimeTask) => boolean, retries?: number, maxTries?: number, retryDelay?: number, interval?: number, keepHistory?: boolean, concatEmails?: boolean | MailTimeConcatEmailsOptions, concatSubject?: string, concatDelimiter?: string, concatDelay?: number, concatThrottling?: number, revolvingInterval?: number, mode?: 'one' | 'batch', concurrency?: number, sendingTimeout?: number, renewClaim?: boolean | number, maxRenewals?: number, strictPayload?: boolean, allowedMailFields?: string[], verifyTransports?: boolean, template?: string, prefix?: string, debug?: boolean, josk?: MailTimeJoSkOptions, recipientPolicies?: MailTimeRecipientPolicy[], onError?: (error: unknown, email: MailTimeTask | null, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>, onSent?: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>, onSuppressed?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>, onRejected?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void> }} MailTimeOptions
|
|
308
|
-
*/
|
|
309
252
|
/**
|
|
310
253
|
* Class of MailTime.
|
|
311
254
|
* With recipientPolicies, terminal callbacks receive grouped recipients and a complete summary after persistence.
|
|
@@ -343,7 +286,7 @@ export class MailTime {
|
|
|
343
286
|
template: string;
|
|
344
287
|
keepHistory: boolean;
|
|
345
288
|
onSent: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
346
|
-
onError: (error: unknown, email: MailTimeTask | null, details?:
|
|
289
|
+
onError: (error: unknown, email: MailTimeTask | null, details?: MailTimeErrorDetails, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
347
290
|
onSuppressed: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
348
291
|
onRejected: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
349
292
|
revolvingInterval: number;
|
|
@@ -360,6 +303,7 @@ export class MailTime {
|
|
|
360
303
|
transports: MailTimeTransport[];
|
|
361
304
|
transport: number;
|
|
362
305
|
verifyTransports: boolean;
|
|
306
|
+
verifyTimeout: number;
|
|
363
307
|
from: boolean | ((transport: MailTimeTransport, details: MailTimeFromDetails) => string);
|
|
364
308
|
/** @type {string} */
|
|
365
309
|
concatSubject: string;
|
|
@@ -416,10 +360,10 @@ export class MailTime {
|
|
|
416
360
|
* @async
|
|
417
361
|
* @memberOf MailTime
|
|
418
362
|
* @name drain
|
|
419
|
-
* @description Wait for all in-flight email send attempts to settle
|
|
420
|
-
* @returns {Promise<
|
|
363
|
+
* @description Wait for all in-flight email send attempts to settle. Resolves with `{ failedWrites }`, the count since this instance was created of failures while recording a send outcome: a storage write that threw, an exception in the completion path, or an outcome write lost after a claim-renewal error (message `outcome write lost (renewal outcome uncertain or lease taken over)`, after one retry with the renewal's stamp (no retry when the claim was already stale at renewal time)). Each is also reported once through `onError` with `details.phase` of `'complete'` or `'checkpoint'`, except after a plain `destroy()`, which still counts but suppresses the hook and the log. A row whose write failed can stay `sending` and be re-sent after `sendingTimeout`. Compare `failedWrites` before and after to scope a shutdown.
|
|
364
|
+
* @returns {Promise<MailTimeDrainResult>}
|
|
421
365
|
*/
|
|
422
|
-
drain(): Promise<
|
|
366
|
+
drain(): Promise<MailTimeDrainResult>;
|
|
423
367
|
/**
|
|
424
368
|
* @memberOf MailTime
|
|
425
369
|
* @name pause
|
|
@@ -456,7 +400,7 @@ export class MailTime {
|
|
|
456
400
|
* @description add email to the queue or append to existing letter if {concatEmails: true}
|
|
457
401
|
* @param {MailTimeMailOptions} opts - email options
|
|
458
402
|
* @returns {Promise<string>} uuid of the email
|
|
459
|
-
* @throws {Error}
|
|
403
|
+
* @throws {Error} missing `html`/`text`, a `raw` field, or an invalid `to`; with `recipientPolicies`, an unparseable address rejects with `error.code === 'MAIL_TIME_INVALID_ADDRESS'` and `error.field` naming the field (header recipients are skipped when `envelope.to` is explicit)
|
|
460
404
|
*/
|
|
461
405
|
sendMail(opts: MailTimeMailOptions): Promise<string>;
|
|
462
406
|
/**
|
package/index.d.ts
CHANGED
|
@@ -199,6 +199,18 @@ export type MailTimeFromDetails = {
|
|
|
199
199
|
index: number;
|
|
200
200
|
from: string | undefined;
|
|
201
201
|
};
|
|
202
|
+
export type MailTimeDrainResult = {
|
|
203
|
+
failedWrites: number;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* `details` passed to `onError`. `phase` is `'verify'` (transport verification, `email === null`), `'complete'` (a storage write recording a send outcome), or `'checkpoint'` (recipient-policy results written after SMTP). Without `phase` it is the SMTP `info` of the failed attempt.
|
|
207
|
+
*/
|
|
208
|
+
export type MailTimeErrorDetails = {
|
|
209
|
+
phase?: "verify" | "complete" | "checkpoint";
|
|
210
|
+
transportIndex?: number;
|
|
211
|
+
attempt?: number;
|
|
212
|
+
[key: string]: unknown;
|
|
213
|
+
};
|
|
202
214
|
export type MailTimeOptions = {
|
|
203
215
|
queue: RedisQueue | MongoQueue | PostgresQueue | CustomQueue;
|
|
204
216
|
type?: "server" | "client";
|
|
@@ -226,86 +238,17 @@ export type MailTimeOptions = {
|
|
|
226
238
|
strictPayload?: boolean;
|
|
227
239
|
allowedMailFields?: string[];
|
|
228
240
|
verifyTransports?: boolean;
|
|
241
|
+
verifyTimeout?: number;
|
|
229
242
|
template?: string;
|
|
230
243
|
prefix?: string;
|
|
231
244
|
debug?: boolean;
|
|
232
245
|
josk?: MailTimeJoSkOptions;
|
|
233
246
|
recipientPolicies?: MailTimeRecipientPolicy[];
|
|
234
|
-
onError?: (error: unknown, email: MailTimeTask | null, details?:
|
|
247
|
+
onError?: (error: unknown, email: MailTimeTask | null, details?: MailTimeErrorDetails, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
235
248
|
onSent?: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
236
249
|
onSuppressed?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
237
250
|
onRejected?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
238
251
|
};
|
|
239
|
-
/**
|
|
240
|
-
* @typedef {import('./presets.js').MailTimePresetName} MailTimePresetName
|
|
241
|
-
*/
|
|
242
|
-
/**
|
|
243
|
-
* @typedef {import('./presets.js').MailTimePresetConfig} MailTimePresetConfig
|
|
244
|
-
*/
|
|
245
|
-
/**
|
|
246
|
-
* @typedef {{ status: string, code: number, statusCode: number, paused?: boolean, error?: unknown }} MailTimePingResult
|
|
247
|
-
*/
|
|
248
|
-
/**
|
|
249
|
-
* @typedef {{ [key: string]: any, query?: (queryText: string, values?: unknown[]) => Promise<{ rows?: unknown[], rowCount?: number | null }> }} MailTimeStorageClient
|
|
250
|
-
*/
|
|
251
|
-
/**
|
|
252
|
-
* @typedef {{ [key: string]: any }} MailTimeMongoDb
|
|
253
|
-
*/
|
|
254
|
-
/**
|
|
255
|
-
* @typedef {{ [key: string]: any }} MailTimeTransport
|
|
256
|
-
*/
|
|
257
|
-
/**
|
|
258
|
-
* @typedef {{ [key: string]: any, type?: 'mongo' | 'redis' | 'postgres', client?: MailTimeStorageClient, db?: MailTimeMongoDb, prefix?: string, resetOnInit?: boolean, useHashTags?: boolean }} MailTimeJoSkAdapterOptions
|
|
259
|
-
*/
|
|
260
|
-
/**
|
|
261
|
-
* @typedef {{ [key: string]: any, adapter: MailTimeJoSkAdapterOptions | object, debug?: boolean, autoClear?: boolean, zombieTime?: number, lockLeaseTime?: number, minRevolvingDelay?: number, maxRevolvingDelay?: number, execute?: 'batch' | 'one', concurrency?: number, lockOwnerId?: string, resetOnInit?: boolean, onError?: (title: string, details: object) => void, onExecuted?: (uid: string, details: object) => void }} MailTimeJoSkOptions
|
|
262
|
-
*/
|
|
263
|
-
/**
|
|
264
|
-
* @typedef {{ [key: string]: any, ping: () => Promise<MailTimePingResult>, setInterval: (func: (...args: any[]) => unknown, delay: number, uid: string) => Promise<string>, destroy: () => boolean, shutdown: (opts?: { timeout?: number }) => Promise<boolean>, pause: (timerId?: string) => boolean, resume: (timerId?: string) => boolean }} MailTimeScheduler
|
|
265
|
-
*/
|
|
266
|
-
/**
|
|
267
|
-
* @typedef {string | { address: string, name?: string }} MailTimeMailbox
|
|
268
|
-
*/
|
|
269
|
-
/**
|
|
270
|
-
* @typedef {{ address: string, sources: Array<'envelope' | 'to' | 'cc' | 'bcc'> }} MailTimePolicyRecipient
|
|
271
|
-
* @typedef {{ address: string, status: 'suppressed' | 'rejected' | 'retry', reason: string }} MailTimePolicyDecision
|
|
272
|
-
* @typedef {{ decisions?: MailTimePolicyDecision[] }} MailTimePolicyResult
|
|
273
|
-
* @typedef {{ index: number, name?: string }} MailTimePolicyTransport
|
|
274
|
-
* @typedef {{ from?: string, to: string[] }} MailTimePolicyEnvelope
|
|
275
|
-
* @typedef {{ task: MailTimeTask, attempt: number, transport: MailTimePolicyTransport, envelope: MailTimePolicyEnvelope, recipients: MailTimePolicyRecipient[] }} MailTimePolicyContext
|
|
276
|
-
* @typedef {MailTimePolicyContext} MailTimeBeforeSendPolicyContext
|
|
277
|
-
* @typedef {{ address: string | null, command?: string, responseCode?: number, response?: string, message?: string, transportIndex: number, transportName?: string }} MailTimeStructuredRejection
|
|
278
|
-
* @typedef {MailTimePolicyContext & { error?: unknown, info?: unknown, rejections: MailTimeStructuredRejection[] }} MailTimeRejectionPolicyContext
|
|
279
|
-
* @typedef {{ address: string, status: 'sent' | 'error' | 'suppressed' | 'rejected', sources?: Array<'envelope' | 'to' | 'cc' | 'bcc'>, reasons: Array<{ provider: string, reason: string }>, attempt: number, transportIndex?: number, transportName?: string, command?: string, responseCode?: number, response?: string, message?: string }} MailTimeRecipientResult
|
|
280
|
-
* @typedef {MailTimeRejectionPolicyContext & { decisions: MailTimeRecipientResult[] }} MailTimeRecipientAttemptContext
|
|
281
|
-
* @typedef {{ uuid: string, tries: number, isSettled: boolean, recipients: { sent: MailTimeRecipientResult[], error: MailTimeRecipientResult[], suppressed: MailTimeRecipientResult[], rejected: MailTimeRecipientResult[] } }} MailTimeRecipientSummary
|
|
282
|
-
* @typedef {{ name: string, failureMode?: 'retry' | 'continue', beforeSend?: (context: MailTimeBeforeSendPolicyContext) => void | MailTimePolicyResult | Promise<void | MailTimePolicyResult>, classifyRejections?: (context: MailTimeRejectionPolicyContext) => void | MailTimePolicyResult | Promise<void | MailTimePolicyResult>, observeAttempt?: (context: MailTimeRecipientAttemptContext) => void | Promise<void> }} MailTimeRecipientPolicy
|
|
283
|
-
* @description Policy contexts are read-only by contract. Providers must bound their own I/O; renewal budgets do not limit hook duration.
|
|
284
|
-
*/
|
|
285
|
-
/**
|
|
286
|
-
* @typedef {{ uuid: string, to?: MailTimeMailbox | MailTimeMailbox[], tries: number, sendAt: number, isSent: boolean, isSettled?: boolean, recipientResults?: MailTimeRecipientResult[], isCancelled: boolean, isFailed: boolean, isSending?: boolean, sendingAt?: number, template?: string | false, transport: number, concatSubject?: string | false, mailOptions: MailTimeMailOptions[] }} MailTimeTask
|
|
287
|
-
*/
|
|
288
|
-
/**
|
|
289
|
-
* @typedef {{ limit?: number, sendingTimeout?: number }} MailTimeIterateOptions
|
|
290
|
-
*/
|
|
291
|
-
/**
|
|
292
|
-
* @typedef {{ ping: () => Promise<MailTimePingResult>, iterate: (opts?: MailTimeIterateOptions) => Promise<void> | void, getPendingTo: (to: string, sendAt: number) => Promise<MailTimeTask | object | null>, push: (email: MailTimeTask) => Promise<void> | void, cancel: (uuid: string) => Promise<boolean>, remove: (email: MailTimeTask | object, opts?: { leaseTries: number, leaseSendingAt: number }) => Promise<boolean>, update: (email: MailTimeTask | object, updateObj: object) => Promise<boolean>, ready?: () => Promise<void>, supportsRecipientPolicies?: boolean }} CustomQueue
|
|
293
|
-
*/
|
|
294
|
-
/**
|
|
295
|
-
* @typedef {{ address: string, error: string }} MailTimeRejectedRecipient
|
|
296
|
-
*/
|
|
297
|
-
/**
|
|
298
|
-
* @typedef {{ [key: string]: any, to: MailTimeMailbox | MailTimeMailbox[], cc?: MailTimeMailbox | MailTimeMailbox[], bcc?: MailTimeMailbox | MailTimeMailbox[], sendAt?: Date | number, template?: string, concatSubject?: string, text?: string | false, html?: string | false, subject?: string, accepted?: string[], rejected?: MailTimeRejectedRecipient[] }} MailTimeMailOptions
|
|
299
|
-
*/
|
|
300
|
-
/**
|
|
301
|
-
* @typedef {{ subject?: string }} MailTimeConcatEmailsOptions
|
|
302
|
-
*/
|
|
303
|
-
/**
|
|
304
|
-
* @typedef {{ index: number, from: string | undefined }} MailTimeFromDetails
|
|
305
|
-
*/
|
|
306
|
-
/**
|
|
307
|
-
* @typedef {{ queue: RedisQueue | MongoQueue | PostgresQueue | CustomQueue, type?: 'server' | 'client', from?: string | ((transport: MailTimeTransport, details: MailTimeFromDetails) => string), transports?: MailTimeTransport[], strategy?: 'backup' | 'balancer', failsToNext?: number, shouldFailOver?: (error: unknown, info: object | undefined, email: MailTimeTask) => boolean, retries?: number, maxTries?: number, retryDelay?: number, interval?: number, keepHistory?: boolean, concatEmails?: boolean | MailTimeConcatEmailsOptions, concatSubject?: string, concatDelimiter?: string, concatDelay?: number, concatThrottling?: number, revolvingInterval?: number, mode?: 'one' | 'batch', concurrency?: number, sendingTimeout?: number, renewClaim?: boolean | number, maxRenewals?: number, strictPayload?: boolean, allowedMailFields?: string[], verifyTransports?: boolean, template?: string, prefix?: string, debug?: boolean, josk?: MailTimeJoSkOptions, recipientPolicies?: MailTimeRecipientPolicy[], onError?: (error: unknown, email: MailTimeTask | null, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>, onSent?: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>, onSuppressed?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>, onRejected?: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void> }} MailTimeOptions
|
|
308
|
-
*/
|
|
309
252
|
/**
|
|
310
253
|
* Class of MailTime.
|
|
311
254
|
* With recipientPolicies, terminal callbacks receive grouped recipients and a complete summary after persistence.
|
|
@@ -343,7 +286,7 @@ export class MailTime {
|
|
|
343
286
|
template: string;
|
|
344
287
|
keepHistory: boolean;
|
|
345
288
|
onSent: (email: MailTimeTask, details?: object, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
346
|
-
onError: (error: unknown, email: MailTimeTask | null, details?:
|
|
289
|
+
onError: (error: unknown, email: MailTimeTask | null, details?: MailTimeErrorDetails, recipients?: MailTimeRecipientResult[], summary?: MailTimeRecipientSummary) => void | Promise<void>;
|
|
347
290
|
onSuppressed: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
348
291
|
onRejected: (email: MailTimeTask, recipients: MailTimeRecipientResult[], summary: MailTimeRecipientSummary) => void | Promise<void>;
|
|
349
292
|
revolvingInterval: number;
|
|
@@ -360,6 +303,7 @@ export class MailTime {
|
|
|
360
303
|
transports: MailTimeTransport[];
|
|
361
304
|
transport: number;
|
|
362
305
|
verifyTransports: boolean;
|
|
306
|
+
verifyTimeout: number;
|
|
363
307
|
from: boolean | ((transport: MailTimeTransport, details: MailTimeFromDetails) => string);
|
|
364
308
|
/** @type {string} */
|
|
365
309
|
concatSubject: string;
|
|
@@ -416,10 +360,10 @@ export class MailTime {
|
|
|
416
360
|
* @async
|
|
417
361
|
* @memberOf MailTime
|
|
418
362
|
* @name drain
|
|
419
|
-
* @description Wait for all in-flight email send attempts to settle
|
|
420
|
-
* @returns {Promise<
|
|
363
|
+
* @description Wait for all in-flight email send attempts to settle. Resolves with `{ failedWrites }`, the count since this instance was created of failures while recording a send outcome: a storage write that threw, an exception in the completion path, or an outcome write lost after a claim-renewal error (message `outcome write lost (renewal outcome uncertain or lease taken over)`, after one retry with the renewal's stamp (no retry when the claim was already stale at renewal time)). Each is also reported once through `onError` with `details.phase` of `'complete'` or `'checkpoint'`, except after a plain `destroy()`, which still counts but suppresses the hook and the log. A row whose write failed can stay `sending` and be re-sent after `sendingTimeout`. Compare `failedWrites` before and after to scope a shutdown.
|
|
364
|
+
* @returns {Promise<MailTimeDrainResult>}
|
|
421
365
|
*/
|
|
422
|
-
drain(): Promise<
|
|
366
|
+
drain(): Promise<MailTimeDrainResult>;
|
|
423
367
|
/**
|
|
424
368
|
* @memberOf MailTime
|
|
425
369
|
* @name pause
|
|
@@ -456,7 +400,7 @@ export class MailTime {
|
|
|
456
400
|
* @description add email to the queue or append to existing letter if {concatEmails: true}
|
|
457
401
|
* @param {MailTimeMailOptions} opts - email options
|
|
458
402
|
* @returns {Promise<string>} uuid of the email
|
|
459
|
-
* @throws {Error}
|
|
403
|
+
* @throws {Error} missing `html`/`text`, a `raw` field, or an invalid `to`; with `recipientPolicies`, an unparseable address rejects with `error.code === 'MAIL_TIME_INVALID_ADDRESS'` and `error.field` naming the field (header recipients are skipped when `envelope.to` is explicit)
|
|
460
404
|
*/
|
|
461
405
|
sendMail(opts: MailTimeMailOptions): Promise<string>;
|
|
462
406
|
/**
|