@lobb-js/lobb-ext-mail 0.1.40 → 0.2.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/.dockerignore +7 -0
- package/.env.example +10 -0
- package/.vscode/settings.json +5 -0
- package/CHANGELOG.md +83 -0
- package/README.md +1 -27
- package/extensions/mail/extensionConfigSchema.ts +14 -0
- package/extensions/mail/index.ts +19 -0
- package/extensions/mail/tests/configs/mail.ts +50 -0
- package/extensions/mail/tests/mail.test.ts +43 -0
- package/extensions/mail/tests/smtpServer.ts +60 -0
- package/lobb.ts +48 -0
- package/package.json +16 -24
package/.dockerignore
ADDED
package/.env.example
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines.
|
|
3
|
+
|
|
4
|
+
- - -
|
|
5
|
+
## mail-ext@0.2.1 - 2026-03-28
|
|
6
|
+
#### Bug Fixes
|
|
7
|
+
- adding readme to all packages - (3a9264a) - malik ben
|
|
8
|
+
#### Miscellaneous Chores
|
|
9
|
+
- add publishConfig and fix ext packages for npm publishing - (49747e9) - malik ben
|
|
10
|
+
|
|
11
|
+
- - -
|
|
12
|
+
|
|
13
|
+
## mail-ext@0.2.0 - 2026-03-28
|
|
14
|
+
#### Features
|
|
15
|
+
- (**mail-ext**) migrate to Bun - (20552c0) - malik ben
|
|
16
|
+
#### Bug Fixes
|
|
17
|
+
- (**studio**) prevent @lobb-js/studio version shadowing in extensions - (cd674b9) - malik ben
|
|
18
|
+
- chaning $lib to relative path - (c6d9e8f) - malik ben
|
|
19
|
+
- adding a studio prefix for the studio app - (6607b5a) - malik ben
|
|
20
|
+
#### Miscellaneous Chores
|
|
21
|
+
- (**mail-ext**) move extension logic and tests to extensions/mail - (529b0dc) - malik ben
|
|
22
|
+
- (**version**) 0.25.2 - (a62acb9) - Cocogitto Bot
|
|
23
|
+
- (**version**) 0.25.1 - (afe7e69) - Cocogitto Bot
|
|
24
|
+
- (**version**) 0.25.0 - (77a383c) - Cocogitto Bot
|
|
25
|
+
- (**version**) 0.24.0 - (a8cb605) - Cocogitto Bot
|
|
26
|
+
- (**version**) 0.23.0 - (60f357e) - Cocogitto Bot
|
|
27
|
+
- (**version**) 0.22.0 - (6510e32) - Cocogitto Bot
|
|
28
|
+
- (**version**) 0.21.0 - (c973aa9) - Cocogitto Bot
|
|
29
|
+
- (**version**) 0.20.0 - (06cc303) - Cocogitto Bot
|
|
30
|
+
- (**version**) 0.19.0 - (6bbc900) - Cocogitto Bot
|
|
31
|
+
- (**version**) 0.18.0 - (efc553f) - Cocogitto Bot
|
|
32
|
+
- (**version**) 0.17.0 - (4174f0c) - Cocogitto Bot
|
|
33
|
+
- (**version**) 0.16.0 - (9508655) - Cocogitto Bot
|
|
34
|
+
- (**version**) 0.15.0 - (0c2c345) - Cocogitto Bot
|
|
35
|
+
- (**version**) 0.14.11 - (ad92b61) - Cocogitto Bot
|
|
36
|
+
- (**version**) 0.14.8 - (0e6c1cb) - Cocogitto Bot
|
|
37
|
+
- (**version**) 0.14.5 - (59ea38d) - Cocogitto Bot
|
|
38
|
+
- (**version**) 0.14.3 - (76abe92) - Cocogitto Bot
|
|
39
|
+
- (**version**) 0.14.2 - (6ecdc1d) - Cocogitto Bot
|
|
40
|
+
- add dev:studio/build:studio scripts, fix Dockerfiles, remove --build flag - (1595975) - malik ben
|
|
41
|
+
- rename @lobb/ scope to @lobb-js/ across all packages and apps - (cce4ce0) - malik ben
|
|
42
|
+
- update CLAUDE.md to enforce no-commit-without-explicit-instruction rule - (6d63a42) - malik ben
|
|
43
|
+
- remove all deno.json and deno.lock files from the monorepo - (84ca5d4) - malik ben
|
|
44
|
+
- replace workspace:* with exact versions in all package.json files - (74fbdb7) - malik ben
|
|
45
|
+
- rename __studio to studio and remove unused studio dirs - (77fb932) - malik ben
|
|
46
|
+
- rename studio directory to __studio for faker-ext, llm-ext, mail-ext, reports-ext, storage-ext - (47e754a) - malik ben
|
|
47
|
+
- bump deno docker image to 2.6.6 across all Dockerfiles - (a2865b4) - malik ben
|
|
48
|
+
- fixing the /studio base issue - (de6686f) - Malik Najjar
|
|
49
|
+
|
|
50
|
+
- - -
|
|
51
|
+
|
|
52
|
+
## mail-ext@0.1.36 - 2026-02-21
|
|
53
|
+
#### Bug Fixes
|
|
54
|
+
- using default export instead of named export for extensions - (37dd485) - malik ben
|
|
55
|
+
#### Miscellaneous Chores
|
|
56
|
+
- (**version**) 0.13.2 - (39b0145) - Cocogitto Bot
|
|
57
|
+
- (**version**) 0.12.3 - (cd06fc0) - Cocogitto Bot
|
|
58
|
+
- (**version**) 0.12.2 - (35b2ff3) - Cocogitto Bot
|
|
59
|
+
- (**version**) 0.12.1 - (c548105) - Cocogitto Bot
|
|
60
|
+
- (**version**) 0.11.1 - (659ebd3) - Cocogitto Bot
|
|
61
|
+
- (**version**) 0.11.0 - (3f4f47e) - Cocogitto Bot
|
|
62
|
+
- (**version**) 0.10.0 - (5d79b6e) - Cocogitto Bot
|
|
63
|
+
- (**version**) 0.8.0 - (fdee7ca) - Cocogitto Bot
|
|
64
|
+
|
|
65
|
+
- - -
|
|
66
|
+
|
|
67
|
+
## mail-ext@0.1.35 - 2026-02-15
|
|
68
|
+
#### Bug Fixes
|
|
69
|
+
- fix deno publish issue - (e8dcc4f) - malik ben
|
|
70
|
+
- issue fix - (63d66d3) - malik ben
|
|
71
|
+
#### Miscellaneous Chores
|
|
72
|
+
- (**version**) 0.5.5 - (d4dedeb) - Cocogitto Bot
|
|
73
|
+
- (**version**) 0.5.4 - (1ca3970) - Cocogitto Bot
|
|
74
|
+
- (**version**) 0.5.3 - (dcdb9cb) - Cocogitto Bot
|
|
75
|
+
- (**version**) 0.5.2 - (aa66e29) - Cocogitto Bot
|
|
76
|
+
- (**version**) 0.5.1 - (41b7c35) - Cocogitto Bot
|
|
77
|
+
- (**version**) 0.5.0 - (af63147) - Cocogitto Bot
|
|
78
|
+
- (**version**) 0.4.4 - (eaed3b4) - Cocogitto Bot
|
|
79
|
+
- (**version**) 0.4.3 - (ea9ec49) - Cocogitto Bot
|
|
80
|
+
|
|
81
|
+
- - -
|
|
82
|
+
|
|
83
|
+
Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto).
|
package/README.md
CHANGED
|
@@ -1,27 +1 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
This directory contains the frontend/dashboard interface for the mail extension.
|
|
4
|
-
|
|
5
|
-
## Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
studio/
|
|
9
|
-
├── src/
|
|
10
|
-
│ ├── index.ts # Extension entry point
|
|
11
|
-
│ ├── main.ts # Vite app entry
|
|
12
|
-
│ └── pages/ # UI pages (to be added)
|
|
13
|
-
├── public/ # Static assets
|
|
14
|
-
├── index.html # HTML entry point
|
|
15
|
-
├── vite.config.ts # Vite configuration
|
|
16
|
-
├── tailwind.config.ts # Tailwind CSS configuration
|
|
17
|
-
└── tsconfig.json # TypeScript configuration
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Future Features
|
|
21
|
-
|
|
22
|
-
The studio interface could include:
|
|
23
|
-
- SMTP server configuration UI
|
|
24
|
-
- Email template management
|
|
25
|
-
- Test email sender
|
|
26
|
-
- Email logs and monitoring
|
|
27
|
-
- Mail queue management
|
|
1
|
+
# @lobb-js/lobb-ext-mail
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Extension, Lobb } from "@lobb-js/core";
|
|
2
|
+
import type { ExtensionConfig } from "./extensionConfigSchema.ts";
|
|
3
|
+
import nodemailer from "nodemailer";
|
|
4
|
+
import type { SendMailOptions } from "nodemailer";
|
|
5
|
+
|
|
6
|
+
export function mail(extensionConfig: ExtensionConfig): Extension {
|
|
7
|
+
let transporter: ReturnType<typeof nodemailer.createTransport>;
|
|
8
|
+
return {
|
|
9
|
+
name: "mail",
|
|
10
|
+
init: async (lobb: Lobb) => {
|
|
11
|
+
transporter = nodemailer.createTransport(extensionConfig.transporter);
|
|
12
|
+
},
|
|
13
|
+
services: (_lobb: Lobb) => ({
|
|
14
|
+
sendMail: async (messageOptions: SendMailOptions): Promise<any> => {
|
|
15
|
+
return await transporter.sendMail(messageOptions);
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Config } from "@lobb-js/core";
|
|
2
|
+
import { mail } from "../../index.ts";
|
|
3
|
+
|
|
4
|
+
export const mailConfig: Config = {
|
|
5
|
+
project: {
|
|
6
|
+
name: "MyApp",
|
|
7
|
+
force_sync: true,
|
|
8
|
+
support_email: "support@myapp.com",
|
|
9
|
+
},
|
|
10
|
+
database: {
|
|
11
|
+
host: "localhost",
|
|
12
|
+
port: 5432,
|
|
13
|
+
username: "test",
|
|
14
|
+
password: "test",
|
|
15
|
+
database: "*",
|
|
16
|
+
},
|
|
17
|
+
web_server: {
|
|
18
|
+
host: "0.0.0.0",
|
|
19
|
+
port: 0,
|
|
20
|
+
},
|
|
21
|
+
extensions: [
|
|
22
|
+
mail({
|
|
23
|
+
transporter: {
|
|
24
|
+
host: "127.0.0.1",
|
|
25
|
+
port: 2525,
|
|
26
|
+
secure: false,
|
|
27
|
+
ignoreTLS: true,
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
collections: {
|
|
32
|
+
articles: {
|
|
33
|
+
indexes: {},
|
|
34
|
+
fields: {
|
|
35
|
+
id: { type: "integer" },
|
|
36
|
+
title: {
|
|
37
|
+
type: "string",
|
|
38
|
+
length: 255,
|
|
39
|
+
},
|
|
40
|
+
body: {
|
|
41
|
+
type: "string",
|
|
42
|
+
length: 255,
|
|
43
|
+
},
|
|
44
|
+
published: { type: "bool" },
|
|
45
|
+
number_of_likes: { type: "integer" },
|
|
46
|
+
user_id: { type: "integer" },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Lobb } from "@lobb-js/core";
|
|
2
|
+
import { expect } from "bun:test";
|
|
3
|
+
import { SmtpServer } from "./smtpServer.ts";
|
|
4
|
+
import { afterAll, beforeAll, describe, it } from "bun:test";
|
|
5
|
+
import { mailConfig } from "./configs/mail.ts";
|
|
6
|
+
|
|
7
|
+
describe("Mail Operations", () => {
|
|
8
|
+
let lobb: Lobb;
|
|
9
|
+
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
await SmtpServer.init();
|
|
12
|
+
lobb = await Lobb.init(mailConfig);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterAll(async () => {
|
|
16
|
+
await lobb.close();
|
|
17
|
+
await SmtpServer.close();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("mail should be sent successfully", async () => {
|
|
21
|
+
const extension = lobb.configManager.getExtension("mail");
|
|
22
|
+
|
|
23
|
+
if (!extension) {
|
|
24
|
+
throw new Error("Couldn't find the mail extension");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const services = extension.services!(lobb) as { sendMail: Function };
|
|
28
|
+
|
|
29
|
+
// sending the mail to the smtp server
|
|
30
|
+
await services.sendMail({
|
|
31
|
+
from: "sender@example.com",
|
|
32
|
+
to: "recipient@example.com",
|
|
33
|
+
subject: "Test email",
|
|
34
|
+
text: "test email from the unit tests",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// getting the mail message from the smtp server
|
|
38
|
+
const receivedMail = SmtpServer.getReceivedMail();
|
|
39
|
+
|
|
40
|
+
expect(receivedMail.subject).toBe("Test email");
|
|
41
|
+
expect(receivedMail.text).toBe("test email from the unit tests\n");
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SMTPServer } from "smtp-server";
|
|
2
|
+
import { simpleParser } from "mailparser";
|
|
3
|
+
|
|
4
|
+
function sleep(ms: number) {
|
|
5
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class SmtpServer {
|
|
9
|
+
private static server: SMTPServer | null = null;
|
|
10
|
+
public static receivedMail: any;
|
|
11
|
+
|
|
12
|
+
static init(): Promise<void> {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
this.server = new SMTPServer({
|
|
15
|
+
authOptional: true,
|
|
16
|
+
closeTimeout: 100,
|
|
17
|
+
onData(stream: any, session: any, callback: any) {
|
|
18
|
+
simpleParser(stream, {}, (err: any, parsed: any) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
console.error("Error parsing email:", err);
|
|
21
|
+
return callback(err); // Call callback with error if parsing fails
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Store the received mail
|
|
25
|
+
SmtpServer.receivedMail = parsed;
|
|
26
|
+
|
|
27
|
+
// Call the callback to signal that the data has been processed
|
|
28
|
+
callback(null, "Message accepted"); // Accept the message
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
this.server.listen(2525, (err: any) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
return reject(err);
|
|
36
|
+
}
|
|
37
|
+
console.log("Mail server listening on port 2525");
|
|
38
|
+
resolve();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static getReceivedMail() {
|
|
44
|
+
return this.receivedMail;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static async close(): Promise<void> {
|
|
48
|
+
await sleep(0);
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
this.server.close((err: any) => {
|
|
51
|
+
if (err) {
|
|
52
|
+
return reject(err);
|
|
53
|
+
}
|
|
54
|
+
this.receivedMail = null;
|
|
55
|
+
this.server = null;
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
package/lobb.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Lobb } from "@lobb-js/core";
|
|
2
|
+
import { mail } from "./extensions/mail/index.ts";
|
|
3
|
+
|
|
4
|
+
Lobb.init({
|
|
5
|
+
project: {
|
|
6
|
+
name: "Mail Extension Test",
|
|
7
|
+
force_sync: true,
|
|
8
|
+
},
|
|
9
|
+
database: {
|
|
10
|
+
host: "localhost",
|
|
11
|
+
port: 5432,
|
|
12
|
+
username: "test",
|
|
13
|
+
password: "test",
|
|
14
|
+
database: "mail_ext_dev",
|
|
15
|
+
},
|
|
16
|
+
web_server: {
|
|
17
|
+
host: "0.0.0.0",
|
|
18
|
+
port: 3000,
|
|
19
|
+
cors: {
|
|
20
|
+
origin: "*",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
extensions: [
|
|
24
|
+
mail({
|
|
25
|
+
transporter: {
|
|
26
|
+
host: "localhost",
|
|
27
|
+
port: 587,
|
|
28
|
+
secure: false,
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
collections: {
|
|
33
|
+
articles: {
|
|
34
|
+
indexes: {},
|
|
35
|
+
fields: {
|
|
36
|
+
id: { type: "integer" },
|
|
37
|
+
title: {
|
|
38
|
+
type: "string",
|
|
39
|
+
length: 255,
|
|
40
|
+
},
|
|
41
|
+
body: {
|
|
42
|
+
type: "string",
|
|
43
|
+
length: 255,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
});
|
package/package.json
CHANGED
|
@@ -1,37 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobb-js/lobb-ext-mail",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"license": "AGPL-3.0-only",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"publishConfig": {
|
|
6
7
|
"access": "public"
|
|
7
8
|
},
|
|
8
|
-
"files": [
|
|
9
|
-
"studio"
|
|
10
|
-
],
|
|
11
9
|
"exports": {
|
|
12
|
-
".": "./
|
|
10
|
+
".": "./extensions/mail/index.ts"
|
|
13
11
|
},
|
|
14
12
|
"scripts": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
13
|
+
"test": "bun run test:lobb",
|
|
14
|
+
"test:lobb": "bun test extensions/mail/tests",
|
|
15
|
+
"dev": "bun run lobb.ts"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@lobb-js/core": "0.13.1",
|
|
19
|
+
"nodemailer": "^6.9.0"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
23
|
-
"@
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"clsx": "^2.1.1",
|
|
28
|
-
"svelte": "^5.49.1",
|
|
29
|
-
"svelte-check": "^4.3.4",
|
|
30
|
-
"tailwind-merge": "^3.4.0",
|
|
31
|
-
"tailwind-variants": "^3.2.2",
|
|
32
|
-
"tailwindcss": "4.1.18",
|
|
33
|
-
"tw-animate-css": "^1.4.0",
|
|
34
|
-
"typescript": "~5.9.3",
|
|
35
|
-
"vite": "6.3.3"
|
|
22
|
+
"@types/nodemailer": "^6.4.0",
|
|
23
|
+
"@types/smtp-server": "^3.5.10",
|
|
24
|
+
"@types/mailparser": "^3.4.0",
|
|
25
|
+
"bun-types": "latest",
|
|
26
|
+
"mailparser": "^3.7.1",
|
|
27
|
+
"smtp-server": "^3.13.5"
|
|
36
28
|
}
|
|
37
29
|
}
|