@breadstone/archipel-platform-mailing 0.0.20 → 0.0.21
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 -0
- package/package.json +4 -4
- package/src/errors/MailDeliveryError.d.ts +10 -0
- package/src/errors/MailDeliveryError.js +21 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +6 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/services/strategies/MailgunDeliveryStrategy.js +3 -2
- package/src/services/strategies/PostmarkDeliveryStrategy.js +3 -2
- package/src/services/strategies/ResendDeliveryStrategy.js +3 -2
- package/src/services/strategies/SendGridDeliveryStrategy.js +3 -2
- package/src/services/strategies/SmtpDeliveryStrategy.js +3 -2
package/README.md
CHANGED
|
@@ -73,6 +73,30 @@ Set `MAIL_DELIVERY_STRATEGY` to one of: `smtp`, `postmark`, `resend`, `sendgrid`
|
|
|
73
73
|
- **Attachment support**: Send file attachments with MIME-type validation and size limits (25 MB max)
|
|
74
74
|
- **Header injection prevention**: Subject lines are automatically sanitized against SMTP header injection
|
|
75
75
|
|
|
76
|
+
## Error Handling
|
|
77
|
+
|
|
78
|
+
All delivery strategies throw a `MailDeliveryError` when email sending fails. This domain error wraps the underlying provider error and exposes structured metadata:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { MailDeliveryError } from '@breadstone/archipel-platform-mailing';
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
await mailService.send(options, content, true);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error instanceof MailDeliveryError) {
|
|
87
|
+
console.error(error.provider); // 'postmark', 'smtp', 'resend', etc.
|
|
88
|
+
console.error(error.code); // 'MAIL_DELIVERY'
|
|
89
|
+
console.error(error.cause); // Original provider SDK error
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
| Property | Type | Description |
|
|
95
|
+
| ---------- | --------- | ----------------------------------------------- |
|
|
96
|
+
| `code` | `string` | Always `'MAIL_DELIVERY'` |
|
|
97
|
+
| `provider` | `string` | Provider that failed (`smtp`, `postmark`, etc.) |
|
|
98
|
+
| `cause` | `unknown` | Original error from the provider SDK |
|
|
99
|
+
|
|
76
100
|
## Available Providers
|
|
77
101
|
|
|
78
102
|
| Subpath | Class | SDK |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@breadstone/archipel-platform-mailing",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"description": "Email delivery with strategy-based transport and template engines for NestJS applications.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"README.md"
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@breadstone/archipel-platform-blob-storage": "0.0.
|
|
79
|
-
"@breadstone/archipel-platform-configuration": "0.0.
|
|
80
|
-
"@breadstone/archipel-platform-core": "0.0.
|
|
78
|
+
"@breadstone/archipel-platform-blob-storage": "0.0.21",
|
|
79
|
+
"@breadstone/archipel-platform-configuration": "0.0.21",
|
|
80
|
+
"@breadstone/archipel-platform-core": "0.0.21",
|
|
81
81
|
"form-data": "4.0.5",
|
|
82
82
|
"nodemailer": "8.0.5",
|
|
83
83
|
"tslib": "2.8.1"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain error thrown when email delivery fails.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare class MailDeliveryError extends Error {
|
|
7
|
+
readonly code = "MAIL_DELIVERY";
|
|
8
|
+
readonly provider: string;
|
|
9
|
+
constructor(provider: string, message: string, cause?: unknown);
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MailDeliveryError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Domain error thrown when email delivery fails.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
class MailDeliveryError extends Error {
|
|
10
|
+
// #endregion
|
|
11
|
+
// #region Ctor
|
|
12
|
+
constructor(provider, message, cause) {
|
|
13
|
+
super(message, { cause });
|
|
14
|
+
// #region Fields
|
|
15
|
+
this.code = 'MAIL_DELIVERY';
|
|
16
|
+
this.name = 'MailDeliveryError';
|
|
17
|
+
this.provider = provider;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.MailDeliveryError = MailDeliveryError;
|
|
21
|
+
//# sourceMappingURL=MailDeliveryError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MailDeliveryError } from './MailDeliveryError';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MailDeliveryError = void 0;
|
|
4
|
+
var MailDeliveryError_1 = require("./MailDeliveryError");
|
|
5
|
+
Object.defineProperty(exports, "MailDeliveryError", { enumerable: true, get: function () { return MailDeliveryError_1.MailDeliveryError; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./env"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./errors/MailDeliveryError"), exports);
|
|
5
6
|
tslib_1.__exportStar(require("./events"), exports);
|
|
6
7
|
tslib_1.__exportStar(require("./MailModule"), exports);
|
|
7
8
|
tslib_1.__exportStar(require("./MailTokens"), exports);
|
|
@@ -7,6 +7,7 @@ const common_1 = require("@nestjs/common");
|
|
|
7
7
|
const form_data_1 = tslib_1.__importDefault(require("form-data"));
|
|
8
8
|
const mailgun_js_1 = tslib_1.__importDefault(require("mailgun.js"));
|
|
9
9
|
const env_1 = require("../../env");
|
|
10
|
+
const MailDeliveryError_1 = require("../../errors/MailDeliveryError");
|
|
10
11
|
const DeliveryStrategyBase_1 = require("./abstracts/DeliveryStrategyBase");
|
|
11
12
|
// #endregion
|
|
12
13
|
/**
|
|
@@ -54,14 +55,14 @@ class MailgunDeliveryStrategy extends DeliveryStrategyBase_1.DeliveryStrategyBas
|
|
|
54
55
|
...(isHtml ? { html: content } : { text: content }),
|
|
55
56
|
});
|
|
56
57
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
57
|
-
setTimeout(() => reject(new Error('Mailgun send timed out after
|
|
58
|
+
setTimeout(() => reject(new Error('Mailgun send timed out after 5000ms')), 5_000);
|
|
58
59
|
});
|
|
59
60
|
await Promise.race([sendPromise, timeoutPromise]);
|
|
60
61
|
this._logger.log('Email sent successfully', 'Mail');
|
|
61
62
|
}
|
|
62
63
|
catch (error) {
|
|
63
64
|
this._logger.error('Error sending email:', error);
|
|
64
|
-
throw error;
|
|
65
|
+
throw new MailDeliveryError_1.MailDeliveryError('mailgun', 'Failed to send email via Mailgun', error);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -5,6 +5,7 @@ exports.PostmarkDeliveryStrategy = void 0;
|
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
6
|
const postmark_1 = require("postmark");
|
|
7
7
|
const env_1 = require("../../env");
|
|
8
|
+
const MailDeliveryError_1 = require("../../errors/MailDeliveryError");
|
|
8
9
|
const DeliveryStrategyBase_1 = require("./abstracts/DeliveryStrategyBase");
|
|
9
10
|
// #endregion
|
|
10
11
|
/**
|
|
@@ -47,14 +48,14 @@ class PostmarkDeliveryStrategy extends DeliveryStrategyBase_1.DeliveryStrategyBa
|
|
|
47
48
|
...(isHtml ? { HtmlBody: content } : { TextBody: content }),
|
|
48
49
|
});
|
|
49
50
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
50
|
-
setTimeout(() => reject(new Error('Postmark send timed out after
|
|
51
|
+
setTimeout(() => reject(new Error('Postmark send timed out after 5000ms')), 5_000);
|
|
51
52
|
});
|
|
52
53
|
await Promise.race([sendPromise, timeoutPromise]);
|
|
53
54
|
this._logger.log('Email sent successfully', 'Mail');
|
|
54
55
|
}
|
|
55
56
|
catch (error) {
|
|
56
57
|
this._logger.error('Error sending email:', error);
|
|
57
|
-
throw error;
|
|
58
|
+
throw new MailDeliveryError_1.MailDeliveryError('postmark', 'Failed to send email via Postmark', error);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
}
|
|
@@ -5,6 +5,7 @@ exports.ResendDeliveryStrategy = void 0;
|
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
6
|
const resend_1 = require("resend");
|
|
7
7
|
const env_1 = require("../../env");
|
|
8
|
+
const MailDeliveryError_1 = require("../../errors/MailDeliveryError");
|
|
8
9
|
const DeliveryStrategyBase_1 = require("./abstracts/DeliveryStrategyBase");
|
|
9
10
|
// #endregion
|
|
10
11
|
/**
|
|
@@ -47,14 +48,14 @@ class ResendDeliveryStrategy extends DeliveryStrategyBase_1.DeliveryStrategyBase
|
|
|
47
48
|
...(isHtml ? { html: content } : { text: content }),
|
|
48
49
|
});
|
|
49
50
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
50
|
-
setTimeout(() => reject(new Error('Resend send timed out after
|
|
51
|
+
setTimeout(() => reject(new Error('Resend send timed out after 5000ms')), 5_000);
|
|
51
52
|
});
|
|
52
53
|
await Promise.race([sendPromise, timeoutPromise]);
|
|
53
54
|
this._logger.log('Email sent successfully', 'Mail');
|
|
54
55
|
}
|
|
55
56
|
catch (error) {
|
|
56
57
|
this._logger.error('Error sending email:', error);
|
|
57
|
-
throw error;
|
|
58
|
+
throw new MailDeliveryError_1.MailDeliveryError('resend', 'Failed to send email via Resend', error);
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
}
|
|
@@ -6,6 +6,7 @@ const tslib_1 = require("tslib");
|
|
|
6
6
|
const common_1 = require("@nestjs/common");
|
|
7
7
|
const mail_1 = tslib_1.__importDefault(require("@sendgrid/mail"));
|
|
8
8
|
const env_1 = require("../../env");
|
|
9
|
+
const MailDeliveryError_1 = require("../../errors/MailDeliveryError");
|
|
9
10
|
const DeliveryStrategyBase_1 = require("./abstracts/DeliveryStrategyBase");
|
|
10
11
|
// #endregion
|
|
11
12
|
/**
|
|
@@ -48,14 +49,14 @@ class SendGridDeliveryStrategy extends DeliveryStrategyBase_1.DeliveryStrategyBa
|
|
|
48
49
|
...(isHtml ? { html: content } : { text: content }),
|
|
49
50
|
});
|
|
50
51
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
51
|
-
setTimeout(() => reject(new Error('SendGrid send timed out after
|
|
52
|
+
setTimeout(() => reject(new Error('SendGrid send timed out after 5000ms')), 5_000);
|
|
52
53
|
});
|
|
53
54
|
await Promise.race([sendPromise, timeoutPromise]);
|
|
54
55
|
this._logger.log('Email sent successfully', 'Mail');
|
|
55
56
|
}
|
|
56
57
|
catch (error) {
|
|
57
58
|
this._logger.error('Error sending email:', error);
|
|
58
|
-
throw error;
|
|
59
|
+
throw new MailDeliveryError_1.MailDeliveryError('sendgrid', 'Failed to send email via SendGrid', error);
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -5,6 +5,7 @@ exports.SmtpDeliveryStrategy = void 0;
|
|
|
5
5
|
const common_1 = require("@nestjs/common");
|
|
6
6
|
const nodemailer_1 = require("nodemailer");
|
|
7
7
|
const env_1 = require("../../env");
|
|
8
|
+
const MailDeliveryError_1 = require("../../errors/MailDeliveryError");
|
|
8
9
|
const DeliveryStrategyBase_1 = require("./abstracts/DeliveryStrategyBase");
|
|
9
10
|
// #endregion
|
|
10
11
|
/**
|
|
@@ -56,14 +57,14 @@ class SmtpDeliveryStrategy extends DeliveryStrategyBase_1.DeliveryStrategyBase {
|
|
|
56
57
|
...(isHtml ? { html: content } : { text: content }),
|
|
57
58
|
});
|
|
58
59
|
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
59
|
-
setTimeout(() => reject(new Error('SMTP send timed out after
|
|
60
|
+
setTimeout(() => reject(new Error('SMTP send timed out after 5000ms')), 5_000);
|
|
60
61
|
});
|
|
61
62
|
await Promise.race([sendPromise, timeoutPromise]);
|
|
62
63
|
this._logger.log('Email sent successfully', 'Mail');
|
|
63
64
|
}
|
|
64
65
|
catch (error) {
|
|
65
66
|
this._logger.error('Error sending email:', error);
|
|
66
|
-
throw error;
|
|
67
|
+
throw new MailDeliveryError_1.MailDeliveryError('smtp', 'Failed to send email via SMTP', error);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
}
|