@heliyos/heliyos-api-core 1.0.68 → 1.0.70

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.
@@ -9,5 +9,6 @@ export declare const emailTemplates: {
9
9
  notificationImmediateGrouped: string;
10
10
  notificationDailySummary: string;
11
11
  organizationDailySummary: string;
12
+ integrationNotSynced: string;
12
13
  };
13
14
  export declare const getEmailTemplate: (template: string, data: object) => string;
@@ -41,6 +41,7 @@ exports.emailTemplates = {
41
41
  notificationImmediateGrouped: "notification-immediate-grouped.html",
42
42
  notificationDailySummary: "notification-daily-summary.html",
43
43
  organizationDailySummary: "organization-daily-summary.html",
44
+ integrationNotSynced: "integration-not-synced.html",
44
45
  };
45
46
  /**
46
47
  * Simple markdown to HTML converter for email templates
@@ -52,12 +53,12 @@ const markdownToHtml = (text) => {
52
53
  // Bold: **text** or __text__
53
54
  .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
54
55
  .replace(/__(.*?)__/g, "<strong>$1</strong>")
55
- // Italics: *text* or _text_
56
+ // Italics: *text* (intentionally avoid _text_ to keep URLs/query keys intact)
56
57
  .replace(/\*(.*?)\*/g, "<em>$1</em>")
57
- .replace(/_(.*?)_/g, "<em>$1</em>")
58
58
  // Newlines to <br>
59
59
  .replace(/\n/g, "<br>");
60
60
  };
61
+ const URL_LIKE_PATTERN = /^(https?:\/\/|mailto:|tel:)\S+$/i;
61
62
  /**
62
63
  * Recursively process object values to convert markdown to HTML
63
64
  */
@@ -65,6 +66,9 @@ const processMarkdownData = (data) => {
65
66
  if (!data)
66
67
  return data;
67
68
  if (typeof data === "string") {
69
+ if (URL_LIKE_PATTERN.test(data.trim())) {
70
+ return data;
71
+ }
68
72
  return markdownToHtml(data);
69
73
  }
70
74
  if (Array.isArray(data)) {
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Integration Not Synched</title>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ line-height: 1.6;
12
+ color: #0e0d0c;
13
+ background-color: #f8f8f6;
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ .container {
19
+ max-width: 600px;
20
+ margin: 20px auto;
21
+ background-color: #ffffff;
22
+ border: 2px solid #7c3aed;
23
+ border-radius: 12px;
24
+ overflow: hidden;
25
+ }
26
+
27
+ .header {
28
+ background-color: #7c3aed;
29
+ padding: 30px 20px;
30
+ text-align: center;
31
+ }
32
+
33
+ .header img {
34
+ max-width: 180px;
35
+ height: auto;
36
+ }
37
+
38
+ .content {
39
+ padding: 30px;
40
+ color: #2c2721;
41
+ }
42
+
43
+ .button {
44
+ display: inline-block;
45
+ padding: 12px 24px;
46
+ background-color: #7c3aed;
47
+ color: #ffffff !important;
48
+ text-decoration: none;
49
+ border-radius: 8px;
50
+ font-weight: bold;
51
+ margin-top: 20px;
52
+ }
53
+
54
+ .button:hover {
55
+ background-color: #6d28d9;
56
+ }
57
+
58
+ .footer {
59
+ background-color: #ebe7db;
60
+ padding: 20px;
61
+ text-align: center;
62
+ font-size: 12px;
63
+ color: #5c5545;
64
+ }
65
+
66
+ .warning-box {
67
+ background-color: #fff3cd;
68
+ border-left: 4px solid #ffc107;
69
+ padding: 16px;
70
+ margin: 20px 0;
71
+ border-radius: 4px;
72
+ }
73
+
74
+ .details-table {
75
+ width: 100%;
76
+ border: 1px solid #e5e7eb;
77
+ border-radius: 8px;
78
+ border-collapse: collapse;
79
+ margin: 20px 0;
80
+ }
81
+
82
+ .details-table td {
83
+ padding: 10px 12px;
84
+ border-bottom: 1px solid #f3f4f6;
85
+ font-size: 13px;
86
+ }
87
+
88
+ .details-label {
89
+ color: #5c5545;
90
+ width: 160px;
91
+ }
92
+
93
+ .details-value {
94
+ color: #0e0d0c;
95
+ }
96
+ </style>
97
+ </head>
98
+
99
+ <body>
100
+ <div class="container">
101
+ <div class="header">
102
+ <img src="https://assets.heliyos.ai/heliyos-logo-white.png" alt="Heliyos AI">
103
+ </div>
104
+ <div class="content">
105
+ <h2 style="margin-top: 0; color: #0e0d0c;">Action Required: Integration Not Synched</h2>
106
+ <p>Hi {{first_name}},</p>
107
+ <p>We detected that your integration <strong>{{integration_name}}</strong> is currently not synched.</p>
108
+ <p>{{summary}}</p>
109
+
110
+ <div class="warning-box">
111
+ <p style="margin: 0;"><strong>Detected at:</strong> {{timestamp}}</p>
112
+ </div>
113
+
114
+ {{#if details}}
115
+ <table class="details-table">
116
+ {{#each details}}
117
+ <tr>
118
+ <td class="details-label">{{label}}</td>
119
+ <td class="details-value">{{value}}</td>
120
+ </tr>
121
+ {{/each}}
122
+ </table>
123
+ {{/if}}
124
+
125
+ <p style="text-align: center;">
126
+ <a href="{{reconnect_url}}" class="button">Reconnect Integration</a>
127
+ </p>
128
+ <p>If you're having trouble clicking the button, copy and paste the following URL into your web browser:</p>
129
+ <p style="word-break: break-all; font-size: 13px; color: #5c5545;">{{reconnect_url}}</p>
130
+ </div>
131
+ <div class="footer">
132
+ <p>&copy; {{year}} {{company_name}}. All rights reserved.</p>
133
+ <p>This is an automated message, please do not reply to this email.</p>
134
+ </div>
135
+ </div>
136
+ </body>
137
+
138
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heliyos/heliyos-api-core",
3
- "version": "1.0.68",
3
+ "version": "1.0.70",
4
4
  "description": "Heliyos's core api functions and middlewares. Its a private package hosted on npm.",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -13,6 +13,7 @@ export const emailTemplates = {
13
13
  notificationImmediateGrouped: "notification-immediate-grouped.html",
14
14
  notificationDailySummary: "notification-daily-summary.html",
15
15
  organizationDailySummary: "organization-daily-summary.html",
16
+ integrationNotSynced: "integration-not-synced.html",
16
17
  };
17
18
 
18
19
  /**
@@ -25,13 +26,14 @@ const markdownToHtml = (text: string): string => {
25
26
  // Bold: **text** or __text__
26
27
  .replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>")
27
28
  .replace(/__(.*?)__/g, "<strong>$1</strong>")
28
- // Italics: *text* or _text_
29
+ // Italics: *text* (intentionally avoid _text_ to keep URLs/query keys intact)
29
30
  .replace(/\*(.*?)\*/g, "<em>$1</em>")
30
- .replace(/_(.*?)_/g, "<em>$1</em>")
31
31
  // Newlines to <br>
32
32
  .replace(/\n/g, "<br>");
33
33
  };
34
34
 
35
+ const URL_LIKE_PATTERN = /^(https?:\/\/|mailto:|tel:)\S+$/i;
36
+
35
37
  /**
36
38
  * Recursively process object values to convert markdown to HTML
37
39
  */
@@ -39,6 +41,9 @@ const processMarkdownData = (data: any): any => {
39
41
  if (!data) return data;
40
42
 
41
43
  if (typeof data === "string") {
44
+ if (URL_LIKE_PATTERN.test(data.trim())) {
45
+ return data;
46
+ }
42
47
  return markdownToHtml(data);
43
48
  }
44
49
 
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Integration Not Synched</title>
8
+ <style>
9
+ body {
10
+ font-family: Arial, sans-serif;
11
+ line-height: 1.6;
12
+ color: #0e0d0c;
13
+ background-color: #f8f8f6;
14
+ margin: 0;
15
+ padding: 0;
16
+ }
17
+
18
+ .container {
19
+ max-width: 600px;
20
+ margin: 20px auto;
21
+ background-color: #ffffff;
22
+ border: 2px solid #7c3aed;
23
+ border-radius: 12px;
24
+ overflow: hidden;
25
+ }
26
+
27
+ .header {
28
+ background-color: #7c3aed;
29
+ padding: 30px 20px;
30
+ text-align: center;
31
+ }
32
+
33
+ .header img {
34
+ max-width: 180px;
35
+ height: auto;
36
+ }
37
+
38
+ .content {
39
+ padding: 30px;
40
+ color: #2c2721;
41
+ }
42
+
43
+ .button {
44
+ display: inline-block;
45
+ padding: 12px 24px;
46
+ background-color: #7c3aed;
47
+ color: #ffffff !important;
48
+ text-decoration: none;
49
+ border-radius: 8px;
50
+ font-weight: bold;
51
+ margin-top: 20px;
52
+ }
53
+
54
+ .button:hover {
55
+ background-color: #6d28d9;
56
+ }
57
+
58
+ .footer {
59
+ background-color: #ebe7db;
60
+ padding: 20px;
61
+ text-align: center;
62
+ font-size: 12px;
63
+ color: #5c5545;
64
+ }
65
+
66
+ .warning-box {
67
+ background-color: #fff3cd;
68
+ border-left: 4px solid #ffc107;
69
+ padding: 16px;
70
+ margin: 20px 0;
71
+ border-radius: 4px;
72
+ }
73
+
74
+ .details-table {
75
+ width: 100%;
76
+ border: 1px solid #e5e7eb;
77
+ border-radius: 8px;
78
+ border-collapse: collapse;
79
+ margin: 20px 0;
80
+ }
81
+
82
+ .details-table td {
83
+ padding: 10px 12px;
84
+ border-bottom: 1px solid #f3f4f6;
85
+ font-size: 13px;
86
+ }
87
+
88
+ .details-label {
89
+ color: #5c5545;
90
+ width: 160px;
91
+ }
92
+
93
+ .details-value {
94
+ color: #0e0d0c;
95
+ }
96
+ </style>
97
+ </head>
98
+
99
+ <body>
100
+ <div class="container">
101
+ <div class="header">
102
+ <img src="https://assets.heliyos.ai/heliyos-logo-white.png" alt="Heliyos AI">
103
+ </div>
104
+ <div class="content">
105
+ <h2 style="margin-top: 0; color: #0e0d0c;">Action Required: Integration Not Synched</h2>
106
+ <p>Hi {{first_name}},</p>
107
+ <p>We detected that your integration <strong>{{integration_name}}</strong> is currently not synched.</p>
108
+ <p>{{summary}}</p>
109
+
110
+ <div class="warning-box">
111
+ <p style="margin: 0;"><strong>Detected at:</strong> {{timestamp}}</p>
112
+ </div>
113
+
114
+ {{#if details}}
115
+ <table class="details-table">
116
+ {{#each details}}
117
+ <tr>
118
+ <td class="details-label">{{label}}</td>
119
+ <td class="details-value">{{value}}</td>
120
+ </tr>
121
+ {{/each}}
122
+ </table>
123
+ {{/if}}
124
+
125
+ <p style="text-align: center;">
126
+ <a href="{{reconnect_url}}" class="button">Reconnect Integration</a>
127
+ </p>
128
+ <p>If you're having trouble clicking the button, copy and paste the following URL into your web browser:</p>
129
+ <p style="word-break: break-all; font-size: 13px; color: #5c5545;">{{reconnect_url}}</p>
130
+ </div>
131
+ <div class="footer">
132
+ <p>&copy; {{year}} {{company_name}}. All rights reserved.</p>
133
+ <p>This is an automated message, please do not reply to this email.</p>
134
+ </div>
135
+ </div>
136
+ </body>
137
+
138
+ </html>