@excofy/utils 2.5.1 → 2.6.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/dist/index.cjs +9 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -1
- package/package.json +2 -2
- package/src/helpers/sanitize.ts +21 -2
- package/src/index.ts +1 -4
- package/tests/helpers/htmlToPlainText.spec.ts +33 -0
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
cryptoUtils: () => cryptoUtils,
|
|
37
37
|
generateCode: () => generateCode,
|
|
38
38
|
htmlEntityDecode: () => htmlEntityDecode,
|
|
39
|
-
htmlToPlainText: () =>
|
|
39
|
+
htmlToPlainText: () => htmlToPlainText,
|
|
40
40
|
numberUtils: () => number_exports,
|
|
41
41
|
slugUtils: () => slug_exports,
|
|
42
42
|
stringUtils: () => stringUtils
|
|
@@ -164,6 +164,14 @@ function htmlEntityDecode(str = "") {
|
|
|
164
164
|
(_, code) => String.fromCharCode(Number.parseInt(code, 16))
|
|
165
165
|
).replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
166
166
|
}
|
|
167
|
+
function htmlToPlainText(html) {
|
|
168
|
+
if (!html || typeof html !== "string" || html.length === 0) {
|
|
169
|
+
return "";
|
|
170
|
+
}
|
|
171
|
+
const decodedHtml = htmlEntityDecode(html);
|
|
172
|
+
const plainText = decodedHtml.replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<\/li>/gi, "\n").replace(/<li>/gi, "\u2022 ").replace(/<\/?[^>]+(>|$)/g, "").replace(/(\r?\n\s*){2,}/g, "\n\n").trim();
|
|
173
|
+
return plainText;
|
|
174
|
+
}
|
|
167
175
|
|
|
168
176
|
// src/helpers/video.ts
|
|
169
177
|
var video = {
|
package/dist/index.d.cts
CHANGED
|
@@ -6,8 +6,8 @@ type AllowedTag = Tag | {
|
|
|
6
6
|
tag: Tag;
|
|
7
7
|
attributes?: Attributes[];
|
|
8
8
|
};
|
|
9
|
-
declare function sanitizeValue(value: string, allowedTags?: AllowedTag[]): string;
|
|
10
9
|
declare function htmlEntityDecode(str?: string): string;
|
|
10
|
+
declare function htmlToPlainText(html: string): string;
|
|
11
11
|
|
|
12
12
|
type TMessage = {
|
|
13
13
|
message: string;
|
|
@@ -242,4 +242,4 @@ declare class ExpiredTokenError extends CryptoError {
|
|
|
242
242
|
constructor(message?: string);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
export { ExpiredTokenError, InvalidTokenError, createValidator, cryptoUtils, generateCode, htmlEntityDecode,
|
|
245
|
+
export { ExpiredTokenError, InvalidTokenError, createValidator, cryptoUtils, generateCode, htmlEntityDecode, htmlToPlainText, number as numberUtils, slug as slugUtils, stringUtils };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ type AllowedTag = Tag | {
|
|
|
6
6
|
tag: Tag;
|
|
7
7
|
attributes?: Attributes[];
|
|
8
8
|
};
|
|
9
|
-
declare function sanitizeValue(value: string, allowedTags?: AllowedTag[]): string;
|
|
10
9
|
declare function htmlEntityDecode(str?: string): string;
|
|
10
|
+
declare function htmlToPlainText(html: string): string;
|
|
11
11
|
|
|
12
12
|
type TMessage = {
|
|
13
13
|
message: string;
|
|
@@ -242,4 +242,4 @@ declare class ExpiredTokenError extends CryptoError {
|
|
|
242
242
|
constructor(message?: string);
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
export { ExpiredTokenError, InvalidTokenError, createValidator, cryptoUtils, generateCode, htmlEntityDecode,
|
|
245
|
+
export { ExpiredTokenError, InvalidTokenError, createValidator, cryptoUtils, generateCode, htmlEntityDecode, htmlToPlainText, number as numberUtils, slug as slugUtils, stringUtils };
|
package/dist/index.js
CHANGED
|
@@ -125,6 +125,14 @@ function htmlEntityDecode(str = "") {
|
|
|
125
125
|
(_, code) => String.fromCharCode(Number.parseInt(code, 16))
|
|
126
126
|
).replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
127
127
|
}
|
|
128
|
+
function htmlToPlainText(html) {
|
|
129
|
+
if (!html || typeof html !== "string" || html.length === 0) {
|
|
130
|
+
return "";
|
|
131
|
+
}
|
|
132
|
+
const decodedHtml = htmlEntityDecode(html);
|
|
133
|
+
const plainText = decodedHtml.replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<\/li>/gi, "\n").replace(/<li>/gi, "\u2022 ").replace(/<\/?[^>]+(>|$)/g, "").replace(/(\r?\n\s*){2,}/g, "\n\n").trim();
|
|
134
|
+
return plainText;
|
|
135
|
+
}
|
|
128
136
|
|
|
129
137
|
// src/helpers/video.ts
|
|
130
138
|
var video = {
|
|
@@ -934,7 +942,7 @@ export {
|
|
|
934
942
|
cryptoUtils,
|
|
935
943
|
generateCode,
|
|
936
944
|
htmlEntityDecode,
|
|
937
|
-
|
|
945
|
+
htmlToPlainText,
|
|
938
946
|
number_exports as numberUtils,
|
|
939
947
|
slug_exports as slugUtils,
|
|
940
948
|
stringUtils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@excofy/utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "Biblioteca de utilitários para o Excofy",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"prepublishOnly": "npm run build",
|
|
18
18
|
"deploy": "act",
|
|
19
|
-
"test": "tsx --test 'tests/helpers/
|
|
19
|
+
"test": "tsx --test 'tests/helpers/htmlToPlainText.spec.ts' --testTimeout=10000"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
package/src/helpers/sanitize.ts
CHANGED
|
@@ -69,7 +69,7 @@ const allAttributes: Attributes[] = [
|
|
|
69
69
|
|
|
70
70
|
export function sanitizeValue(
|
|
71
71
|
value: string,
|
|
72
|
-
allowedTags?: AllowedTag[]
|
|
72
|
+
allowedTags?: AllowedTag[],
|
|
73
73
|
): string {
|
|
74
74
|
let whiteList: IWhiteList = {};
|
|
75
75
|
|
|
@@ -109,7 +109,7 @@ export function htmlEntityDecode(str = ''): string {
|
|
|
109
109
|
return str
|
|
110
110
|
.replace(/&#(\d+);/g, (_, code) => String.fromCharCode(code))
|
|
111
111
|
.replace(/&#x([0-9a-f]+);/gi, (_, code) =>
|
|
112
|
-
String.fromCharCode(Number.parseInt(code, 16))
|
|
112
|
+
String.fromCharCode(Number.parseInt(code, 16)),
|
|
113
113
|
)
|
|
114
114
|
.replace(/&/g, '&')
|
|
115
115
|
.replace(/"/g, '"')
|
|
@@ -117,3 +117,22 @@ export function htmlEntityDecode(str = ''): string {
|
|
|
117
117
|
.replace(/</g, '<')
|
|
118
118
|
.replace(/>/g, '>');
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
export function htmlToPlainText(html: string): string {
|
|
122
|
+
if (!html || typeof html !== 'string' || html.length === 0) {
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const decodedHtml = htmlEntityDecode(html);
|
|
127
|
+
|
|
128
|
+
const plainText = decodedHtml
|
|
129
|
+
.replace(/<br\s*\/?>/gi, '\n')
|
|
130
|
+
.replace(/<\/p>/gi, '\n')
|
|
131
|
+
.replace(/<\/li>/gi, '\n')
|
|
132
|
+
.replace(/<li>/gi, '• ')
|
|
133
|
+
.replace(/<\/?[^>]+(>|$)/g, '') // Remove outras tags
|
|
134
|
+
.replace(/(\r?\n\s*){2,}/g, '\n\n') // Remove quebras de linha duplicadas
|
|
135
|
+
.trim();
|
|
136
|
+
|
|
137
|
+
return plainText;
|
|
138
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { createValidator } from './helpers/validator';
|
|
2
|
-
import {
|
|
3
|
-
htmlEntityDecode,
|
|
4
|
-
sanitizeValue as htmlToPlainText,
|
|
5
|
-
} from './helpers/sanitize';
|
|
2
|
+
import { htmlEntityDecode, htmlToPlainText } from './helpers/sanitize';
|
|
6
3
|
import { generateCode } from './helpers/generateCode';
|
|
7
4
|
import { stringUtils } from './helpers/string';
|
|
8
5
|
import { cryptoUtils } from './helpers/crypto';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { htmlToPlainText } from '../../src/helpers/sanitize';
|
|
4
|
+
|
|
5
|
+
test('Converte <br> em quebra de linha', () => {
|
|
6
|
+
const html = 'Linha 1<br>Linha 2';
|
|
7
|
+
const expected = 'Linha 1\nLinha 2';
|
|
8
|
+
assert.equal(htmlToPlainText(html), expected);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('Remove todas as tags HTML exceto marcadores de lista', () => {
|
|
12
|
+
const html = '<ul><li>Item 1</li><li>Item 2</li></ul>';
|
|
13
|
+
const expected = '• Item 1\n• Item 2';
|
|
14
|
+
assert.equal(htmlToPlainText(html), expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Converte <p> em quebra de linha', () => {
|
|
18
|
+
const html = '<p>Parágrafo 1</p><p>Parágrafo 2</p>';
|
|
19
|
+
const expected = 'Parágrafo 1\nParágrafo 2';
|
|
20
|
+
assert.equal(htmlToPlainText(html), expected);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('Decodifica entidades HTML', () => {
|
|
24
|
+
const html = 'Tom & Jerry <3';
|
|
25
|
+
const expected = 'Tom & Jerry';
|
|
26
|
+
assert.equal(htmlToPlainText(html), expected);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('Remove quebras de linha duplicadas', () => {
|
|
30
|
+
const html = 'Linha 1<br><br>Linha 2';
|
|
31
|
+
const expected = 'Linha 1\nLinha 2';
|
|
32
|
+
assert.equal(htmlToPlainText(html), expected);
|
|
33
|
+
});
|