mikromail 0.0.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 ADDED
@@ -0,0 +1,99 @@
1
+ # MikroMail
2
+
3
+ **Lightweight replacement for Nodemailer, supporting HTML, international symbols, and more**.
4
+
5
+ ![Build Status](https://github.com/mikaelvesavuori/mikromail/workflows/main/badge.svg)
6
+
7
+ ---
8
+
9
+ - Tiny (~X.X KB gzipped)
10
+ - Zero dependencies
11
+ - High test coverage
12
+
13
+ ## Usage
14
+
15
+ ### Basic importing and usage
16
+
17
+ ```typescript
18
+ import { MikroMail } from 'MikroMail';
19
+
20
+ const config = {
21
+ user: 'me@mydomain.com',
22
+ password: 'YOUR_PASSWORD_HERE',
23
+ host: 'smtp.email-provider.com'
24
+ };
25
+
26
+ const emailOptions = {
27
+ from: 'me@mydomain.com',
28
+ subject: 'Test Email',
29
+ text: 'Hello!',
30
+ to: 'you@yourdomain.com'
31
+ };
32
+
33
+ await new MikroMail({ config }).send(emailOptions);
34
+ ```
35
+
36
+ ### Bigger example
37
+
38
+ ```typescript
39
+ import { MikroMail } from 'MikroMail';
40
+
41
+ const sender = 'this-is-me@somewhere-over-the-rainbow.cloud';
42
+
43
+ const config = {
44
+ // Required
45
+ user: sender,
46
+ password: 'YOUR_PASSWORD_HERE',
47
+ host: 'smtp.your-provider.net',
48
+ // Optional - defaults shown
49
+ port: 465,
50
+ secure: true,
51
+ debug: false,
52
+ maxRetries: 2
53
+ };
54
+
55
+ const emailOptions = {
56
+ // Required
57
+ from: sender,
58
+ subject: 'Test Email',
59
+ text: 'Hello, this is a test email! Hallå, MikroMail has international support for, among others, español, français, português, 中文, 日本語, and Русский!',
60
+ to: 'sam.person@somewhere-over-the-rainbow.cloud',
61
+ // Optional
62
+ cc: ['dat.person@somewhere-over-the-rainbow.cloud'],
63
+ bcc: ['hoo.person@somewhere-over-the-rainbow.cloud'],
64
+ html: `
65
+ <html>
66
+ <head>
67
+ <meta charset="utf-8">
68
+ <style>
69
+ body { font-family: Arial, sans-serif; color: #333; }
70
+ .highlight { color: #0066cc; font-weight: bold; }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <h1>Hello, this is a test email!</h1>
75
+ <p>Hallå, MikroMail has <span class="highlight">international support</span> for, among others, español, français, português, 中文, 日本語, and Русский!</p>
76
+ <p>It also supports <b>HTML formatting</b> and <i>styling</i>.</p>
77
+ </body>
78
+ </html>
79
+ `,
80
+ headers: {
81
+ 'X-Priority': '1',
82
+ 'X-Custom-Header': 'Custom Value'
83
+ }
84
+ };
85
+
86
+ await new MikroMail({ config }).send(emailOptions);
87
+ ```
88
+
89
+ ## Testing
90
+
91
+ Some of the tests require faking an SMTP server. Here we use [Mailpit](https://github.com/axllent/mailpit), which will run a server on `http://localhost:8025`.
92
+
93
+ - On a Mac, install Mailpit with `brew install mailpit` (assuming you have Homebrew)
94
+ - Run Mailpit with `brew services start mailpit`
95
+ - Stop Mailpit with `brew services stop mailpit`
96
+
97
+ ## License
98
+
99
+ MIT
@@ -0,0 +1,41 @@
1
+ import { ConfigurationOptions, SMTPConfiguration } from './interfaces/index.mjs';
2
+
3
+ /**
4
+ * @description Configuration class that handles both CLI arguments and config file settings
5
+ */
6
+ declare class Configuration {
7
+ private readonly config;
8
+ private readonly defaults;
9
+ /**
10
+ * @description Creates a new Configuration instance
11
+ * @param configFilePath Path to the configuration file (e.g., 'mikromail.config.json')
12
+ * @param args Command line arguments array from process.argv
13
+ */
14
+ constructor(options?: ConfigurationOptions);
15
+ /**
16
+ * @description Creates a configuration object by merging defaults, config file settings,
17
+ * and CLI arguments (in order of increasing precedence)
18
+ * @param configFilePath Path to the configuration file
19
+ * @param args Command line arguments array
20
+ * @returns The merged configuration object
21
+ */
22
+ private create;
23
+ /**
24
+ * @description Parses command line arguments into a configuration object
25
+ * @param args Command line arguments array
26
+ * @returns Parsed CLI configuration
27
+ */
28
+ private parseCliArgs;
29
+ /**
30
+ * @description Validates the configuration
31
+ * @throws Error if the configuration is invalid
32
+ */
33
+ private validate;
34
+ /**
35
+ * @description Returns the complete configuration
36
+ * @returns The configuration object
37
+ */
38
+ get(): SMTPConfiguration;
39
+ }
40
+
41
+ export { Configuration };
@@ -0,0 +1,41 @@
1
+ import { ConfigurationOptions, SMTPConfiguration } from './interfaces/index.js';
2
+
3
+ /**
4
+ * @description Configuration class that handles both CLI arguments and config file settings
5
+ */
6
+ declare class Configuration {
7
+ private readonly config;
8
+ private readonly defaults;
9
+ /**
10
+ * @description Creates a new Configuration instance
11
+ * @param configFilePath Path to the configuration file (e.g., 'mikromail.config.json')
12
+ * @param args Command line arguments array from process.argv
13
+ */
14
+ constructor(options?: ConfigurationOptions);
15
+ /**
16
+ * @description Creates a configuration object by merging defaults, config file settings,
17
+ * and CLI arguments (in order of increasing precedence)
18
+ * @param configFilePath Path to the configuration file
19
+ * @param args Command line arguments array
20
+ * @returns The merged configuration object
21
+ */
22
+ private create;
23
+ /**
24
+ * @description Parses command line arguments into a configuration object
25
+ * @param args Command line arguments array
26
+ * @returns Parsed CLI configuration
27
+ */
28
+ private parseCliArgs;
29
+ /**
30
+ * @description Validates the configuration
31
+ * @throws Error if the configuration is invalid
32
+ */
33
+ private validate;
34
+ /**
35
+ * @description Returns the complete configuration
36
+ * @returns The configuration object
37
+ */
38
+ get(): SMTPConfiguration;
39
+ }
40
+
41
+ export { Configuration };
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/Configuration.ts
21
+ var Configuration_exports = {};
22
+ __export(Configuration_exports, {
23
+ Configuration: () => Configuration
24
+ });
25
+ module.exports = __toCommonJS(Configuration_exports);
26
+ var import_node_fs = require("fs");
27
+
28
+ // src/errors/index.ts
29
+ var ValidationError = class extends Error {
30
+ constructor(message) {
31
+ super();
32
+ this.name = "ValidationError";
33
+ this.message = message;
34
+ this.cause = { statusCode: 400 };
35
+ }
36
+ };
37
+
38
+ // src/Configuration.ts
39
+ var Configuration = class {
40
+ config;
41
+ defaults = {
42
+ configFilePath: "mikromail.config.json",
43
+ args: []
44
+ };
45
+ /**
46
+ * @description Creates a new Configuration instance
47
+ * @param configFilePath Path to the configuration file (e.g., 'mikromail.config.json')
48
+ * @param args Command line arguments array from process.argv
49
+ */
50
+ constructor(options) {
51
+ const configuration = options?.config || {};
52
+ const configFilePath = options?.configFilePath || this.defaults.configFilePath;
53
+ const args = options?.args || this.defaults.args;
54
+ this.config = this.create(configFilePath, args, configuration);
55
+ }
56
+ /**
57
+ * @description Creates a configuration object by merging defaults, config file settings,
58
+ * and CLI arguments (in order of increasing precedence)
59
+ * @param configFilePath Path to the configuration file
60
+ * @param args Command line arguments array
61
+ * @returns The merged configuration object
62
+ */
63
+ create(configFilePath, args, configuration) {
64
+ const defaults = {
65
+ host: "",
66
+ user: "",
67
+ password: "",
68
+ port: 465,
69
+ secure: true,
70
+ debug: false,
71
+ maxRetries: 2
72
+ };
73
+ let fileConfig = {};
74
+ if ((0, import_node_fs.existsSync)(configFilePath)) {
75
+ try {
76
+ const fileContent = (0, import_node_fs.readFileSync)(configFilePath, "utf8");
77
+ fileConfig = JSON.parse(fileContent);
78
+ console.log(`Loaded configuration from ${configFilePath}`);
79
+ } catch (error) {
80
+ console.error(
81
+ `Error reading config file: ${error instanceof Error ? error.message : String(error)}`
82
+ );
83
+ }
84
+ }
85
+ const cliConfig = this.parseCliArgs(args);
86
+ return {
87
+ ...defaults,
88
+ ...configuration,
89
+ ...fileConfig,
90
+ ...cliConfig
91
+ };
92
+ }
93
+ /**
94
+ * @description Parses command line arguments into a configuration object
95
+ * @param args Command line arguments array
96
+ * @returns Parsed CLI configuration
97
+ */
98
+ parseCliArgs(args) {
99
+ const cliConfig = {};
100
+ for (let i = 2; i < args.length; i++) {
101
+ const arg = args[i];
102
+ switch (arg) {
103
+ case "--host":
104
+ if (i + 1 < args.length) cliConfig.host = args[++i];
105
+ break;
106
+ case "--user":
107
+ if (i + 1 < args.length) cliConfig.user = args[++i];
108
+ break;
109
+ case "--password":
110
+ if (i + 1 < args.length) cliConfig.password = args[++i];
111
+ break;
112
+ case "--port":
113
+ if (i + 1 < args.length) {
114
+ const value = Number.parseInt(args[++i], 10);
115
+ if (!Number.isNaN(value)) cliConfig.port = value;
116
+ }
117
+ break;
118
+ case "--secure":
119
+ cliConfig.secure = true;
120
+ break;
121
+ case "--debug":
122
+ cliConfig.debug = true;
123
+ break;
124
+ case "--retries":
125
+ if (i + 1 < args.length) {
126
+ const value = Number.parseInt(args[++i], 10);
127
+ if (!Number.isNaN(value)) cliConfig.maxRetries = value;
128
+ }
129
+ break;
130
+ }
131
+ }
132
+ return cliConfig;
133
+ }
134
+ /**
135
+ * @description Validates the configuration
136
+ * @throws Error if the configuration is invalid
137
+ */
138
+ validate() {
139
+ if (!this.config.host) throw new ValidationError("Host value not found");
140
+ }
141
+ /**
142
+ * @description Returns the complete configuration
143
+ * @returns The configuration object
144
+ */
145
+ get() {
146
+ this.validate();
147
+ return this.config;
148
+ }
149
+ };
150
+ // Annotate the CommonJS export names for ESM import in node:
151
+ 0 && (module.exports = {
152
+ Configuration
153
+ });
@@ -0,0 +1,7 @@
1
+ import {
2
+ Configuration
3
+ } from "./chunk-V2NYOKWA.mjs";
4
+ import "./chunk-47VXJTWV.mjs";
5
+ export {
6
+ Configuration
7
+ };
@@ -0,0 +1,30 @@
1
+ import { ConfigurationOptions, EmailOptions } from './interfaces/index.mjs';
2
+
3
+ /**
4
+ * @description Lightweight replacement for Nodemailer, supporting HTML, international symbols, and more.
5
+ * @example
6
+ * const config = {
7
+ * user: 'me@mydomain.com',
8
+ * password: 'YOUR_PASSWORD_HERE',
9
+ * host: 'smtp.email-provider.com'
10
+ * };
11
+ *
12
+ * const emailOptions = {
13
+ * from: 'me@mydomain.com',
14
+ * subject: 'Test Email',
15
+ * text: 'Hello!',
16
+ * to: 'you@yourdomain.com'
17
+ * };
18
+ *
19
+ * await new MikroMail({ config }).send(emailOptions);
20
+ */
21
+ declare class MikroMail {
22
+ private readonly smtpClient;
23
+ constructor(options?: ConfigurationOptions);
24
+ /**
25
+ * Sends an email to valid domains.
26
+ */
27
+ send(emailOptions: EmailOptions): Promise<void>;
28
+ }
29
+
30
+ export { MikroMail };
@@ -0,0 +1,30 @@
1
+ import { ConfigurationOptions, EmailOptions } from './interfaces/index.js';
2
+
3
+ /**
4
+ * @description Lightweight replacement for Nodemailer, supporting HTML, international symbols, and more.
5
+ * @example
6
+ * const config = {
7
+ * user: 'me@mydomain.com',
8
+ * password: 'YOUR_PASSWORD_HERE',
9
+ * host: 'smtp.email-provider.com'
10
+ * };
11
+ *
12
+ * const emailOptions = {
13
+ * from: 'me@mydomain.com',
14
+ * subject: 'Test Email',
15
+ * text: 'Hello!',
16
+ * to: 'you@yourdomain.com'
17
+ * };
18
+ *
19
+ * await new MikroMail({ config }).send(emailOptions);
20
+ */
21
+ declare class MikroMail {
22
+ private readonly smtpClient;
23
+ constructor(options?: ConfigurationOptions);
24
+ /**
25
+ * Sends an email to valid domains.
26
+ */
27
+ send(emailOptions: EmailOptions): Promise<void>;
28
+ }
29
+
30
+ export { MikroMail };