mgc 1.0.0 → 1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mgc",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A cli based tool for generating your saved modules",
5
5
  "author": "Admond Tamang",
6
6
  "license": "MIT",
@@ -25,9 +25,15 @@
25
25
  },
26
26
  "type": "module",
27
27
  "dependencies": {
28
+ "@aws-sdk/client-ses": "^3.398.0",
28
29
  "chalk": "^5.3.0",
29
30
  "commander": "^11.0.0",
30
31
  "dotenv": "^16.3.1",
32
+ "handlebars": "^4.7.8",
33
+ "nodemailer": "^6.9.4",
31
34
  "openai": "^3.3.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/nodemailer": "^6.4.9"
32
38
  }
33
39
  }
package/readme.md CHANGED
@@ -1,3 +1,15 @@
1
+ # Introducation
2
+
3
+ Module Generate Cli (mgc)
4
+
5
+ ## Quick start
6
+
7
+ To generate a module
8
+
9
+ ```
10
+ mgc gen express/email
11
+ ```
12
+
1
13
  ## Inspiration
2
14
 
3
15
  https://github.com/arminbro/generate-react-cli#openai-integration-alpha-release
@@ -0,0 +1,45 @@
1
+ # Email Module
2
+
3
+ ## Required env variables
4
+
5
+ ```
6
+ EMAIL_FROM=""
7
+ AWS_REGION=""
8
+ AWS_ACCESS_KEY_ID=""
9
+ AWS_SECRET_ACCESS_KEY=""
10
+ ```
11
+
12
+ ## Usae
13
+
14
+ - First you have to create a `.hbs` template in `/templates` directory with necessary placeholders i.e. `{{verificationCode}}` or any other name as per your requirement
15
+ - Then in `email.interface.ts` file on `EmailTemplate` type, append the newly created file name, i.e. if you created `forgot-password.hbs`, the new type should be
16
+
17
+ ```ts
18
+ export type EmailTemplate = "welcome" | "verify-email" | 'forgot-password';
19
+ ```
20
+
21
+ - Now use `sendMail` function wherever you require
22
+
23
+ ```ts
24
+ sendMail({
25
+ to: "user@email.com",
26
+ subject: "Email verification",
27
+ template: "verify-email",
28
+ context: {
29
+ verificationCode: "", // populate the placeholder you placed in .hbs file
30
+ },
31
+ });
32
+ ```
33
+
34
+ ## Important Note
35
+ - we have to copy hbs file as it won't happen during ts compilation step thus add this script on your `package.json`
36
+
37
+ ```json
38
+ "copy-hbs": "copyfiles -u 1 src/**/*.hbs dist"
39
+ ```
40
+
41
+ - and modify your build script to
42
+
43
+ ```json
44
+ "build": "tsc && yarn copy-hbs",
45
+ ```
@@ -1,6 +1,6 @@
1
- import { Attachment } from 'nodemailer/lib/mailer';
1
+ import { Attachment } from "nodemailer/lib/mailer";
2
2
 
3
- export interface IEmailInterface {
3
+ export type MailerParams = {
4
4
  from?: string;
5
5
  to: string | Array<string>;
6
6
  subject: string;
@@ -8,6 +8,6 @@ export interface IEmailInterface {
8
8
  attachments?: Attachment[];
9
9
  template?: EmailTemplate;
10
10
  html?: string;
11
- }
11
+ };
12
12
 
13
- export type EmailTemplate = 'welcome' | 'mfa' | 'registration-invite' | 'forgot-password' | 'axp-user-notifications';
13
+ export type EmailTemplate = "welcome" | "verify-email";
@@ -1,19 +1,33 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import handlebars from 'handlebars';
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import nodemailer from "nodemailer";
4
+ import handlebars from "handlebars";
5
+ import * as aws from "@aws-sdk/client-ses";
4
6
 
5
- import { config } from '../../../config';
6
- import { logger } from '../../../lib/logger';
7
- import { nodeMailerTransporter } from '../../../lib/nodemailer';
7
+ import { MailerParams, EmailTemplate } from "./email.interface";
8
8
 
9
- import { IEmailInterface, EmailTemplate } from './email.interface';
9
+ const ses = new aws.SESClient({
10
+ apiVersion: "2010-12-01",
11
+ region: process.env.AWS_REGION,
12
+ credentials: {
13
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
14
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
15
+ },
16
+ });
10
17
 
11
- export const sendMail = (emailData: IEmailInterface) => {
12
- emailData.from = emailData.from || config.email.from;
18
+ const nodeMailerTransporter = nodemailer.createTransport({
19
+ SES: { ses, aws },
20
+ });
21
+
22
+ export function sendMail(emailData: MailerParams) {
23
+ emailData.from = emailData.from || process.env.EMAIL_FROM;
13
24
 
14
25
  // handlebars config
15
26
  if (emailData.template) {
16
- const emailTemplate = fs.readFileSync(path.join(__dirname, `./templates/${emailData.template}.hbs`), 'utf8');
27
+ const emailTemplate = fs.readFileSync(
28
+ path.join(__dirname, `./templates/${emailData.template}.hbs`),
29
+ "utf8"
30
+ );
17
31
  const template = handlebars.compile(emailTemplate);
18
32
  emailData.template = emailTemplate as EmailTemplate;
19
33
  emailData.html = template(emailData.context);
@@ -21,9 +35,11 @@ export const sendMail = (emailData: IEmailInterface) => {
21
35
 
22
36
  nodeMailerTransporter.sendMail(emailData, (err, info) => {
23
37
  if (err) {
24
- throw err;
38
+ console.log(`[EmailService] - Error sending email ${err}`);
25
39
  } else {
26
- logger.info(`[EmailService] - Email sent successfully with response id ${info.response}`);
40
+ console.log(
41
+ `[EmailService] - Email sent successfully with response id ${info.response}`
42
+ );
27
43
  }
28
44
  });
29
- };
45
+ }
@@ -1,16 +1,14 @@
1
- <!DOCTYPE html>
2
1
  <html>
3
2
 
4
- <head>
5
- <meta charset="utf-8">
3
+ <head>
4
+ <meta charset="utf-8" />
6
5
  <title>Example App - Home</title>
7
- </head>
6
+ </head>
8
7
 
9
- <body>
8
+ <body>
10
9
 
11
10
  <p>{{message}}</p>
12
11
 
12
+ </body>
13
13
 
14
- </body>
15
-
16
- </html>
14
+ </html>
@@ -1,52 +0,0 @@
1
- <html lang='en'>
2
-
3
- <head>
4
- <title>{{title}}</title>
5
-
6
- <meta charset='utf-8' />
7
- <meta name='viewport' content='width=device-width, initial-scale=1' />
8
-
9
- <style>
10
- .body { padding-bottom: 82px; font-size: 16px; background-color: rgba(0, 0, 0, 0.04); font-family: Arial,
11
- sans-serif } .header { background-color: #042940; padding: 23px 48px; border-radius: 16px 16px 0px 0px; } .main {
12
- max-width: 635px; margin: 0 auto; padding: 68px 0 51px 0; color: rgba(0, 0, 0, 0.74); line-height: 140%;
13
- letter-spacing: 0.16px; border-radius: 16px; } .content { background-color: #fff; padding: 51px 48px 87px 48px;
14
- border-radius: 0px 0px 16px 16px; } .content-main { margin: 24px 0 68px 0; } .content-main p { margin: 20px 0 0 0;
15
- } .content-main p:first { margin: 0; } .mfa-code { color: #000; font-style: normal; font-weight: 500; } .greeting
16
- { color: #321D36; font-style: normal; font-weight: 500; } .copyright { color: rgba(17, 18, 24, 0.54); text-align:
17
- center; font-size: 13px; font-family: Inter; line-height: 130%; } .salutation { font-family: Verdana, Geneva,
18
- sans-serif; } .action-link { font-size: 14px; font-weight: 500; color: #004C95; line-height: 140%; letter-spacing:
19
- 0.42px; text-decoration: none; } .sub-text { color: rgba(0, 0, 0, 0.54); font-size: 14px; }
20
- </style>
21
- </head>
22
-
23
- <body>
24
- <div class='body'>
25
- <div class='main'>
26
- <div class='header'>
27
- <img src='https://axp-data-dev.s3.us-east-2.amazonaws.com/public-assets/logo.png' alt='AXP Logo' />
28
- </div>
29
-
30
- <div class='content'>
31
- <p class='greeting salutation'>Hello,</p>
32
-
33
- <div class='content-main'>
34
- <p>{{{message}}} Click the link below to view in detail, or perform actions:</p>
35
-
36
- <p><a href='{{dashboardUrl}}' class='action-link'>{{dashboardUrl}}</a></p>
37
-
38
- </div>
39
-
40
- <p>
41
- <div class='greeting'>Regards,</div>
42
- AX Partners Digital Technology Team
43
- </p>
44
-
45
- </div>
46
- </div>
47
-
48
- <div class='copyright'>© AX Partner Corporation 2023</div>
49
- </div>
50
- </body>
51
-
52
- </html>
@@ -1,57 +0,0 @@
1
- <html lang='en'>
2
-
3
- <head>
4
- <title>Password Reset Request</title>
5
-
6
- <meta charset='utf-8' />
7
- <meta name='viewport' content='width=device-width, initial-scale=1' />
8
-
9
- <style>
10
- .body { padding-bottom: 82px; font-size: 16px; background-color: rgba(0, 0, 0, 0.04); font-family: Arial,
11
- sans-serif } .header { background-color: #042940; padding: 23px 48px; border-radius: 16px 16px 0px 0px; } .main {
12
- max-width: 635px; margin: 0 auto; padding: 68px 0 51px 0; color: rgba(0, 0, 0, 0.74); line-height: 140%;
13
- letter-spacing: 0.16px; border-radius: 16px; } .content { background-color: #fff; padding: 51px 48px 87px 48px;
14
- border-radius: 0px 0px 16px 16px; } .content-main { margin: 24px 0 68px 0; } .content-main p { margin: 20px 0 0 0;
15
- } .content-main p:first { margin: 0; } .mfa-code { color: #000; font-style: normal; font-weight: 500; } .greeting
16
- { color: #321D36; font-style: normal; font-weight: 500; } .copyright { color: rgba(17, 18, 24, 0.54); text-align:
17
- center; font-size: 13px; font-family: Inter; line-height: 130%; } .salutation { font-family: Verdana, Geneva,
18
- sans-serif; } .action-link { font-size: 14px; font-weight: 500; color: #004C95; line-height: 140%; letter-spacing:
19
- 0.42px; text-decoration: none; } .sub-text { color: rgba(0, 0, 0, 0.54); font-size: 14px; }
20
- </style>
21
- </head>
22
-
23
- <body>
24
- <div class='body'>
25
- <div class='main'>
26
- <div class='header'>
27
- <img src='https://axp-data-dev.s3.us-east-2.amazonaws.com/public-assets/logo.png' alt='AXP Logo' />
28
- </div>
29
-
30
- <div class='content'>
31
- <p class='greeting salutation'>Dear {{firstName}},</p>
32
-
33
- <div class='content-main'>
34
- <p>You recently requested a password reset for your AX Partner account. Click the link below to set a new
35
- password:</p>
36
-
37
- <p><a href='{{passwordResetUrl}}' class='action-link'>{{passwordResetUrl}}</a></p>
38
- <div class='sub-text'>* This link is valid for a week</div>
39
-
40
- <p>If you didn't make this request, please disregard this email. Your account remains secure.</p>
41
-
42
- <p>If you need further assistance, please contact our support team at [support email/phone number].</p>
43
- </div>
44
-
45
- <p>
46
- <div class='greeting'>Regards,</div>
47
- AX Partners Digital Technology Team
48
- </p>
49
-
50
- </div>
51
- </div>
52
-
53
- <div class='copyright'>© AX Partner Corporation 2023</div>
54
- </div>
55
- </body>
56
-
57
- </html>
@@ -1,64 +0,0 @@
1
- <html lang='en'>
2
-
3
- <head>
4
- <title>Multi Factor Authentication Code</title>
5
-
6
- <meta charset='utf-8' />
7
- <meta name='viewport' content='width=device-width, initial-scale=1' />
8
-
9
- <style>
10
- .body { padding-bottom: 82px; font-size: 16px; background-color: rgba(0, 0, 0, 0.04); font-family: Arial,
11
- sans-serif } .header { background-color: #042940; padding: 23px 48px; border-radius: 16px 16px 0px 0px; } .main {
12
- max-width: 635px; margin: 0 auto; padding: 68px 0 51px 0; color: rgba(0, 0, 0, 0.74); line-height: 140%;
13
- letter-spacing: 0.16px; border-radius: 16px; } .content { background-color: #fff; padding: 51px 48px 87px 48px;
14
- border-radius: 0px 0px 16px 16px; } .content-main { margin: 24px 0 68px 0; } .content-main p { margin: 20px 0 0 0;
15
- } .content-main p:first { margin: 0; } .mfa-code { color: #000; font-style: normal; font-weight: 500; } .greeting
16
- { color: #321D36; font-style: normal; font-weight: 500; } .copyright { color: rgba(17, 18, 24, 0.54); text-align:
17
- center; font-size: 13px; font-family: Inter; line-height: 130%; } .salutation { font-family: Verdana, Geneva,
18
- sans-serif; }
19
- </style>
20
- </head>
21
-
22
- <body>
23
- <div class='body'>
24
- <div class='main'>
25
- <div class='header'>
26
- <img src='https://axp-data-dev.s3.us-east-2.amazonaws.com/public-assets/logo.png' alt='AXP Logo' />
27
- </div>
28
-
29
- <div class='content'>
30
- <p class='greeting salutation'>Dear {{firstName}},</p>
31
-
32
- <div class='content-main'>
33
- <p>To enhance the security of your AX Partner account, we have implemented Multi-Factor Authentication
34
- (MFA). As part of this security measure, you are required to provide a verification code during the login
35
- process. Please find your MFA code below:</p>
36
-
37
- <p class='mfa-code'>MFA Code: {{mfaCode}}</p>
38
-
39
- <p>Please follow the steps below to complete the login process:
40
- <ol>
41
- <li>Visit the AX Partner login page at {{loginUrl}}.</li>
42
- <li>Enter your username and password as usual.</li>
43
- <li>When prompted, enter the provided MFA code {{mfaCode}} in the designated field.</li>
44
- </ol>
45
- </p>
46
-
47
- <p>Please note that the MFA code is time-sensitive and will expire after a certain period. If the code
48
- expires, you can request a new one by clicking on the "Resend Code" option on the login page.</p>
49
- <p>Thank you for your cooperation in keeping your AX Partner account secure.</p>
50
- </div>
51
-
52
- <p>
53
- <div class='greeting'>Regards,</div>
54
- AX Partners Digital Technology Team
55
- </p>
56
-
57
- </div>
58
- </div>
59
-
60
- <div class='copyright'>© AX Partner Corporation 2023</div>
61
- </div>
62
- </body>
63
-
64
- </html>
@@ -1,60 +0,0 @@
1
- <html lang='en'>
2
-
3
- <head>
4
- <title>Register Your Account</title>
5
-
6
- <meta charset='utf-8' />
7
- <meta name='viewport' content='width=device-width, initial-scale=1' />
8
-
9
- <style>
10
- .body { padding-bottom: 82px; font-size: 16px; background-color: rgba(0, 0, 0, 0.04); font-family: Arial,
11
- sans-serif } .header { background-color: #042940; padding: 23px 48px; border-radius: 16px 16px 0px 0px; } .main {
12
- max-width: 635px; margin: 0 auto; padding: 68px 0 51px 0; color: rgba(0, 0, 0, 0.74); line-height: 140%;
13
- letter-spacing: 0.16px; border-radius: 16px; } .content { background-color: #fff; padding: 51px 48px 87px 48px;
14
- border-radius: 0px 0px 16px 16px; } .content-main { margin: 24px 0 68px 0; } .content-main p { margin: 20px 0 0 0;
15
- } .content-main p:first { margin: 0; } .mfa-code { color: #000; font-style: normal; font-weight: 500; } .greeting
16
- { color: #321D36; font-style: normal; font-weight: 500; } .copyright { color: rgba(17, 18, 24, 0.54); text-align:
17
- center; font-size: 13px; font-family: Inter; line-height: 130%; } .salutation { font-family: Verdana, Geneva,
18
- sans-serif; } .action-link { font-size: 14px; font-weight: 500; color: #004C95; line-height: 140%; letter-spacing:
19
- 0.42px; text-decoration: none; } .sub-text { color: rgba(0, 0, 0, 0.54); font-size: 14px; }
20
- </style>
21
- </head>
22
-
23
- <body>
24
- <div class='body'>
25
- <div class='main'>
26
- <div class='header'>
27
- <img src='https://axp-data-dev.s3.us-east-2.amazonaws.com/public-assets/logo.png' alt='AXP Logo' />
28
- </div>
29
-
30
- <div class='content'>
31
- <p class='greeting salutation'>Hello,</p>
32
-
33
- <div class='content-main'>
34
- <p>Thank you for choosing AX Partner as your trusted platform for [specific purpose]. We are excited to have
35
- you join our community of.</p>
36
-
37
- <p>To complete your registration and gain access to our exclusive features and resources, please click on
38
- the following link:
39
- </p>
40
- <p><a href='{{inviteLink}}' class='action-link'>{{inviteLink}}</a></p>
41
- <div class='sub-text'>* This link is valid for a week</div>
42
-
43
- <p>By clicking the link, you will be directed to a secure registration page where you can set up your
44
- account and provide the necessary information.</p>
45
-
46
- </div>
47
-
48
- <p>
49
- <div class='greeting'>Regards,</div>
50
- AX Partners Digital Technology Team
51
- </p>
52
-
53
- </div>
54
- </div>
55
-
56
- <div class='copyright'>© AX Partner Corporation 2023</div>
57
- </div>
58
- </body>
59
-
60
- </html>