add email service

This commit is contained in:
Emily
2025-01-27 15:12:22 +01:00
parent 65c682c75d
commit 510bc2545a
23 changed files with 3128 additions and 54 deletions

View File

@@ -16,6 +16,7 @@ export const PREMIUM_TAGS = [
'APPSUMO_INCUBATION',
'APPSUMO_ACCELERATION',
'APPSUMO_GROWTH',
'APPSUMO_UNICORN'
] as const;
@@ -149,6 +150,14 @@ export const PREMIUM_PLAN: Record<PREMIUM_TAG, PREMIUM_DATA> = {
PRICE_TEST: '',
COST: 0
},
APPSUMO_UNICORN: {
ID: 6006,
COUNT_LIMIT: 5_000_000,
AI_MESSAGE_LIMIT: 20_000,
PRICE: 'price_1Qls1lB2lPUiVs9VI6ej8hwE',
PRICE_TEST: '',
COST: 0
}
}
export function getPlanFromTag(tag: PREMIUM_TAG) {

View File

@@ -29,7 +29,7 @@ const VisitSchema = new Schema<TVisit>({
continent: { type: String },
country: { type: String },
session: { type: String },
session: { type: String, index: true },
flowHash: { type: String },
device: { type: String },

3
email/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules
dist
ecosystem.config.js

15
email/package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "email",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"compile": "tsc"
},
"keywords": [],
"author": "Emily",
"license": "MIT",
"devDependencies": {
"typescript": "^5.7.3"
}
}

24
email/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,24 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
typescript:
specifier: ^5.7.3
version: 5.7.3
packages:
typescript@5.7.3:
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
engines: {node: '>=14.17'}
hasBin: true
snapshots:
typescript@5.7.3: {}

3
email/src/index.ts Normal file
View File

@@ -0,0 +1,3 @@
import { start } from "./services/server";
start();

182
email/src/services/email.ts Normal file
View File

@@ -0,0 +1,182 @@
import { TransactionalEmailsApi, SendSmtpEmail } from '@getbrevo/brevo';
import * as TEMPLATE from './templates'
export class EmailService {
private static apiInstance = new TransactionalEmailsApi();
static init(apiKey: string) {
this.apiInstance.setApiKey(0, apiKey);
}
static async sendLimitEmail50(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "⚡ You've reached 50% limit on Litlyx";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.LIMIT_50_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendLimitEmail90(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "⚡ You've reached 90% limit on Litlyx";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.LIMIT_90_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendLimitEmailMax(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "🚨 You've reached your limit on Litlyx!";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.LIMIT_MAX_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendWelcomeEmail(target: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Welcome to Litlyx!";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.WELCOME_EMAIL;
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendPurchaseEmail(target: string, projectName: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Thank You for Upgrading Your Litlyx Plan!";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.PURCHASE_EMAIL
.replace(/\[Project Name\]/, projectName)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendAnomalyVisitsEventsEmail(target: string, projectName: string,
data: {
visits: { _id: string, count: number }[],
events: { _id: string, count: number }[]
}) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "🔍 Unexpected Activity Detected by our AI";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.ANOMALY_VISITS_EVENTS_EMAIL
.replace(/\[Project Name\]/, projectName)
.replace(/\[ENTRIES\]/,
[
...data.visits.map(e => (`<li> Visits in date ${new Date(e._id).toLocaleDateString('en-EN')} [ ${e.count} ] </li>`)),
...data.events.map(e => (`<li> Events in date ${new Date(e._id).toLocaleDateString('en-EN')} [ ${e.count} ] </li>`))
]
.join('')
)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendAnomalyDomainEmail(target: string, projectName: string, domains: string[]) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "🔍 Suspicious dns detected by our AI";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "help@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.ANOMALY_DOMAIN_EMAIL
.replace(/\[Project Name\]/, projectName)
.replace(/\[CURRENT_DATE\]/, new Date().toLocaleDateString('en-EN'))
// .replace(/\[DNS_ENTRIES\]/,
// domains.map(e => (`<li> ${e} </li>`)).join('<br>')
.replace(/\[DNS_ENTRIES\]/, domains[0])
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendConfirmEmail(target: string, link: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Confirm your email";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.CONFIRM_EMAIL
.replace(/\[CONFIRM_LINK\]/, link)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
static async sendResetPasswordEmail(target: string, newPassword: string) {
try {
const sendSmtpEmail = new SendSmtpEmail();
sendSmtpEmail.subject = "Password reset";
sendSmtpEmail.sender = { "name": "Litlyx", "email": "no-reply@litlyx.com" };
sendSmtpEmail.to = [{ "email": target }];
sendSmtpEmail.htmlContent = TEMPLATE.RESET_PASSWORD_EMAIL
.replace(/\[NEW_PASSWORD\]/, newPassword)
.toString();
await this.apiInstance.sendTransacEmail(sendSmtpEmail);
return true;
} catch (ex) {
console.error('ERROR SENDING EMAIL', ex);
return false;
}
}
}

View File

@@ -0,0 +1,134 @@
import express from 'express';
import cors from 'cors';
import { EmailService } from './email';
const TOKEN = process.env.TOKEN;
if (!TOKEN || TOKEN.length == 0) {
console.log('TOKEN not set');
process.exit();
}
const PORT = process.env.PORT;
if (!PORT || PORT.length == 0) {
console.log('PORT not set');
process.exit();
}
const BREVO_API_KEY = process.env.BREVO_API_KEY;
if (!BREVO_API_KEY || BREVO_API_KEY.length == 0) {
console.log('BREVO_API_KEY not set');
process.exit();
}
EmailService.init(BREVO_API_KEY);
const app = express();
app.use(cors());
app.use((req, res, next) => {
const token = req.header('x-litlyx-token');
if (token != TOKEN) {
res.status(403).json({ error: 'token not valid' });
return;
}
console.log(req.path, req.body);
next();
});
app.post('/send/confirm', express.json(), async (req, res) => {
try {
const { target, link } = req.body;
const ok = await EmailService.sendConfirmEmail(target, link);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/welcome', express.json(), async (req, res) => {
try {
const { target } = req.body;
const ok = await EmailService.sendWelcomeEmail(target);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/purchase', express.json(), async (req, res) => {
try {
const { target, projectName } = req.body;
const ok = await EmailService.sendPurchaseEmail(target, projectName);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/reset_password', express.json(), async (req, res) => {
try {
const { target, newPassword } = req.body;
const ok = await EmailService.sendResetPasswordEmail(target, newPassword);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/anomaly/domain', express.json(), async (req, res) => {
try {
const { target, projectName, domains } = req.body;
const ok = await EmailService.sendAnomalyDomainEmail(target, projectName, domains);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/anomaly/visits_events', express.json(), async (req, res) => {
try {
const { target, projectName, data } = req.body;
const ok = await EmailService.sendAnomalyVisitsEventsEmail(target, projectName, data);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/limit/50', express.json(), async (req, res) => {
try {
const { target, projectName } = req.body;
const ok = await EmailService.sendLimitEmail50(target, projectName);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/limit/90', express.json(), async (req, res) => {
try {
const { target, projectName } = req.body;
const ok = await EmailService.sendLimitEmail90(target, projectName);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
app.post('/send/limit/max', express.json(), async (req, res) => {
try {
const { target, projectName } = req.body;
const ok = await EmailService.sendLimitEmailMax(target, projectName);
res.json({ ok });
} catch (ex) {
res.status(500).json({ error: ex.message });
}
});
export function start() {
const server = app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
return { app, server };
}

View File

@@ -0,0 +1,23 @@
import { WELCOME_EMAIL } from '../../templates/WelcomeEmail';
import { LIMIT_50_EMAIL } from '../../templates/Limit50Email';
import { LIMIT_90_EMAIL } from '../../templates/Limit90Email';
import { LIMIT_MAX_EMAIL } from '../../templates/LimitMaxEmail';
import { PURCHASE_EMAIL } from '../../templates/PurchaseEmail';
import { ANOMALY_VISITS_EVENTS_EMAIL } from '../../templates/AnomalyUsageEmail';
import { ANOMALY_DOMAIN_EMAIL } from '../../templates/AnomalyDomainEmail';
import { CONFIRM_EMAIL } from '../../templates/ConfirmEmail';
import { RESET_PASSWORD_EMAIL } from '../../templates/ResetPasswordEmail';
export {
WELCOME_EMAIL,
LIMIT_50_EMAIL,
LIMIT_90_EMAIL,
LIMIT_MAX_EMAIL,
PURCHASE_EMAIL,
ANOMALY_VISITS_EVENTS_EMAIL,
ANOMALY_DOMAIN_EMAIL,
CONFIRM_EMAIL,
RESET_PASSWORD_EMAIL
}

View File

@@ -0,0 +1,159 @@
export const ANOMALY_DOMAIN_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:37.5em">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="border:1px solid rgb(0,0,0, 0.1);border-radius:3px;overflow:hidden">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<img src="https://litlyx.com/images/locker2.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-bottom:0">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column">
<h1 style="font-size:32px;font-weight:bold;text-align:center">
Dear user
</h1>
<h2 style="font-size:26px;font-weight:bold;text-align:center">
Our AI Agent noticed a recent Anomaly on your project on Litlyx.
</h2>
<p style="font-size:16px;line-height:24px;margin:16px 0">
<b>Time: </b> [CURRENT_DATE]
<!-- September 7, 2022 at 10:58 AM -->
</p>
<p
style="font-size:16px;line-height:24px;margin:16px 0;margin-top:-5px">
<b>Project: </b> [Project Name]
</p>
<p
style="font-size:16px;line-height:24px;margin:16px 0;margin-top:-5px">
<b>Suspicious DNS: </b> [DNS_ENTRIES]
</p>
<p style="font-size:16px;line-height:24px;margin:16px 0">
If this was you, there&#x27;s nothing else you
need to do.
</p>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-top:0">
<tbody style="width:100%">
<tr style="width:100%">
<td colspan="2" data-id="__react-email-column"
style="display:flex;justify-content:center;width:100%">
<a style="line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#FFF;font-weight:bold;border:1px solid rgb(0,0,0, 0.1);cursor:pointer;padding:12px 30px 12px 30px"
target="_blank" href="https://dashboard.litlyx.com"><span></span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px">
Go to Dashboard</span><span></span></a>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-bottom:0">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column">
<h3>If this wasn't you..</h3>
<p>you should reach out to the webmasters of
the websites that have duplicated your content and request them
to remove it or give you proper attribution (if available).</p>
<p>You can also use <a href="https://www.whois.com/whois/"
style="color: #D32F2F; text-decoration: none;">https://www.whois.com/whois/</a>
to get the contact details of the webmaster or domain owner.</p>
<p>If webmasters don't respond or cooperate, <strong>you can file a
DMCA complaint here:</strong> <a
href="https://support.google.com/legal/answer/3110420?hl=en"
style="color: #D32F2F; text-decoration: none;">https://support.google.com/legal/answer/3110420?hl=en</a>
<strong>with Google to request the removal of the duplicate
content from their search results.</strong></p>
<h3>Please refer to this for more information:</h3>
<ul>
<li><a href="https://support.google.com/legal/answer/3110420?hl=en&sjid=14235884554806745995-AP&authuser=2"
style="color: #D32F2F; text-decoration: none;">Report
Content for Legal Reasons</a></li>
<li><a href="https://www.dmca.com/FAQ/How-can-I-get-a-webpage-removed-from-Google-search-results"
style="color: #D32F2F; text-decoration: none;">How can I
get a webpage removed from Google search results?</a>
</li>
</ul>
<p>Your safety is our main priority.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool!
</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding:45px 0 0 0">
<tbody>
<tr>
<td>
<img src="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/yelp-footer.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</td>
</tr>
</tbody>
</table>
<p style="font-size:12px;line-height:24px;margin:16px 0;text-align:center;color:rgb(0,0,0, 0.7)">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA: 17814721001- REA: RM-1743194
</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>
`

View File

@@ -0,0 +1,152 @@
export const ANOMALY_VISITS_EVENTS_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:37.5em">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="border:1px solid rgb(0,0,0, 0.1);border-radius:3px;overflow:hidden">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<img src="https://litlyx.com/images/locker2.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-bottom:0">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column">
<h1 style="font-size:32px;font-weight:bold;text-align:center">
Dear user
</h1>
<h2 style="font-size:26px;font-weight:bold;text-align:center">
Our AI Agent noticed a recent unexpected usage on your project
on Litlyx.
</h2>
<p
style="font-size:16px;line-height:24px;margin:16px 0;margin-top:-5px">
<b>Project: </b> [Project Name]
</p>
<p
style="font-size:16px;line-height:24px;margin:16px 0;margin-top:-5px">
<b>Info: </b> [ENTRIES]
</p>
<p>If this spike in activity is expected, theres no need to worry.
However, if you believe this could be unexpected or suspicious,
we recommend taking a closer look at your data on the
<strong>Litlyx Dashboard</strong>. You can analyze your recent
traffic and event logs to identify any irregularities or
potential issues.</p>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-top:0">
<tbody style="width:100%">
<tr style="width:100%">
<td colspan="2" data-id="__react-email-column"
style="display:flex;justify-content:center;width:100%">
<a style="line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#FFF;font-weight:bold;border:1px solid rgb(0,0,0, 0.1);cursor:pointer;padding:12px 30px 12px 30px"
target="_blank"
href="https://dashboard.litlyx.com"><span></span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px">
Go to Dashboard</span><span></span></a>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-bottom:0">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column">
<h3>What can I do?</h3>
<p>To better understand the situation, you can:</p>
<ol>
<li>Review your traffic sources to see where the visits or
events are coming from.</li>
<li>Check for any unexpected patterns, such as a high number of
visits from unknown sources or abnormal event triggers.</li>
<li>Check your code to find bugs on a specific action that is
triggered in loops.</li>
</ol>
<p>If you need help understanding this activity or have any
concerns, feel free to reach out to our support team at <a
href="mailto:help@litlyx.com"
style="color: #D32F2F; text-decoration: none;"><strong>help@litlyx.com</strong></a>.
We are here to assist you!</p>
<p><strong>Your safety and data integrity are our top
priorities.</strong></p>
<p>Thank you for trusting Litlyx as your analytics tool!</p>
<p>Best regards,</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding:45px 0 0 0">
<tbody>
<tr>
<td>
<img src="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/yelp-footer.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</td>
</tr>
</tbody>
</table>
<p style="font-size:12px;line-height:24px;margin:16px 0;text-align:center;color:rgb(0,0,0, 0.7)">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA: 17814721001- REA: RM-1743194
</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>
`

View File

@@ -0,0 +1,69 @@
export const CONFIRM_EMAIL = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Email Confirmation</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}
.container {
background-color: #ffffff;
padding: 20px;
max-width: 600px;
margin: 0 auto;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #333333;
}
p {
color: #555555;
line-height: 1.5;
}
.button {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: #ffffff;
text-decoration: none;
border-radius: 5px;
}
.footer {
margin-top: 20px;
font-size: 12px;
color: #777777;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h2>Confirm your email on Litlyx</h2>
<p>Hello,</p>
<p>Thank you so much for signing up on Litlyx! Please confirm your email address by clicking the button below:
</p>
<p><a href="[CONFIRM_LINK]" class="button">Confirm Email</a></p>
<p>If you didn't create an account with us, you can safely ignore this email.</p>
<p>We hope to hear from you soon!</p>
<div class="footer">
<p>&copy; 2024 Litlyx. All rights reserved.</p>
</div>
</div>
</body>
</html>`

View File

@@ -0,0 +1,116 @@
export const LIMIT_50_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<link rel="preload" as="image" href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-logo.png" />
<link rel="preload" as="image"
href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-review-user.jpg" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#ffffff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:100%;margin:0 auto;padding:20px 0 48px;width:580px">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<img alt="Founder" height="96"
src="https://litlyx.com/images/founder.jpg"
style="display:block;outline:none;border:none;text-decoration:none;margin:0 auto;margin-bottom:16px;border-radius:50%"
width="96" />
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding-bottom:20px">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:32px;line-height:1.3;margin:16px 0;font-weight:700;color:#484848">
Youve Reached 50% of Your Litlyx Project Limit on [Project Name]
</p>
<p
style="font-size:18px;line-height:1.4;margin:16px 0;color:#484848;padding:24px;background-color:#f2f3f3;border-radius:4px">
To avoid losing precious data, please remember to monitor your usage
on the <strong>Litlyx Dashboard</strong>. You can find your current
usage details under <strong>Settings > Billing Tab</strong>
</p>
<p>If you need more data collection storage, you may consider upgrading
your plan to get additional benefits and ensure uninterrupted data
collection.</p>
<p>Feel free to reply to this email or contact us at <a
href="mailto:help@litlyx.com"
style="color: #FF5733; text-decoration: none;">help@litlyx.com</a>
if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
<a href="https://dashboard.litlyx.com/"
style="line-height:100%;text-decoration:none;display:block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#fff;font-size:18px;padding-top:19px;padding-bottom:19px;text-align:center;width:100%;padding:19px 0px 19px 0px"
target="_blank"><span>
</span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:14.25px">Go to Dashboard</span><span></span></a>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<hr
style="width:100%;border:none;border-top:1px solid #eaeaea;border-color:#cccccc;margin:20px 0" />
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:14px;line-height:24px;margin:16px 0;color:#9ca299;margin-bottom:10px">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA:
17814721001- REA: RM-1743194
</p>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--/$-->
</body>
</html>
`

View File

@@ -0,0 +1,117 @@
export const LIMIT_90_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<link rel="preload" as="image" href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-logo.png" />
<link rel="preload" as="image"
href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-review-user.jpg" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#ffffff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:100%;margin:0 auto;padding:20px 0 48px;width:580px">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<img alt="Founder" height="96"
src="https://litlyx.com/images/founder.jpg"
style="display:block;outline:none;border:none;text-decoration:none;margin:0 auto;margin-bottom:16px;border-radius:50%"
width="96" />
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding-bottom:20px">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:32px;line-height:1.3;margin:16px 0;font-weight:700;color:#484848">
Youve Reached 90% of Your Litlyx Project Limit on [Project Name]
</p>
<p
style="font-size:18px;line-height:1.4;margin:16px 0;color:#484848;padding:24px;background-color:#f2f3f3;border-radius:4px">
To avoid losing precious data, please remember to monitor your usage
on the <strong>Litlyx Dashboard</strong>. You can find your current
usage details under <strong>Settings > Billing Tab</strong>
</p>
<p>If you need more data collection storage, you may consider upgrading
your plan to get additional benefits and ensure uninterrupted data
collection.</p>
<p>Feel free to reply to this email or contact us at <a
href="mailto:help@litlyx.com"
style="color: #FF5733; text-decoration: none;">help@litlyx.com</a>
if you have any questions or need assistance.</p>
<p>Thank you for choosing Litlyx every day as your analytics tool.</p>
<p>Have a nice day!</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
<a href="https://dashboard.litlyx.com/"
style="line-height:100%;text-decoration:none;display:block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#fff;font-size:18px;padding-top:19px;padding-bottom:19px;text-align:center;width:100%;padding:19px 0px 19px 0px"
target="_blank"><span>
</span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:14.25px">Go to Dashboard</span><span></span></a>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<hr
style="width:100%;border:none;border-top:1px solid #eaeaea;border-color:#cccccc;margin:20px 0" />
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:14px;line-height:24px;margin:16px 0;color:#9ca299;margin-bottom:10px">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA:
17814721001- REA: RM-1743194
</p>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--/$-->
</body>
</html>
`

View File

@@ -0,0 +1,138 @@
export const LIMIT_MAX_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<link rel="preload" as="image" href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-logo.png" />
<link rel="preload" as="image"
href="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/airbnb-review-user.jpg" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#ffffff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:100%;margin:0 auto;padding:20px 0 48px;width:580px">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<img alt="Founder" height="96"
src="https://litlyx.com/images/founder.jpg"
style="display:block;outline:none;border:none;text-decoration:none;margin:0 auto;margin-bottom:16px;border-radius:50%"
width="96" />
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding-bottom:20px">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:32px;line-height:1.3;margin:16px 0;font-weight:700;color:#484848">
Youve Reached Your Litlyx Project Limit on [Project Name]
</p>
<p
style="font-size:18px;line-height:1.4;margin:16px 0;color:#484848;padding:24px;background-color:#ffbb03;border-radius:4px">
We noticed that Litlyx has stopped collecting data for your project.
</p>
<p>
To help you avoid losing valuable insights, we recommend keeping an
eye on your usage via the Litlyx Dashboard.
</p>
<p>
You can view your current usage details under Settings > Billing
Tab.
</p>
<p>
If you need additional storage for data collection, consider
upgrading your plan to unlock more benefits and ensure uninterrupted
service.
</p>
<p style="font-weight: 700;">
As a token of appreciation, we're offering you 25% off for life at
checkout with the code LIT25.
</p>
Thank you for choosing Litlyx as your trusted analytics tool.
<p></p>
<p>
If you have any questions or need assistance, feel free to reply to
this email or contact us at <a href="mailto:help@litlyx.com"
style="color: #FF5733; text-decoration: none;">help@litlyx.com</a>
</p>
<p>
Have a great day!
</p>
<p>
Antonio
CEO | Litlyx
</p>
<a href="https://dashboard.litlyx.com/"
style="line-height:100%;text-decoration:none;display:block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#fff;font-size:18px;padding-top:19px;padding-bottom:19px;text-align:center;width:100%;padding:19px 0px 19px 0px"
target="_blank"><span>
</span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:14.25px">Go
to Dashboard</span><span></span></a>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<hr
style="width:100%;border:none;border-top:1px solid #eaeaea;border-color:#cccccc;margin:20px 0" />
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<p
style="font-size:14px;line-height:24px;margin:16px 0;color:#9ca299;margin-bottom:10px">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA:
17814721001- REA: RM-1743194
</p>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--/$-->
</body>
</html>
`

View File

@@ -0,0 +1,45 @@
export const PURCHASE_EMAIL = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank You for Upgrading Your Litlyx Plan!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<!-- Email Content -->
<p>Dear User,</p>
<p>We are thrilled to inform you that <strong>[Project Name]</strong> on <strong>Litlyx</strong> has successfully been upgraded to a higher plan! Thank you for choosing to elevate your experience with us and for believing in our project.</p>
<p>We appreciate your trust in Litlyx and are committed to providing you with the best analytics experience. Your support helps us to continually improve our platform and bring new features to make your analytics journey even better.</p>
<p>You can find your current plan details and download your invoices under <strong>Settings > Billing Tab</strong>.</p>
<h3>What does this mean for you?</h3>
<p>With your upgraded plan, you can now enjoy more data collection, advanced features, and additional benefits to enhance your data analysis capabilities:</p>
<ol>
<li>Access to more storage and increased data limits.</li>
<li>Advanced analytics tools like IP-Company Matching, download CSV for your raw data, AI insights, and more.</li>
<li>Priority support to help you make the most of your Litlyx experience on Slack or Discord!</li>
</ol>
<p>If you have any questions about your new plan or need assistance, feel free to reach out to our support team at <a href="mailto:help@litlyx.com" style="color: #28a745; text-decoration: none;"><strong>help@litlyx.com</strong></a>. Were here to help you make the most out of your upgraded plan!</p>
<p><strong>Thank you for using Litlyx every day as your analytics tool and for being a part of our journey.</strong></p>
<p>We look forward to continuing to support your growth and success!</p>
<p>Best regards,</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>
`

View File

@@ -0,0 +1,109 @@
export const RESET_PASSWORD_EMAIL = `<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta name="x-apple-disable-message-reformatting" />
<!--$-->
</head>
<body
style='background-color:#fff;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="max-width:37.5em">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="border:1px solid rgb(0,0,0, 0.1);border-radius:3px;overflow:hidden">
<tbody>
<tr>
<td>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<img src="https://litlyx.com/images/locker2.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-bottom:0">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column">
<h1 style="font-size:32px;font-weight:bold;text-align:center">
Dear user
</h1>
<h2 style="font-size:26px;font-weight:bold;text-align:center">
Below is the temporary password for logging in again to the
Litlyx dashboard.
</h2>
<p style="font-size:16px;line-height:24px;margin:16px 0">
<b>Temporary Password: </b> [NEW_PASSWORD]
<!-- September 7, 2022 at 10:58 AM -->
</p>
<p style="font-size:16px;line-height:24px;margin:16px 0">
Please ensure that you change your password as soon as possible.
To do so, go to <b>Settings > Account</b> in the dashboard. <br>
If you need further assistance, feel free to contact us at
<a href="mailto:help@litlyx.com">help@litlyx.com</a>.
</p>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0"
role="presentation" style="padding:20px;padding-top:0">
<tbody style="width:100%">
<tr style="width:100%">
<td colspan="2" data-id="__react-email-column"
style="display:flex;justify-content:center;width:100%">
<a style="line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;background-color:#5680f8;border-radius:3px;color:#FFF;font-weight:bold;border:1px solid rgb(0,0,0, 0.1);cursor:pointer;padding:12px 30px 12px 30px"
target="_blank"
href="https://dashboard.litlyx.com"><span></span><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px">
Go to Dashboard</span><span></span></a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table align="center" width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation"
style="padding:45px 0 0 0">
<tbody>
<tr>
<td>
<img src="https://react-email-demo-lpdmf0ryo-resend.vercel.app/static/yelp-footer.png"
style="display:block;outline:none;border:none;text-decoration:none;max-width:100%"
width="620" />
</td>
</tr>
</tbody>
</table>
<p style="font-size:12px;line-height:24px;margin:16px 0;text-align:center;color:rgb(0,0,0, 0.7)">
2024 © Litlyx. All rights reserved.
<br>
Litlyx S.R.L. - Viale Tirreno, 187 - 00141 Rome - P.IVA: 17814721001- REA: RM-1743194
</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>
`

View File

@@ -0,0 +1,39 @@
export const WELCOME_EMAIL = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome to Litlyx!</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<p>Were happy to have you onboard,</p>
<p>At Litlyx, were committed to creating the best analytics collection experience for everybody, starting from developers.</p>
<p>Here are a few things you can do to get started tracking analytics today:</p>
<ol>
<li><strong><a href="https://dashboard.litlyx.com" style="color: #007BFF; text-decoration: none;">Create a new project</a></strong> by just naming it</li>
<li><strong><a style="color: #0a0a0a; text-decoration: none;">Copy the universal Script</a></strong> we provide you the snippets to copy in your index.html file and start instantly to track metrics on your website or web app.</li>
<li><strong><a style="color: #0a0a0a; text-decoration: none;">Deploy</a></strong> Litlyx is production ready.</li>
</ol>
<p>If you have any questions or need support, visit <a href="http://docs.litlyx.com" style="color: #007BFF;">docs.litlyx.com</a>.</p>
<p>Feel free to reply to this email or reach out to our team at <a href="mailto:help@litlyx.com" style="color: #007BFF;">help@litlyx.com</a>. Were here to help!</p>
<p>Link to Discord for developer support: <a href="https://discord.com/invite/9cQykjsmWX" style="color: #007BFF;">https://discord.com/invite/9cQykjsmWX</a></p>
<p>Thank you for joining us, and we look forward to seeing you around.</p>
<p>We want to make analytics the freshest thing on the web.</p>
<p>Antonio,</p>
<p>CEO | Litlyx</p>
</body>
</html>
`

13
email/tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "NodeNext",
"target": "ESNext",
"outDir": "dist"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

View File

@@ -10,5 +10,15 @@
},
"keywords": [],
"author": "Emily",
"license": "MIT"
"license": "MIT",
"dependencies": {
"@getbrevo/brevo": "^2.2.0",
"cors": "^2.8.5",
"express": "^4.21.2"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/node": "^22.10.10"
}
}

1751
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -10,58 +10,14 @@ helper.clear();
// TODO: Email service as external repo
helper.create('services');
helper.copy('services/DateService.ts');
// // ---------------- Services ----------------
// const dashServicesPath = path.join(dashboardPath, 'shared/services');
// const sharedServicesPath = path.join(sharedPath, 'services');
helper.create('data');
helper.copy('data/PREMIUM.ts');
helper.copy('data/ADMINS.ts');
// if (fs.existsSync(dashServicesPath)) {
// fs.rmSync(dashServicesPath, { force: true, recursive: true });
// fs.mkdirSync(dashServicesPath);
// }
helper.create('data/broker');
helper.copy('data/broker/Limits.ts');
// // DateService
// const dashDateServicePath = path.join(dashServicesPath, 'DateService.ts');
// const sharedDateServicePath = path.join(sharedServicesPath, 'DateService.ts');
// fs.cpSync(sharedDateServicePath, dashDateServicePath);
// // ---------------- Data ----------------
// const dashDataPath = path.join(dashboardPath, 'shared/data');
// const sharedDataPath = path.join(sharedPath, 'data');
// if (fs.existsSync(dashDataPath)) {
// fs.rmSync(dashDataPath, { force: true, recursive: true });
// fs.mkdirSync(dashDataPath);
// }
// // Premium
// const dashPremiumDataPath = path.join(dashDataPath, 'PREMIUM.ts');
// const sharedPremiumDataPath = path.join(sharedDataPath, 'PREMIUM.ts');
// fs.cpSync(sharedPremiumDataPath, dashPremiumDataPath);
// // Admins
// const dashAdminsDataPath = path.join(dashDataPath, 'ADMINS.ts');
// const sharedAdminsDataPath = path.join(sharedDataPath, 'ADMINS.ts');
// fs.cpSync(sharedAdminsDataPath, dashAdminsDataPath);
// // BrokerLimits
// const dashBrokerLimitsDataPath = path.join(dashDataPath, 'broker/Limits.ts');
// const sharedBrokerLimitsDataPath = path.join(sharedDataPath, 'broker/Limits.ts');
// fs.cpSync(sharedBrokerLimitsDataPath, dashBrokerLimitsDataPath);
// // ---------------- Schema ----------------
// const dashSchemaPath = path.join(dashboardPath, 'shared/schema');
// const sharedSchemaPath = path.join(sharedPath, 'schema');
// if (fs.existsSync(dashSchemaPath)) {
// fs.rmSync(dashSchemaPath, { force: true, recursive: true });
// fs.mkdirSync(dashSchemaPath);
// }
// fs.cpSync(sharedSchemaPath, dashSchemaPath, { recursive: true });
helper.copyFolder('schema');

View File

@@ -27,7 +27,14 @@ class SharedHelper {
copy(name) {
const localSharedFile = path.join(this.localSharedPath, name);
fs.cpSync(SharedHelper.getSharedPath(), localSharedFile);
const sharedFile = path.join(SharedHelper.getSharedPath(), name);
fs.cpSync(sharedFile, localSharedFile);
}
copyFolder(name) {
const localFolder = path.join(this.localSharedPath, name);
const sharedFolder = path.join(SharedHelper.getSharedPath(), name);
fs.cpSync(sharedFolder, localFolder, { force: true, recursive: true });
}
}