@excofy/utils 2.5.1 → 2.6.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/index.cjs CHANGED
@@ -36,7 +36,7 @@ __export(index_exports, {
36
36
  cryptoUtils: () => cryptoUtils,
37
37
  generateCode: () => generateCode,
38
38
  htmlEntityDecode: () => htmlEntityDecode,
39
- htmlToPlainText: () => sanitizeValue,
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(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/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(/\n{2,}/g, "\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, sanitizeValue as htmlToPlainText, number as numberUtils, slug as slugUtils, stringUtils };
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, sanitizeValue as htmlToPlainText, number as numberUtils, slug as slugUtils, stringUtils };
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(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&lt;/g, "<").replace(/&gt;/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(/\n{2,}/g, "\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
- sanitizeValue as htmlToPlainText,
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.5.1",
3
+ "version": "2.6.0",
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/crypto.spec.ts' --testTimeout=10000"
19
+ "test": "tsx --test 'tests/helpers/htmlToPlainText.spec.ts' --testTimeout=10000"
20
20
  },
21
21
  "repository": {
22
22
  "type": "git",
@@ -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(/&amp;/g, '&')
115
115
  .replace(/&quot;/g, '"')
@@ -117,3 +117,22 @@ export function htmlEntityDecode(str = ''): string {
117
117
  .replace(/&lt;/g, '<')
118
118
  .replace(/&gt;/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(/\n{2,}/g, '\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 &amp; Jerry &lt;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
+ });