entities 2.1.0 → 7.0.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.
Files changed (124) hide show
  1. package/decode.d.ts +3 -0
  2. package/decode.js +3 -0
  3. package/dist/commonjs/decode-codepoint.d.ts +19 -0
  4. package/dist/commonjs/decode-codepoint.d.ts.map +1 -0
  5. package/dist/commonjs/decode-codepoint.js +77 -0
  6. package/dist/commonjs/decode-codepoint.js.map +1 -0
  7. package/dist/commonjs/decode.d.ts +205 -0
  8. package/dist/commonjs/decode.d.ts.map +1 -0
  9. package/dist/commonjs/decode.js +568 -0
  10. package/dist/commonjs/decode.js.map +1 -0
  11. package/dist/commonjs/encode.d.ts +22 -0
  12. package/dist/commonjs/encode.d.ts.map +1 -0
  13. package/dist/commonjs/encode.js +92 -0
  14. package/dist/commonjs/encode.js.map +1 -0
  15. package/dist/commonjs/escape.d.ts +46 -0
  16. package/dist/commonjs/escape.d.ts.map +1 -0
  17. package/dist/commonjs/escape.js +138 -0
  18. package/dist/commonjs/escape.js.map +1 -0
  19. package/dist/commonjs/generated/decode-data-html.d.ts +2 -0
  20. package/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
  21. package/dist/commonjs/generated/decode-data-html.js +7 -0
  22. package/dist/commonjs/generated/decode-data-html.js.map +1 -0
  23. package/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
  24. package/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
  25. package/dist/commonjs/generated/decode-data-xml.js +7 -0
  26. package/dist/commonjs/generated/decode-data-xml.js.map +1 -0
  27. package/dist/commonjs/generated/encode-html.d.ts +3 -0
  28. package/dist/commonjs/generated/encode-html.d.ts.map +1 -0
  29. package/dist/commonjs/generated/encode-html.js +14 -0
  30. package/dist/commonjs/generated/encode-html.js.map +1 -0
  31. package/dist/commonjs/index.d.ts +96 -0
  32. package/dist/commonjs/index.d.ts.map +1 -0
  33. package/dist/commonjs/index.js +131 -0
  34. package/dist/commonjs/index.js.map +1 -0
  35. package/dist/commonjs/internal/bin-trie-flags.d.ts +17 -0
  36. package/dist/commonjs/internal/bin-trie-flags.d.ts.map +1 -0
  37. package/dist/commonjs/internal/bin-trie-flags.js +21 -0
  38. package/dist/commonjs/internal/bin-trie-flags.js.map +1 -0
  39. package/dist/commonjs/internal/decode-shared.d.ts +2 -0
  40. package/dist/commonjs/internal/decode-shared.d.ts.map +1 -0
  41. package/dist/commonjs/internal/decode-shared.js +31 -0
  42. package/dist/commonjs/internal/decode-shared.js.map +1 -0
  43. package/dist/commonjs/internal/encode-shared.d.ts +32 -0
  44. package/dist/commonjs/internal/encode-shared.d.ts.map +1 -0
  45. package/dist/commonjs/internal/encode-shared.js +94 -0
  46. package/dist/commonjs/internal/encode-shared.js.map +1 -0
  47. package/dist/commonjs/package.json +3 -0
  48. package/dist/esm/decode-codepoint.d.ts +19 -0
  49. package/dist/esm/decode-codepoint.d.ts.map +1 -0
  50. package/dist/esm/decode-codepoint.js +72 -0
  51. package/dist/esm/decode-codepoint.js.map +1 -0
  52. package/dist/esm/decode.d.ts +205 -0
  53. package/dist/esm/decode.d.ts.map +1 -0
  54. package/dist/esm/decode.js +554 -0
  55. package/dist/esm/decode.js.map +1 -0
  56. package/dist/esm/encode.d.ts +22 -0
  57. package/dist/esm/encode.d.ts.map +1 -0
  58. package/dist/esm/encode.js +88 -0
  59. package/dist/esm/encode.js.map +1 -0
  60. package/dist/esm/escape.d.ts +46 -0
  61. package/dist/esm/escape.d.ts.map +1 -0
  62. package/dist/esm/escape.js +134 -0
  63. package/dist/esm/escape.js.map +1 -0
  64. package/dist/esm/generated/decode-data-html.d.ts +2 -0
  65. package/dist/esm/generated/decode-data-html.d.ts.map +1 -0
  66. package/dist/esm/generated/decode-data-html.js +4 -0
  67. package/dist/esm/generated/decode-data-html.js.map +1 -0
  68. package/dist/esm/generated/decode-data-xml.d.ts +2 -0
  69. package/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
  70. package/dist/esm/generated/decode-data-xml.js +4 -0
  71. package/dist/esm/generated/decode-data-xml.js.map +1 -0
  72. package/dist/esm/generated/encode-html.d.ts +3 -0
  73. package/dist/esm/generated/encode-html.d.ts.map +1 -0
  74. package/dist/esm/generated/encode-html.js +11 -0
  75. package/dist/esm/generated/encode-html.js.map +1 -0
  76. package/dist/esm/index.d.ts +96 -0
  77. package/dist/esm/index.d.ts.map +1 -0
  78. package/dist/esm/index.js +107 -0
  79. package/dist/esm/index.js.map +1 -0
  80. package/dist/esm/internal/bin-trie-flags.d.ts +17 -0
  81. package/dist/esm/internal/bin-trie-flags.d.ts.map +1 -0
  82. package/dist/esm/internal/bin-trie-flags.js +18 -0
  83. package/dist/esm/internal/bin-trie-flags.js.map +1 -0
  84. package/dist/esm/internal/decode-shared.d.ts +2 -0
  85. package/dist/esm/internal/decode-shared.d.ts.map +1 -0
  86. package/dist/esm/internal/decode-shared.js +28 -0
  87. package/dist/esm/internal/decode-shared.js.map +1 -0
  88. package/dist/esm/internal/encode-shared.d.ts +32 -0
  89. package/dist/esm/internal/encode-shared.d.ts.map +1 -0
  90. package/dist/esm/internal/encode-shared.js +91 -0
  91. package/dist/esm/internal/encode-shared.js.map +1 -0
  92. package/dist/esm/package.json +3 -0
  93. package/escape.d.ts +3 -0
  94. package/escape.js +3 -0
  95. package/package.json +106 -49
  96. package/readme.md +109 -16
  97. package/src/decode-codepoint.ts +81 -0
  98. package/src/decode.ts +685 -0
  99. package/src/encode.ts +93 -0
  100. package/src/escape.ts +161 -0
  101. package/src/generated/.eslintrc.json +10 -0
  102. package/src/generated/decode-data-html.ts +6 -0
  103. package/src/generated/decode-data-xml.ts +6 -0
  104. package/src/generated/encode-html.ts +17 -0
  105. package/src/index.ts +187 -0
  106. package/src/internal/bin-trie-flags.ts +16 -0
  107. package/src/internal/decode-shared.ts +30 -0
  108. package/src/internal/encode-shared.ts +121 -0
  109. package/lib/decode.d.ts +0 -7
  110. package/lib/decode.d.ts.map +0 -1
  111. package/lib/decode.js +0 -54
  112. package/lib/decode_codepoint.d.ts +0 -2
  113. package/lib/decode_codepoint.d.ts.map +0 -1
  114. package/lib/decode_codepoint.js +0 -24
  115. package/lib/encode.d.ts +0 -4
  116. package/lib/encode.d.ts.map +0 -1
  117. package/lib/encode.js +0 -73
  118. package/lib/index.d.ts +0 -24
  119. package/lib/index.d.ts.map +0 -1
  120. package/lib/index.js +0 -52
  121. package/lib/maps/decode.json +0 -1
  122. package/lib/maps/entities.json +0 -1
  123. package/lib/maps/legacy.json +0 -1
  124. package/lib/maps/xml.json +0 -1
package/readme.md CHANGED
@@ -1,7 +1,20 @@
1
- # 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)
1
+ # entities [![NPM version](https://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) [![Node.js CI](https://github.com/fb55/entities/actions/workflows/nodejs-test.yml/badge.svg)](https://github.com/fb55/entities/actions/workflows/nodejs-test.yml)
2
2
 
3
3
  Encode & decode HTML & XML entities with ease & speed.
4
4
 
5
+ ## Features
6
+
7
+ - 😇 Tried and true: `entities` is used by many popular libraries; eg.
8
+ [`htmlparser2`](https://github.com/fb55/htmlparser2), the official
9
+ [AWS SDK](https://github.com/aws/aws-sdk-js-v3) and
10
+ [`commonmark`](https://github.com/commonmark/commonmark.js) use it to process
11
+ HTML entities.
12
+ - ⚡️ Fast: `entities` is the fastest library for decoding HTML entities (as of
13
+ September 2025); see [performance](#performance).
14
+ - 🎛 Configurable: Get an output tailored for your needs. You are fine with
15
+ UTF8? That'll save you some bytes. Prefer to only have ASCII characters? We
16
+ can do that as well!
17
+
5
18
  ## How to…
6
19
 
7
20
  ### …install `entities`
@@ -13,26 +26,100 @@ Encode & decode HTML & XML entities with ease & speed.
13
26
  ```javascript
14
27
  const entities = require("entities");
15
28
 
16
- //encoding
17
- entities.escape("&"); // "&"
18
- entities.encodeXML("&"); // "&"
19
- entities.encodeHTML("&"); // "&"
29
+ // Encoding
30
+ entities.escapeUTF8("& ü"); // "& ü"
31
+ entities.encodeXML("& ü"); // "& ü"
32
+ entities.encodeHTML("& ü"); // "& ü"
20
33
 
21
- //decoding
34
+ // Decoding
22
35
  entities.decodeXML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
23
36
  entities.decodeHTML("asdf & ÿ ü '"); // "asdf & ÿ ü '"
24
37
  ```
25
38
 
26
39
  ## Performance
27
40
 
28
- This is how `entities` compares to other libraries on a very basic benchmark (see `scripts/benchmark.ts`, for 10,000,000 iterations):
41
+ Benchmarked in September 2025 with Node v24.6.0 on Apple M2 using `tinybench`.
42
+ Higher ops/s is better; `avg (μs)` is the mean time per operation.
43
+ See `scripts/benchmark.ts` to reproduce.
44
+
45
+ ### Decoding
46
+
47
+ | Library | Version | ops/s | avg (μs) | ±% | slower |
48
+ | -------------- | ------- | --------- | -------- | ---- | ------ |
49
+ | entities | 7.0.0 | 5,838,416 | 175.57 | 0.06 | — |
50
+ | html-entities | 2.6.0 | 2,919,637 | 347.77 | 0.33 | 50.0% |
51
+ | he | 1.2.0 | 2,318,438 | 446.48 | 0.70 | 60.3% |
52
+ | parse-entities | 4.0.2 | 852,855 | 1,199.51 | 0.36 | 85.4% |
53
+
54
+ ### Encoding
55
+
56
+ | Library | Version | ops/s | avg (μs) | ±% | slower |
57
+ | -------------- | ------- | --------- | -------- | ---- | ------ |
58
+ | entities | 7.0.0 | 2,770,115 | 368.09 | 0.11 | — |
59
+ | html-entities | 2.6.0 | 1,491,963 | 679.96 | 0.58 | 46.2% |
60
+ | he | 1.2.0 | 481,278 | 2,118.25 | 0.61 | 82.6% |
61
+
62
+ ### Escaping
63
+
64
+ | Library | Version | ops/s | avg (μs) | ±% | slower |
65
+ | -------------- | ------- | --------- | -------- | ---- | ------ |
66
+ | entities | 7.0.0 | 4,616,468 | 223.84 | 0.17 | — |
67
+ | he | 1.2.0 | 3,659,301 | 280.76 | 0.58 | 20.7% |
68
+ | html-entities | 2.6.0 | 3,555,301 | 296.63 | 0.84 | 23.0% |
69
+
70
+ Note: Micro-benchmarks may vary across machines and Node versions.
71
+
72
+ ---
73
+
74
+ ## FAQ
75
+
76
+ > What methods should I actually use to encode my documents?
77
+
78
+ If your target supports UTF-8, the `escapeUTF8` method is going to be your best
79
+ choice. Otherwise, use either `encodeHTML` or `encodeXML` based on whether
80
+ you're dealing with an HTML or an XML document.
81
+
82
+ You can have a look at the options for the `encode` and `decode` methods to see
83
+ everything you can configure.
84
+
85
+ > When should I use strict decoding?
86
+
87
+ When strict decoding, entities not terminated with a semicolon will be ignored.
88
+ This is helpful for decoding entities in legacy environments.
89
+
90
+ > Why should I use `entities` instead of alternative modules?
91
+
92
+ As of September 2025, `entities` is faster than other modules. Still, this is
93
+ not a differentiated space and other modules can catch up.
94
+
95
+ **More importantly**, you might already have `entities` in your dependency graph
96
+ (as a dependency of eg. `cheerio`, or `htmlparser2`), and including it directly
97
+ might not even increase your bundle size. The same is true for other entity
98
+ libraries, so have a look through your `node_modules` directory!
99
+
100
+ > Does `entities` support tree shaking?
101
+
102
+ Yes! `entities` ships as both a CommonJS and a ES module. Note that for best
103
+ results, you should not use the `encode` and `decode` functions, as they wrap
104
+ around a number of other functions, all of which will remain in the bundle.
105
+ Instead, use the functions that you need directly.
106
+
107
+ ---
108
+
109
+ ## Acknowledgements
110
+
111
+ This library wouldn't be possible without the work of these individuals. Thanks
112
+ to
29
113
 
30
- | Library | `decode` performance | `encode` performance | Bundle size |
31
- | -------------- | -------------------- | -------------------- | -------------------------------------------------------------------------- |
32
- | entities | 10.809s | 17.683s | ![npm bundle size](https://img.shields.io/bundlephobia/min/entities) |
33
- | html-entities | 14.029s | 22.670s | ![npm bundle size](https://img.shields.io/bundlephobia/min/html-entities) |
34
- | he | 16.163s | 44.010s | ![npm bundle size](https://img.shields.io/bundlephobia/min/he) |
35
- | parse-entities | 28.507s | N/A | ![npm bundle size](https://img.shields.io/bundlephobia/min/parse-entities) |
114
+ - [@mathiasbynens](https://github.com/mathiasbynens) for his explanations about
115
+ character encodings, and his library `he`, which was one of the inspirations
116
+ for `entities`
117
+ - [@inikulin](https://github.com/inikulin) for his work on optimized tries for
118
+ decoding HTML entities for the `parse5` project
119
+ - [@mdevils](https://github.com/mdevils) for taking on the challenge of
120
+ producing a quick entity library with his `html-entities` library. `entities`
121
+ would be quite a bit slower if there wasn't any competition. Right now
122
+ `entities` is on top, but we'll see how long that lasts!
36
123
 
37
124
  ---
38
125
 
@@ -40,11 +127,17 @@ License: BSD-2-Clause
40
127
 
41
128
  ## Security contact information
42
129
 
43
- To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
44
- Tidelift will coordinate the fix and disclosure.
130
+ To report a security vulnerability, please use the
131
+ [Tidelift security contact](https://tidelift.com/security). Tidelift will
132
+ coordinate the fix and disclosure.
45
133
 
46
134
  ## `entities` for enterprise
47
135
 
48
136
  Available as part of the Tidelift Subscription
49
137
 
50
- The maintainers of `entities` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-entities?utm_source=npm-entities&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
138
+ The maintainers of `entities` and thousands of other packages are working with
139
+ Tidelift to deliver commercial support and maintenance for the open source
140
+ dependencies you use to build your applications. Save time, reduce risk, and
141
+ improve code health, while paying the maintainers of the exact dependencies you
142
+ use.
143
+ [Learn more.](https://tidelift.com/subscription/pkg/npm-entities?utm_source=npm-entities&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
@@ -0,0 +1,81 @@
1
+ // Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
2
+
3
+ const decodeMap = new Map([
4
+ [0, 65_533],
5
+ // C1 Unicode control character reference replacements
6
+ [128, 8364],
7
+ [130, 8218],
8
+ [131, 402],
9
+ [132, 8222],
10
+ [133, 8230],
11
+ [134, 8224],
12
+ [135, 8225],
13
+ [136, 710],
14
+ [137, 8240],
15
+ [138, 352],
16
+ [139, 8249],
17
+ [140, 338],
18
+ [142, 381],
19
+ [145, 8216],
20
+ [146, 8217],
21
+ [147, 8220],
22
+ [148, 8221],
23
+ [149, 8226],
24
+ [150, 8211],
25
+ [151, 8212],
26
+ [152, 732],
27
+ [153, 8482],
28
+ [154, 353],
29
+ [155, 8250],
30
+ [156, 339],
31
+ [158, 382],
32
+ [159, 376],
33
+ ]);
34
+
35
+ /**
36
+ * Polyfill for `String.fromCodePoint`. It is used to create a string from a Unicode code point.
37
+ */
38
+ export const fromCodePoint: (...codePoints: number[]) => string =
39
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, n/no-unsupported-features/es-builtins
40
+ String.fromCodePoint ??
41
+ ((codePoint: number): string => {
42
+ let output = "";
43
+
44
+ if (codePoint > 0xff_ff) {
45
+ codePoint -= 0x1_00_00;
46
+ output += String.fromCharCode(
47
+ ((codePoint >>> 10) & 0x3_ff) | 0xd8_00,
48
+ );
49
+ codePoint = 0xdc_00 | (codePoint & 0x3_ff);
50
+ }
51
+
52
+ output += String.fromCharCode(codePoint);
53
+ return output;
54
+ });
55
+
56
+ /**
57
+ * Replace the given code point with a replacement character if it is a
58
+ * surrogate or is outside the valid range. Otherwise return the code
59
+ * point unchanged.
60
+ */
61
+ export function replaceCodePoint(codePoint: number): number {
62
+ if (
63
+ (codePoint >= 0xd8_00 && codePoint <= 0xdf_ff) ||
64
+ codePoint > 0x10_ff_ff
65
+ ) {
66
+ return 0xff_fd;
67
+ }
68
+
69
+ return decodeMap.get(codePoint) ?? codePoint;
70
+ }
71
+
72
+ /**
73
+ * Replace the code point if relevant, then convert it to a string.
74
+ *
75
+ * @deprecated Use `fromCodePoint(replaceCodePoint(codePoint))` instead.
76
+ * @param codePoint The code point to decode.
77
+ * @returns The decoded code point.
78
+ */
79
+ export function decodeCodePoint(codePoint: number): string {
80
+ return fromCodePoint(replaceCodePoint(codePoint));
81
+ }