Socket
Socket
Sign inDemoInstall

entities

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

entities - npm Package Compare versions

Comparing version 2.2.0 to 3.0.0

lib/encode-trie.d.ts

44

lib/decode_codepoint.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
Object.defineProperty(exports, "__esModule", { value: true });
var decode_json_1 = __importDefault(require("./maps/decode.json"));
// Adapted from https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
var decodeMap = new Map([
[0, 65533],
[128, 8364],
[130, 8218],
[131, 402],
[132, 8222],
[133, 8230],
[134, 8224],
[135, 8225],
[136, 710],
[137, 8240],
[138, 352],
[139, 8249],
[140, 338],
[142, 381],
[145, 8216],
[146, 8217],
[147, 8220],
[148, 8221],
[149, 8226],
[150, 8211],
[151, 8212],
[152, 732],
[153, 8482],
[154, 353],
[155, 8250],
[156, 339],
[158, 382],
[159, 376],
]);
var fromCodePoint =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
String.fromCodePoint ||

@@ -22,10 +48,8 @@ function (codePoint) {

function decodeCodePoint(codePoint) {
var _a;
if ((codePoint >= 0xd800 && codePoint <= 0xdfff) || codePoint > 0x10ffff) {
return "\uFFFD";
}
if (codePoint in decode_json_1.default) {
codePoint = decode_json_1.default[codePoint];
}
return fromCodePoint(codePoint);
return fromCodePoint((_a = decodeMap.get(codePoint)) !== null && _a !== void 0 ? _a : codePoint);
}
exports.default = decodeCodePoint;

@@ -1,5 +0,27 @@

export declare const decodeXML: (str: string) => string;
export declare const decodeHTMLStrict: (str: string) => string;
export declare type MapType = Record<string, string>;
export declare const decodeHTML: (str: string) => string;
import htmlDecodeTree from "./generated/decode-data-html";
import xmlDecodeTree from "./generated/decode-data-xml";
export { htmlDecodeTree, xmlDecodeTree };
export declare enum CharCodes {
NUM,
SEMI,
ZERO,
NINE,
LOWER_A,
UPPER_A,
LOWER_F,
UPPER_F,
LOWER_X,
UPPER_X
}
export declare enum BinTrieFlags {
HAS_VALUE = 32768,
BRANCH_LENGTH = 32512,
MULTI_BYTE = 128,
JUMP_TABLE = 127
}
export declare const JUMP_OFFSET_BASE: number;
export declare function determineBranch(decodeTree: Uint16Array, current: number, nodeIdx: number, char: number): number;
export declare function decodeHTML(str: string): string;
export declare function decodeHTMLStrict(str: string): string;
export declare function decodeXML(str: string): string;
//# sourceMappingURL=decode.d.ts.map

@@ -6,49 +6,155 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeHTML = exports.decodeHTMLStrict = exports.decodeXML = void 0;
var entities_json_1 = __importDefault(require("./maps/entities.json"));
var legacy_json_1 = __importDefault(require("./maps/legacy.json"));
var xml_json_1 = __importDefault(require("./maps/xml.json"));
exports.decodeXML = exports.decodeHTMLStrict = exports.decodeHTML = exports.determineBranch = exports.JUMP_OFFSET_BASE = exports.BinTrieFlags = exports.CharCodes = exports.xmlDecodeTree = exports.htmlDecodeTree = void 0;
var decode_data_html_1 = __importDefault(require("./generated/decode-data-html"));
exports.htmlDecodeTree = decode_data_html_1.default;
var decode_data_xml_1 = __importDefault(require("./generated/decode-data-xml"));
exports.xmlDecodeTree = decode_data_xml_1.default;
var decode_codepoint_1 = __importDefault(require("./decode_codepoint"));
var strictEntityRe = /&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g;
exports.decodeXML = getStrictDecoder(xml_json_1.default);
exports.decodeHTMLStrict = getStrictDecoder(entities_json_1.default);
function getStrictDecoder(map) {
var replace = getReplacer(map);
return function (str) { return String(str).replace(strictEntityRe, replace); };
var CharCodes;
(function (CharCodes) {
CharCodes[CharCodes["NUM"] = "#".charCodeAt(0)] = "NUM";
CharCodes[CharCodes["SEMI"] = ";".charCodeAt(0)] = "SEMI";
CharCodes[CharCodes["ZERO"] = "0".charCodeAt(0)] = "ZERO";
CharCodes[CharCodes["NINE"] = "9".charCodeAt(0)] = "NINE";
CharCodes[CharCodes["LOWER_A"] = "a".charCodeAt(0)] = "LOWER_A";
CharCodes[CharCodes["UPPER_A"] = "A".charCodeAt(0)] = "UPPER_A";
CharCodes[CharCodes["LOWER_F"] = "f".charCodeAt(0)] = "LOWER_F";
CharCodes[CharCodes["UPPER_F"] = "F".charCodeAt(0)] = "UPPER_F";
CharCodes[CharCodes["LOWER_X"] = "x".charCodeAt(0)] = "LOWER_X";
CharCodes[CharCodes["UPPER_X"] = "X".charCodeAt(0)] = "UPPER_X";
})(CharCodes = exports.CharCodes || (exports.CharCodes = {}));
var BinTrieFlags;
(function (BinTrieFlags) {
BinTrieFlags[BinTrieFlags["HAS_VALUE"] = 32768] = "HAS_VALUE";
BinTrieFlags[BinTrieFlags["BRANCH_LENGTH"] = 32512] = "BRANCH_LENGTH";
BinTrieFlags[BinTrieFlags["MULTI_BYTE"] = 128] = "MULTI_BYTE";
BinTrieFlags[BinTrieFlags["JUMP_TABLE"] = 127] = "JUMP_TABLE";
})(BinTrieFlags = exports.BinTrieFlags || (exports.BinTrieFlags = {}));
exports.JUMP_OFFSET_BASE = CharCodes.ZERO - 1;
function getDecoder(decodeTree) {
return function decodeHTMLBinary(str, strict) {
var ret = "";
var lastIdx = 0;
var strIdx = 0;
while ((strIdx = str.indexOf("&", strIdx)) >= 0) {
ret += str.slice(lastIdx, strIdx);
lastIdx = strIdx;
// Skip the "&"
strIdx += 1;
// If we have a numeric entity, handle this separately.
if (str.charCodeAt(strIdx) === CharCodes.NUM) {
// Skip the leading "&#". For hex entities, also skip the leading "x".
var start = strIdx + 1;
var base = 10;
var cp = str.charCodeAt(start);
if (cp === CharCodes.LOWER_X || cp === CharCodes.UPPER_X) {
base = 16;
strIdx += 1;
start += 1;
}
while (((cp = str.charCodeAt(++strIdx)) >= CharCodes.ZERO &&
cp <= CharCodes.NINE) ||
(base === 16 &&
((cp >= CharCodes.LOWER_A && cp <= CharCodes.LOWER_F) ||
(cp >= CharCodes.UPPER_A &&
cp <= CharCodes.UPPER_F))))
;
if (start !== strIdx) {
var entity = str.substring(start, strIdx);
var parsed = parseInt(entity, base);
if (str.charCodeAt(strIdx) === CharCodes.SEMI) {
strIdx += 1;
}
else if (strict) {
continue;
}
ret += decode_codepoint_1.default(parsed);
lastIdx = strIdx;
}
continue;
}
var result = null;
var excess = 1;
var treeIdx = 0;
var current = decodeTree[treeIdx];
for (; strIdx < str.length; strIdx++, excess++) {
treeIdx = determineBranch(decodeTree, current, treeIdx + 1, str.charCodeAt(strIdx));
if (treeIdx < 0)
break;
current = decodeTree[treeIdx];
// If the branch is a value, store it and continue
if (current & BinTrieFlags.HAS_VALUE) {
// If we have a legacy entity while parsing strictly, just skip the number of bytes
if (strict && str.charCodeAt(strIdx) !== CharCodes.SEMI) {
// No need to consider multi-byte values, as the legacy entity is always a single byte
treeIdx += 1;
}
else {
// If this is a surrogate pair, combine the higher bits from the node with the next byte
result =
current & BinTrieFlags.MULTI_BYTE
? String.fromCharCode(decodeTree[++treeIdx], decodeTree[++treeIdx])
: String.fromCharCode(decodeTree[++treeIdx]);
excess = 0;
}
}
}
if (result != null) {
ret += result;
lastIdx = strIdx - excess + 1;
}
}
return ret + str.slice(lastIdx);
};
}
var sorter = function (a, b) { return (a < b ? 1 : -1); };
exports.decodeHTML = (function () {
var legacy = Object.keys(legacy_json_1.default).sort(sorter);
var keys = Object.keys(entities_json_1.default).sort(sorter);
for (var i = 0, j = 0; i < keys.length; i++) {
if (legacy[j] === keys[i]) {
keys[i] += ";?";
j++;
function determineBranch(decodeTree, current, nodeIdx, char) {
if (current <= 128) {
return char === current ? nodeIdx : -1;
}
var branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 8;
if (branchCount === 0) {
return -1;
}
if (branchCount === 1) {
return char === decodeTree[nodeIdx] ? nodeIdx + 1 : -1;
}
var jumpOffset = current & BinTrieFlags.JUMP_TABLE;
if (jumpOffset) {
var value = char - exports.JUMP_OFFSET_BASE - jumpOffset;
return value < 0 || value > branchCount
? -1
: decodeTree[nodeIdx + value] - 1;
}
// Binary search for the character.
var lo = nodeIdx;
var hi = lo + branchCount - 1;
while (lo <= hi) {
var mid = (lo + hi) >>> 1;
var midVal = decodeTree[mid];
if (midVal < char) {
lo = mid + 1;
}
else if (midVal > char) {
hi = mid - 1;
}
else {
keys[i] += ";";
return decodeTree[mid + branchCount];
}
}
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g");
var replace = getReplacer(entities_json_1.default);
function replacer(str) {
if (str.substr(-1) !== ";")
str += ";";
return replace(str);
}
// TODO consider creating a merged map
return function (str) { return String(str).replace(re, replacer); };
})();
function getReplacer(map) {
return function replace(str) {
if (str.charAt(1) === "#") {
var secondChar = str.charAt(2);
if (secondChar === "X" || secondChar === "x") {
return decode_codepoint_1.default(parseInt(str.substr(3), 16));
}
return decode_codepoint_1.default(parseInt(str.substr(2), 10));
}
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
return map[str.slice(1, -1)] || str;
};
return -1;
}
exports.determineBranch = determineBranch;
var htmlDecoder = getDecoder(decode_data_html_1.default);
var xmlDecoder = getDecoder(decode_data_xml_1.default);
function decodeHTML(str) {
return htmlDecoder(str, false);
}
exports.decodeHTML = decodeHTML;
function decodeHTMLStrict(str) {
return htmlDecoder(str, true);
}
exports.decodeHTMLStrict = decodeHTMLStrict;
function decodeXML(str) {
return xmlDecoder(str, true);
}
exports.decodeXML = decodeXML;

@@ -8,3 +8,3 @@ /**

*/
export declare const encodeXML: (data: string) => string;
export declare function encodeXML(str: string): string;
/**

@@ -20,3 +20,3 @@ * Encodes all entities and non-ASCII characters in the input.

*/
export declare const encodeHTML: (data: string) => string;
export declare function encodeHTML(data: string): string;
/**

@@ -29,3 +29,3 @@ * Encodes all non-ASCII characters, as well as characters not valid in HTML

*/
export declare const encodeNonAsciiHTML: (data: string) => string;
export declare function encodeNonAsciiHTML(data: string): string;
/**

@@ -40,6 +40,5 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML

*/
export declare function escape(data: string): string;
export declare const escape: typeof encodeXML;
/**
* Encodes all characters not valid in XML documents using numeric hexadecimal
* reference (eg. `&#xfc;`).
* Encodes all characters not valid in XML documents using XML entities.
*

@@ -46,0 +45,0 @@ * Note that the output will be character-set dependent.

@@ -8,4 +8,11 @@ "use strict";

var xml_json_1 = __importDefault(require("./maps/xml.json"));
var inverseXML = getInverseObj(xml_json_1.default);
var xmlReplacer = getInverseReplacer(inverseXML);
var encode_trie_1 = require("./encode-trie");
var entities_json_1 = __importDefault(require("./maps/entities.json"));
var htmlReplacer = getCharRegExp(entities_json_1.default, true);
var xmlReplacer = getCharRegExp(xml_json_1.default, true);
var xmlInvalidChars = getCharRegExp(xml_json_1.default, false);
var xmlCodeMap = new Map(Object.keys(xml_json_1.default).map(function (k) { return [
xml_json_1.default[k].charCodeAt(0),
"&" + k + ";",
]; }));
/**

@@ -18,6 +25,23 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML

*/
exports.encodeXML = getASCIIEncoder(inverseXML);
var entities_json_1 = __importDefault(require("./maps/entities.json"));
var inverseHTML = getInverseObj(entities_json_1.default);
var htmlReplacer = getInverseReplacer(inverseHTML);
function encodeXML(str) {
var ret = "";
var lastIdx = 0;
var match;
while ((match = xmlReplacer.exec(str)) !== null) {
var i = match.index;
var char = str.charCodeAt(i);
var next = xmlCodeMap.get(char);
if (next) {
ret += str.substring(lastIdx, i) + next;
lastIdx = i + 1;
}
else {
ret += str.substring(lastIdx, i) + "&#x" + encode_trie_1.getCodePoint(str, i).toString(16) + ";";
// Increase by 1 if we have a surrogate pair
lastIdx = xmlReplacer.lastIndex += Number((char & 0xd800) === 0xd800);
}
}
return ret + str.substr(lastIdx);
}
exports.encodeXML = encodeXML;
/**

@@ -33,3 +57,6 @@ * Encodes all entities and non-ASCII characters in the input.

*/
exports.encodeHTML = getInverse(inverseHTML, htmlReplacer);
function encodeHTML(data) {
return encode_trie_1.encodeHTMLTrieRe(htmlReplacer, data);
}
exports.encodeHTML = encodeHTML;
/**

@@ -42,32 +69,20 @@ * Encodes all non-ASCII characters, as well as characters not valid in HTML

*/
exports.encodeNonAsciiHTML = getASCIIEncoder(inverseHTML);
function getInverseObj(obj) {
return Object.keys(obj)
.sort()
.reduce(function (inverse, name) {
inverse[obj[name]] = "&" + name + ";";
return inverse;
}, {});
function encodeNonAsciiHTML(data) {
return encode_trie_1.encodeHTMLTrieRe(xmlReplacer, data);
}
function getInverseReplacer(inverse) {
var single = [];
var multiple = [];
for (var _i = 0, _a = Object.keys(inverse); _i < _a.length; _i++) {
var k = _a[_i];
if (k.length === 1) {
// Add value to single array
single.push("\\" + k);
}
else {
// Add value to multiple array
multiple.push(k);
}
}
exports.encodeNonAsciiHTML = encodeNonAsciiHTML;
function getCharRegExp(map, nonAscii) {
// Collect the start characters of all entities
var chars = Object.keys(map)
.map(function (k) { return "\\" + map[k].charAt(0); })
.filter(function (v) { return !nonAscii || v.charCodeAt(1) < 128; })
.sort(function (a, b) { return a.charCodeAt(1) - b.charCodeAt(1); })
// Remove duplicates
.filter(function (v, i, a) { return v !== a[i + 1]; });
// Add ranges to single characters.
single.sort();
for (var start = 0; start < single.length - 1; start++) {
for (var start = 0; start < chars.length - 1; start++) {
// Find the end of a run of characters
var end = start;
while (end < single.length - 1 &&
single[end].charCodeAt(1) + 1 === single[end + 1].charCodeAt(1)) {
while (end < chars.length - 1 &&
chars[end].charCodeAt(1) + 1 === chars[end + 1].charCodeAt(1)) {
end += 1;

@@ -79,34 +94,6 @@ }

continue;
single.splice(start, count, single[start] + "-" + single[end]);
chars.splice(start, count, chars[start] + "-" + chars[end]);
}
multiple.unshift("[" + single.join("") + "]");
return new RegExp(multiple.join("|"), "g");
return new RegExp("[" + chars.join("") + (nonAscii ? "\\x80-\\uFFFF" : "") + "]", "g");
}
// /[^\0-\x7F]/gu
var reNonASCII = /(?:[\x80-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g;
var getCodePoint =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
String.prototype.codePointAt != null
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
function (str) { return str.codePointAt(0); }
: // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
function (c) {
return (c.charCodeAt(0) - 0xd800) * 0x400 +
c.charCodeAt(1) -
0xdc00 +
0x10000;
};
function singleCharReplacer(c) {
return "&#x" + (c.length > 1 ? getCodePoint(c) : c.charCodeAt(0))
.toString(16)
.toUpperCase() + ";";
}
function getInverse(inverse, re) {
return function (data) {
return data
.replace(re, function (name) { return inverse[name]; })
.replace(reNonASCII, singleCharReplacer);
};
}
var reEscapeChars = new RegExp(xmlReplacer.source + "|" + reNonASCII.source, "g");
/**

@@ -121,9 +108,5 @@ * Encodes all non-ASCII characters, as well as characters not valid in XML

*/
function escape(data) {
return data.replace(reEscapeChars, singleCharReplacer);
}
exports.escape = escape;
exports.escape = encodeXML;
/**
* Encodes all characters not valid in XML documents using numeric hexadecimal
* reference (eg. `&#xfc;`).
* Encodes all characters not valid in XML documents using XML entities.
*

@@ -135,9 +118,16 @@ * Note that the output will be character-set dependent.

function escapeUTF8(data) {
return data.replace(xmlReplacer, singleCharReplacer);
var match;
var lastIdx = 0;
var result = "";
while ((match = xmlInvalidChars.exec(data))) {
if (lastIdx !== match.index) {
result += data.substring(lastIdx, match.index);
}
// We know that this chararcter will be in `inverseXML`
result += xmlCodeMap.get(match[0].charCodeAt(0));
// Every match will be of length 1
lastIdx = match.index + 1;
}
return result + data.substring(lastIdx);
}
exports.escapeUTF8 = escapeUTF8;
function getASCIIEncoder(obj) {
return function (data) {
return data.replace(reEscapeChars, function (c) { return obj[c] || singleCharReplacer(c); });
};
}

@@ -0,1 +1,52 @@

/** The level of entities to support. */
export declare enum EntityLevel {
/** Support only XML entities. */
XML = 0,
/** Support HTML entities, which are a superset of XML entities. */
HTML = 1
}
/** Determines whether some entities are allowed to be written without a trailing `;`. */
export declare enum DecodingMode {
/** Support legacy HTML entities. */
Legacy = 0,
/** Do not support legacy HTML entities. */
Strict = 1
}
export declare enum EncodingMode {
/**
* The output is UTF-8 encoded. Only characters that need escaping within
* HTML will be escaped.
*/
UTF8 = 0,
/**
* The output consists only of ASCII characters. Characters that need
* escaping within HTML, and characters that aren't ASCII characters will
* be escaped.
*/
ASCII = 1,
/**
* Encode all characters that have an equivalent entity, as well as all
* characters that are not ASCII characters.
*/
Extensive = 2
}
interface DecodingOptions {
/**
* The level of entities to support.
* @default EntityLevel.XML
*/
level?: EntityLevel;
/**
* Decoding mode. If `Legacy`, will support legacy entities not terminated
* with a semicolon (`;`).
*
* Always `Strict` for XML. For HTML, set this to `true` if you are parsing
* an attribute value.
*
* The deprecated `decodeStrict` function defaults this to `Strict`.
*
* @default DecodingMode.Legacy
*/
mode?: DecodingMode;
}
/**

@@ -5,6 +56,5 @@ * Decodes a string with entities.

* @param data String to decode.
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `decodeXML` or `decodeHTML` directly.
* @param options Decoding options.
*/
export declare function decode(data: string, level?: number): string;
export declare function decode(data: string, options?: DecodingOptions | EntityLevel): string;
/**

@@ -14,16 +64,30 @@ * Decodes a string with entities. Does not allow missing trailing semicolons for entities.

* @param data String to decode.
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `decodeHTMLStrict` or `decodeXML` directly.
* @param options Decoding options.
* @deprecated Use `decode` with the `mode` set to `Strict`.
*/
export declare function decodeStrict(data: string, level?: number): string;
export declare function decodeStrict(data: string, options?: DecodingOptions | EntityLevel): string;
/**
* Options for `encode`.
*/
export interface EncodingOptions {
/**
* The level of entities to support.
* @default EntityLevel.XML
*/
level?: EntityLevel;
/**
* Output format.
* @default EncodingMode.Extensive
*/
mode?: EncodingMode;
}
/**
* Encodes a string with entities.
*
* @param data String to encode.
* @param level Optional level to encode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `encodeHTML`, `encodeXML` or `encodeNonAsciiHTML` directly.
* @param options Encoding options.
*/
export declare function encode(data: string, level?: number): string;
export declare function encode(data: string, options?: EncodingOptions | EntityLevel): string;
export { encodeXML, encodeHTML, encodeNonAsciiHTML, escape, escapeUTF8, encodeHTML as encodeHTML4, encodeHTML as encodeHTML5, } from "./encode";
export { decodeXML, decodeHTML, decodeHTMLStrict, decodeHTML as decodeHTML4, decodeHTML as decodeHTML5, decodeHTMLStrict as decodeHTML4Strict, decodeHTMLStrict as decodeHTML5Strict, decodeXML as decodeXMLStrict, } from "./decode";
//# sourceMappingURL=index.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = void 0;
exports.decodeXMLStrict = exports.decodeHTML5Strict = exports.decodeHTML4Strict = exports.decodeHTML5 = exports.decodeHTML4 = exports.decodeHTMLStrict = exports.decodeHTML = exports.decodeXML = exports.encodeHTML5 = exports.encodeHTML4 = exports.escapeUTF8 = exports.escape = exports.encodeNonAsciiHTML = exports.encodeHTML = exports.encodeXML = exports.encode = exports.decodeStrict = exports.decode = exports.EncodingMode = exports.DecodingMode = exports.EntityLevel = void 0;
var decode_1 = require("./decode");
var encode_1 = require("./encode");
/** The level of entities to support. */
var EntityLevel;
(function (EntityLevel) {
/** Support only XML entities. */
EntityLevel[EntityLevel["XML"] = 0] = "XML";
/** Support HTML entities, which are a superset of XML entities. */
EntityLevel[EntityLevel["HTML"] = 1] = "HTML";
})(EntityLevel = exports.EntityLevel || (exports.EntityLevel = {}));
/** Determines whether some entities are allowed to be written without a trailing `;`. */
var DecodingMode;
(function (DecodingMode) {
/** Support legacy HTML entities. */
DecodingMode[DecodingMode["Legacy"] = 0] = "Legacy";
/** Do not support legacy HTML entities. */
DecodingMode[DecodingMode["Strict"] = 1] = "Strict";
})(DecodingMode = exports.DecodingMode || (exports.DecodingMode = {}));
var EncodingMode;
(function (EncodingMode) {
/**
* The output is UTF-8 encoded. Only characters that need escaping within
* HTML will be escaped.
*/
EncodingMode[EncodingMode["UTF8"] = 0] = "UTF8";
/**
* The output consists only of ASCII characters. Characters that need
* escaping within HTML, and characters that aren't ASCII characters will
* be escaped.
*/
EncodingMode[EncodingMode["ASCII"] = 1] = "ASCII";
/**
* Encode all characters that have an equivalent entity, as well as all
* characters that are not ASCII characters.
*/
EncodingMode[EncodingMode["Extensive"] = 2] = "Extensive";
})(EncodingMode = exports.EncodingMode || (exports.EncodingMode = {}));
/**

@@ -10,7 +45,14 @@ * Decodes a string with entities.

* @param data String to decode.
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `decodeXML` or `decodeHTML` directly.
* @param options Decoding options.
*/
function decode(data, level) {
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTML)(data);
function decode(data, options) {
if (options === void 0) { options = EntityLevel.XML; }
var opts = typeof options === "number" ? { level: options } : options;
if (opts.level === EntityLevel.HTML) {
if (opts.mode === DecodingMode.Strict) {
return decode_1.decodeHTMLStrict(data);
}
return decode_1.decodeHTML(data);
}
return decode_1.decodeXML(data);
}

@@ -22,7 +64,15 @@ exports.decode = decode;

* @param data String to decode.
* @param level Optional level to decode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `decodeHTMLStrict` or `decodeXML` directly.
* @param options Decoding options.
* @deprecated Use `decode` with the `mode` set to `Strict`.
*/
function decodeStrict(data, level) {
return (!level || level <= 0 ? decode_1.decodeXML : decode_1.decodeHTMLStrict)(data);
function decodeStrict(data, options) {
if (options === void 0) { options = EntityLevel.XML; }
var opts = typeof options === "number" ? { level: options } : options;
if (opts.level === EntityLevel.HTML) {
if (opts.mode === DecodingMode.Legacy) {
return decode_1.decodeHTML(data);
}
return decode_1.decodeHTMLStrict(data);
}
return decode_1.decodeXML(data);
}

@@ -34,7 +84,18 @@ exports.decodeStrict = decodeStrict;

* @param data String to encode.
* @param level Optional level to encode at. 0 = XML, 1 = HTML. Default is 0.
* @deprecated Use `encodeHTML`, `encodeXML` or `encodeNonAsciiHTML` directly.
* @param options Encoding options.
*/
function encode(data, level) {
return (!level || level <= 0 ? encode_1.encodeXML : encode_1.encodeHTML)(data);
function encode(data, options) {
if (options === void 0) { options = EntityLevel.XML; }
var opts = typeof options === "number" ? { level: options } : options;
// Mode `UTF8` just escapes XML entities
if (opts.mode === EncodingMode.UTF8)
return encode_1.escapeUTF8(data);
if (opts.level === EntityLevel.HTML) {
if (opts.mode === EncodingMode.ASCII) {
return encode_1.encodeNonAsciiHTML(data);
}
return encode_1.encodeHTML(data);
}
// ASCII and Extensive are equivalent
return encode_1.encodeXML(data);
}

@@ -41,0 +102,0 @@ exports.encode = encode;

{
"name": "entities",
"version": "2.2.0",
"version": "3.0.0",
"description": "Encode & decode XML and HTML entities with ease",

@@ -24,19 +24,21 @@ "author": "Felix Boehm <me@feedic.com>",

],
"engines": {
"node": ">=0.12"
},
"devDependencies": {
"@types/jest": "^26.0.0",
"@types/node": "^14.11.8",
"@typescript-eslint/eslint-plugin": "^4.4.1",
"@typescript-eslint/parser": "^4.4.1",
"coveralls": "*",
"eslint": "^7.11.0",
"eslint-config-prettier": "^7.0.0",
"@types/jest": "^26.0.24",
"@types/node": "^16.4.13",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-node": "^11.1.0",
"jest": "^26.5.3",
"jest": "^27.0.3",
"prettier": "^2.0.5",
"ts-jest": "^26.1.0",
"ts-jest": "^27.0.4",
"typescript": "^4.0.2"
},
"scripts": {
"test": "jest --coverage && npm run lint",
"coverage": "cat coverage/lcov.info | coveralls",
"test": "npm run test:jest && npm run lint",
"test:jest": "jest",
"lint": "npm run lint:es && npm run lint:prettier",

@@ -59,3 +61,4 @@ "lint:es": "eslint .",

"preset": "ts-jest",
"testEnvironment": "node"
"testEnvironment": "node",
"coverageProvider": "v8"
},

@@ -62,0 +65,0 @@ "prettier": {

@@ -31,11 +31,28 @@ # entities [![NPM version](http://img.shields.io/npm/v/entities.svg)](https://npmjs.org/package/entities) [![Downloads](https://img.shields.io/npm/dm/entities.svg)](https://npmjs.org/package/entities) [![Build Status](http://img.shields.io/travis/fb55/entities.svg)](http://travis-ci.org/fb55/entities) [![Coverage](http://img.shields.io/coveralls/fb55/entities.svg)](https://coveralls.io/r/fb55/entities)

| Library | `decode` performance | `encode` performance | Bundle size |
| -------------- | -------------------- | -------------------- | -------------------------------------------------------------------------- |
| entities | 10.809s | 17.683s | ![npm bundle size](https://img.shields.io/bundlephobia/min/entities) |
| html-entities | 14.029s | 22.670s | ![npm bundle size](https://img.shields.io/bundlephobia/min/html-entities) |
| he | 16.163s | 44.010s | ![npm bundle size](https://img.shields.io/bundlephobia/min/he) |
| parse-entities | 28.507s | N/A | ![npm bundle size](https://img.shields.io/bundlephobia/min/parse-entities) |
| Library | `decode` perf | `encode` perf | `escape` perf | Bundle size |
| -------------- | ------------- | ------------- | ------------- | -------------------------------------------------------------------------- |
| entities | 1.418s | 6.786s | 2.196s | ![npm bundle size](https://img.shields.io/bundlephobia/min/entities) |
| html-entities | 2.530s | 6.829s | 2.415s | ![npm bundle size](https://img.shields.io/bundlephobia/min/html-entities) |
| he | 5.800s | 24.237s | 3.624s | ![npm bundle size](https://img.shields.io/bundlephobia/min/he) |
| parse-entities | 9.660s | N/A | N/A | ![npm bundle size](https://img.shields.io/bundlephobia/min/parse-entities) |
---
## Acknowledgements
This libary wouldn't be possible without the work of these individuals. Thanks
to
- [@mathiasbynens](https://github.com/mathiasbynens) for his explanations
about character encodings, and his library `he`, which was one of the
inspirations for `entities`
- [@inikulin](https://github.com/inikulin) for his work on optimized tries for
decoding HTML entities for the `parse5` project
- [@mdevils](https://github.com/mdevils) for taking on the challenge of
producing a quick entity library with his `html-entities` library.
`entities` would be quite a bit slower if there wasn't any competition.
Right now `entities` is on top, but we'll see how long that lasts!
---
License: BSD-2-Clause

@@ -42,0 +59,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc