@pallasoft/ps-utilities 2.3.0 → 2.5.0
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/dist/common/constants/email-preview-config.d.ts +29 -0
- package/dist/common/constants/email-preview-config.js +32 -0
- package/dist/common/constants/index.d.ts +1 -0
- package/dist/common/constants/index.js +17 -0
- package/dist/common/email-preview-service.d.ts +15 -0
- package/dist/common/email-preview-service.js +126 -0
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/models/email-preview-input.d.ts +7 -0
- package/dist/models/email-preview-input.js +2 -0
- package/package.json +11 -11
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const EmailPreviewConfig: {
|
|
2
|
+
readonly documentName: "email.html";
|
|
3
|
+
readonly documentContentType: "text/html";
|
|
4
|
+
readonly imageName: "email.png";
|
|
5
|
+
readonly imageContentType: "image/png";
|
|
6
|
+
readonly fallbackSubject: "Email";
|
|
7
|
+
readonly page: {
|
|
8
|
+
readonly width: 860;
|
|
9
|
+
readonly padding: 48;
|
|
10
|
+
readonly headerGap: 28;
|
|
11
|
+
readonly subjectSize: 22;
|
|
12
|
+
readonly metaSize: 13;
|
|
13
|
+
readonly bodySize: 15;
|
|
14
|
+
readonly lineHeight: 24;
|
|
15
|
+
readonly maxLines: 140;
|
|
16
|
+
readonly minHeight: 520;
|
|
17
|
+
readonly charWidth: 7.4;
|
|
18
|
+
readonly subjectWidthRatio: 1.45;
|
|
19
|
+
readonly metaWidthRatio: 0.9;
|
|
20
|
+
readonly fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica, Arial, 'DejaVu Sans', 'Liberation Sans', sans-serif";
|
|
21
|
+
readonly paperColour: "#ffffff";
|
|
22
|
+
readonly bandColour: "#0f9d58";
|
|
23
|
+
readonly bandHeight: 6;
|
|
24
|
+
readonly ruleColour: "#e4e8ee";
|
|
25
|
+
readonly subjectColour: "#101828";
|
|
26
|
+
readonly metaColour: "#667085";
|
|
27
|
+
readonly bodyColour: "#344054";
|
|
28
|
+
};
|
|
29
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmailPreviewConfig = void 0;
|
|
4
|
+
exports.EmailPreviewConfig = {
|
|
5
|
+
documentName: 'email.html',
|
|
6
|
+
documentContentType: 'text/html',
|
|
7
|
+
imageName: 'email.png',
|
|
8
|
+
imageContentType: 'image/png',
|
|
9
|
+
fallbackSubject: 'Email',
|
|
10
|
+
page: {
|
|
11
|
+
width: 860,
|
|
12
|
+
padding: 48,
|
|
13
|
+
headerGap: 28,
|
|
14
|
+
subjectSize: 22,
|
|
15
|
+
metaSize: 13,
|
|
16
|
+
bodySize: 15,
|
|
17
|
+
lineHeight: 24,
|
|
18
|
+
maxLines: 140,
|
|
19
|
+
minHeight: 520,
|
|
20
|
+
charWidth: 7.4,
|
|
21
|
+
subjectWidthRatio: 1.45,
|
|
22
|
+
metaWidthRatio: 0.9,
|
|
23
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica, Arial, 'DejaVu Sans', 'Liberation Sans', sans-serif",
|
|
24
|
+
paperColour: '#ffffff',
|
|
25
|
+
bandColour: '#0f9d58',
|
|
26
|
+
bandHeight: 6,
|
|
27
|
+
ruleColour: '#e4e8ee',
|
|
28
|
+
subjectColour: '#101828',
|
|
29
|
+
metaColour: '#667085',
|
|
30
|
+
bodyColour: '#344054',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './email-preview-config';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./email-preview-config"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EmailPreviewInput } from '../models/email-preview-input';
|
|
2
|
+
export declare class EmailPreviewService {
|
|
3
|
+
static escape(value: string): string;
|
|
4
|
+
static hasContent(input: EmailPreviewInput): boolean;
|
|
5
|
+
static subjectOf(input: EmailPreviewInput): string;
|
|
6
|
+
static toText(input: EmailPreviewInput): string;
|
|
7
|
+
static toDocument(input: EmailPreviewInput): string;
|
|
8
|
+
static toImageMarkup(input: EmailPreviewInput): string;
|
|
9
|
+
private static clip;
|
|
10
|
+
private static wrap;
|
|
11
|
+
private static push;
|
|
12
|
+
private static fromHtml;
|
|
13
|
+
private static decode;
|
|
14
|
+
private static body;
|
|
15
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmailPreviewService = void 0;
|
|
4
|
+
var email_preview_config_1 = require("./constants/email-preview-config");
|
|
5
|
+
var EmailPreviewService = /** @class */ (function () {
|
|
6
|
+
function EmailPreviewService() {
|
|
7
|
+
}
|
|
8
|
+
EmailPreviewService.escape = function (value) {
|
|
9
|
+
return value
|
|
10
|
+
.replace(/&/g, '&')
|
|
11
|
+
.replace(/</g, '<')
|
|
12
|
+
.replace(/>/g, '>')
|
|
13
|
+
.replace(/"/g, '"')
|
|
14
|
+
.replace(/'/g, ''');
|
|
15
|
+
};
|
|
16
|
+
EmailPreviewService.hasContent = function (input) {
|
|
17
|
+
return ((input.html !== null && input.html.trim() !== '') ||
|
|
18
|
+
(input.text !== null && input.text.trim() !== ''));
|
|
19
|
+
};
|
|
20
|
+
EmailPreviewService.subjectOf = function (input) {
|
|
21
|
+
return input.subject === null || input.subject.trim() === ''
|
|
22
|
+
? email_preview_config_1.EmailPreviewConfig.fallbackSubject
|
|
23
|
+
: input.subject.trim();
|
|
24
|
+
};
|
|
25
|
+
EmailPreviewService.toText = function (input) {
|
|
26
|
+
if (input.text !== null && input.text.trim() !== '')
|
|
27
|
+
return input.text.trim();
|
|
28
|
+
if (input.html === null)
|
|
29
|
+
return '';
|
|
30
|
+
return EmailPreviewService.fromHtml(input.html);
|
|
31
|
+
};
|
|
32
|
+
EmailPreviewService.toDocument = function (input) {
|
|
33
|
+
var subject = EmailPreviewService.subjectOf(input);
|
|
34
|
+
var body = input.html !== null && input.html.trim() !== ''
|
|
35
|
+
? EmailPreviewService.body(input.html)
|
|
36
|
+
: "<pre style=\"white-space:pre-wrap;font-family:inherit;margin:0;\">".concat(EmailPreviewService.escape(input.text === null ? '' : input.text), "</pre>");
|
|
37
|
+
return "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\t\t<title>".concat(EmailPreviewService.escape(subject), "</title>\n\t</head>\n\t<body style=\"margin:0;padding:24px;background:#f5f7fa;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:#101828;\">\n\t\t<div style=\"max-width:760px;margin:0 auto;background:#ffffff;border:1px solid #e4e8ee;border-radius:12px;overflow:hidden;\">\n\t\t\t<div style=\"padding:16px 20px;border-bottom:1px solid #e4e8ee;background:#f9fafb;\">\n\t\t\t\t<div style=\"font-size:15px;font-weight:700;\">").concat(EmailPreviewService.escape(subject), "</div>\n\t\t\t\t<div style=\"margin-top:4px;font-size:12px;color:#667085;\">From ").concat(EmailPreviewService.escape(input.from), " \u00B7 ").concat(EmailPreviewService.escape(input.receivedAt), "</div>\n\t\t\t</div>\n\t\t\t<div style=\"padding:20px;\">").concat(body, "</div>\n\t\t</div>\n\t</body>\n</html>");
|
|
38
|
+
};
|
|
39
|
+
EmailPreviewService.toImageMarkup = function (input) {
|
|
40
|
+
var page = email_preview_config_1.EmailPreviewConfig.page;
|
|
41
|
+
var width = page.width - page.padding * 2;
|
|
42
|
+
var subject = EmailPreviewService.clip(EmailPreviewService.subjectOf(input), Math.floor(width / (page.charWidth * page.subjectWidthRatio)));
|
|
43
|
+
var meta = EmailPreviewService.clip("From ".concat(input.from, " \u00B7 ").concat(input.receivedAt), Math.floor(width / (page.charWidth * page.metaWidthRatio)));
|
|
44
|
+
var lines = EmailPreviewService.wrap(EmailPreviewService.toText(input), Math.floor(width / page.charWidth)).slice(0, page.maxLines);
|
|
45
|
+
var metaBaseline = page.padding + page.subjectSize + 10 + page.metaSize;
|
|
46
|
+
var bodyTop = metaBaseline + page.headerGap;
|
|
47
|
+
var height = Math.max(page.minHeight, bodyTop + lines.length * page.lineHeight + page.padding);
|
|
48
|
+
var body = lines
|
|
49
|
+
.map(function (line, index) {
|
|
50
|
+
return "<text x=\"".concat(page.padding, "\" y=\"").concat(bodyTop + index * page.lineHeight, "\" font-size=\"").concat(page.bodySize, "\" fill=\"").concat(page.bodyColour, "\">").concat(EmailPreviewService.escape(line), "</text>");
|
|
51
|
+
})
|
|
52
|
+
.join('');
|
|
53
|
+
return "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"".concat(page.width, "\" height=\"").concat(height, "\" viewBox=\"0 0 ").concat(page.width, " ").concat(height, "\" font-family=\"").concat(page.fontFamily, "\">\n\t<rect width=\"").concat(page.width, "\" height=\"").concat(height, "\" fill=\"").concat(page.paperColour, "\" />\n\t<rect x=\"0\" y=\"0\" width=\"").concat(page.width, "\" height=\"").concat(page.bandHeight, "\" fill=\"").concat(page.bandColour, "\" />\n\t<text x=\"").concat(page.padding, "\" y=\"").concat(page.padding + page.subjectSize, "\" font-size=\"").concat(page.subjectSize, "\" font-weight=\"700\" fill=\"").concat(page.subjectColour, "\">").concat(EmailPreviewService.escape(subject), "</text>\n\t<text x=\"").concat(page.padding, "\" y=\"").concat(metaBaseline, "\" font-size=\"").concat(page.metaSize, "\" fill=\"").concat(page.metaColour, "\">").concat(EmailPreviewService.escape(meta), "</text>\n\t<line x1=\"").concat(page.padding, "\" y1=\"").concat(metaBaseline + 8, "\" x2=\"").concat(page.width - page.padding, "\" y2=\"").concat(metaBaseline + 8, "\" stroke=\"").concat(page.ruleColour, "\" stroke-width=\"1\" />\n\t").concat(body, "\n</svg>");
|
|
54
|
+
};
|
|
55
|
+
EmailPreviewService.clip = function (value, limit) {
|
|
56
|
+
return value.length <= limit ? value : "".concat(value.slice(0, Math.max(limit - 1, 1)), "\u2026");
|
|
57
|
+
};
|
|
58
|
+
EmailPreviewService.wrap = function (text, limit) {
|
|
59
|
+
var lines = [];
|
|
60
|
+
for (var _i = 0, _a = text.split('\n'); _i < _a.length; _i++) {
|
|
61
|
+
var paragraph = _a[_i];
|
|
62
|
+
if (paragraph.trim() === '') {
|
|
63
|
+
lines.push('');
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
var current = '';
|
|
67
|
+
for (var _b = 0, _c = paragraph.trim().split(/\s+/); _b < _c.length; _b++) {
|
|
68
|
+
var word = _c[_b];
|
|
69
|
+
var candidate = current === '' ? word : "".concat(current, " ").concat(word);
|
|
70
|
+
if (candidate.length <= limit) {
|
|
71
|
+
current = candidate;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (current !== '')
|
|
75
|
+
lines.push(current);
|
|
76
|
+
current = word.length <= limit ? word : EmailPreviewService.push(lines, word, limit);
|
|
77
|
+
}
|
|
78
|
+
lines.push(current);
|
|
79
|
+
}
|
|
80
|
+
return lines;
|
|
81
|
+
};
|
|
82
|
+
EmailPreviewService.push = function (lines, word, limit) {
|
|
83
|
+
var rest = word;
|
|
84
|
+
while (rest.length > limit) {
|
|
85
|
+
lines.push(rest.slice(0, limit));
|
|
86
|
+
rest = rest.slice(limit);
|
|
87
|
+
}
|
|
88
|
+
return rest;
|
|
89
|
+
};
|
|
90
|
+
EmailPreviewService.fromHtml = function (html) {
|
|
91
|
+
return EmailPreviewService.decode(html
|
|
92
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
93
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, '')
|
|
94
|
+
.replace(/<head\b[^>]*>[\s\S]*?<\/head>/gi, '')
|
|
95
|
+
.replace(/<br\s*\/?>/gi, '\n')
|
|
96
|
+
.replace(/<\/(p|div|tr|li|h[1-6]|table|section|header|footer)>/gi, '\n')
|
|
97
|
+
.replace(/<[^>]+>/g, ' '))
|
|
98
|
+
.replace(/[^\S\n]+/g, ' ')
|
|
99
|
+
.replace(/ *\n */g, '\n')
|
|
100
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
101
|
+
.trim();
|
|
102
|
+
};
|
|
103
|
+
EmailPreviewService.decode = function (value) {
|
|
104
|
+
return value
|
|
105
|
+
.replace(/ /gi, ' ')
|
|
106
|
+
.replace(/&/gi, '&')
|
|
107
|
+
.replace(/</gi, '<')
|
|
108
|
+
.replace(/>/gi, '>')
|
|
109
|
+
.replace(/"/gi, '"')
|
|
110
|
+
.replace(/�?39;|'|'/gi, "'")
|
|
111
|
+
.replace(/’|’/gi, '’')
|
|
112
|
+
.replace(/—|—/gi, '—')
|
|
113
|
+
.replace(/–|–/gi, '–');
|
|
114
|
+
};
|
|
115
|
+
EmailPreviewService.body = function (html) {
|
|
116
|
+
var withoutScripts = html
|
|
117
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, '')
|
|
118
|
+
.replace(/<iframe\b[^>]*>[\s\S]*?<\/iframe>/gi, '')
|
|
119
|
+
.replace(/\son[a-z]+\s*=\s*"[^"]*"/gi, '')
|
|
120
|
+
.replace(/\son[a-z]+\s*=\s*'[^']*'/gi, '');
|
|
121
|
+
var inner = withoutScripts.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
|
122
|
+
return inner === null ? withoutScripts : inner[1];
|
|
123
|
+
};
|
|
124
|
+
return EmailPreviewService;
|
|
125
|
+
}());
|
|
126
|
+
exports.EmailPreviewService = EmailPreviewService;
|
package/dist/common/index.d.ts
CHANGED
package/dist/common/index.js
CHANGED
|
@@ -15,7 +15,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./color-service"), exports);
|
|
18
|
+
__exportStar(require("./constants"), exports);
|
|
18
19
|
__exportStar(require("./crypto-service"), exports);
|
|
20
|
+
__exportStar(require("./email-preview-service"), exports);
|
|
19
21
|
__exportStar(require("./encrypted-fields-service"), exports);
|
|
20
22
|
__exportStar(require("./envelope-crypto-service"), exports);
|
|
21
23
|
__exportStar(require("./date-service"), exports);
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import * as ClientNamespace from './client';
|
|
|
2
2
|
import * as CommonNamespace from './common';
|
|
3
3
|
export declare const Common: typeof CommonNamespace;
|
|
4
4
|
export declare const Client: typeof ClientNamespace;
|
|
5
|
+
export type { EmailPreviewInput } from './models/email-preview-input';
|
|
5
6
|
export type { EncryptedFieldsSpec } from './common/encrypted-fields-service';
|
|
6
7
|
export type { DataKeyPair } from './common/envelope-crypto-service';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pallasoft/ps-utilities",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -41,27 +41,27 @@
|
|
|
41
41
|
"@commitlint/config-conventional": "^20.0.0",
|
|
42
42
|
"@eslint/compat": "^2.0.0",
|
|
43
43
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.0",
|
|
44
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
45
|
+
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
46
|
+
"@semantic-release/git": "^10.0.1",
|
|
47
|
+
"@semantic-release/github": "^11.0.1",
|
|
48
|
+
"@semantic-release/npm": "^12.0.0",
|
|
49
|
+
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
44
50
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
45
51
|
"@typescript-eslint/parser": "^8.48.0",
|
|
46
52
|
"commitlint": "^20.1.0",
|
|
53
|
+
"conventional-changelog-conventionalcommits": "^7.0.2",
|
|
47
54
|
"eslint": "^9.39.1",
|
|
48
55
|
"eslint-config-prettier": "^10.1.8",
|
|
49
56
|
"eslint-plugin-import": "^2.32.0",
|
|
50
57
|
"eslint-plugin-prettier": "^5.5.4",
|
|
58
|
+
"hono": "^4.12.18",
|
|
51
59
|
"husky": "^9.1.7",
|
|
52
60
|
"lint-staged": "^16.2.7",
|
|
53
61
|
"prettier": "^3.6.2",
|
|
54
|
-
"
|
|
62
|
+
"semantic-release": "^24.2.0",
|
|
55
63
|
"ts-node": "^10.9.2",
|
|
56
|
-
"typescript": "^5.9.3"
|
|
57
|
-
"@semantic-release/changelog": "^6.0.3",
|
|
58
|
-
"@semantic-release/commit-analyzer": "^13.0.0",
|
|
59
|
-
"@semantic-release/git": "^10.0.1",
|
|
60
|
-
"@semantic-release/github": "^11.0.1",
|
|
61
|
-
"@semantic-release/npm": "^12.0.0",
|
|
62
|
-
"@semantic-release/release-notes-generator": "^14.0.1",
|
|
63
|
-
"conventional-changelog-conventionalcommits": "^7.0.2",
|
|
64
|
-
"semantic-release": "^24.2.0"
|
|
64
|
+
"typescript": "^5.9.3"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"hono": "^4.0.0"
|