Files
SLACK_COORD_RELATORIO/logic/normalize.js
T
GustavoandClaude Sonnet 5 d7650308a9 feat(v2): add robust GLPI text normalization (HTML/entities, multi-level escaping)
Handles: numeric entities (< >), named entities (&   etc),
HTML tags, multi-level escaping (up to 5 decode iterations, capped to
avoid infinite loop), whitespace/newline collapsing. Preserves dates,
names, numbers, error codes, hostnames, versions -- only strips markup.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 16:45:36 -03:00

59 lines
1.6 KiB
JavaScript

const NAMED_ENTITIES = {
'&nbsp;': ' ',
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#39;': "'",
'&apos;': "'",
};
const MAX_DECODE_ITERATIONS = 5;
function decodeEntitiesOnce(text) {
let result = text.replace(/&#(\d+);/g, (match, code) => {
const num = Number(code);
return Number.isFinite(num) ? String.fromCodePoint(num) : match;
});
result = result.replace(/&#x([0-9a-fA-F]+);/g, (match, hex) => {
const num = parseInt(hex, 16);
return Number.isFinite(num) ? String.fromCodePoint(num) : match;
});
for (const [entity, char] of Object.entries(NAMED_ENTITIES)) {
result = result.split(entity).join(char);
}
return result;
}
function stripHtmlTags(text) {
return text.replace(/<[^>]*>/g, ' ');
}
// Decodifica HTML/entities (inclusive escapado multiplas vezes, ate MAX_DECODE_ITERATIONS
// para nunca travar em loop) e remove tags -- sem apagar informacao (datas, nomes, numeros,
// codigos de erro, hostname, versao continuam intactos: nenhuma dessas regras mexe em texto
// que nao seja literalmente uma entidade HTML ou uma tag).
function normalizeGlpiText(rawText) {
if (rawText === null || rawText === undefined) return '';
let text = String(rawText);
for (let i = 0; i < MAX_DECODE_ITERATIONS; i += 1) {
const decoded = decodeEntitiesOnce(text);
if (decoded === text) break;
text = decoded;
}
text = stripHtmlTags(text);
text = text
.split('\n')
.map((line) => line.replace(/[ \t]+/g, ' ').trim())
.join('\n')
.replace(/\n{3,}/g, '\n\n')
.trim();
return text;
}
module.exports = { normalizeGlpiText, decodeEntitiesOnce, stripHtmlTags };