source: node_modules/unraw/dist/index.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 7.5 KB
RevLine 
[d24f17c]1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.unraw = exports.errorMessages = exports.ErrorType = void 0;
4const errors_1 = require("./errors");
5Object.defineProperty(exports, "ErrorType", { enumerable: true, get: function () { return errors_1.ErrorType; } });
6Object.defineProperty(exports, "errorMessages", { enumerable: true, get: function () { return errors_1.errorMessages; } });
7/**
8 * Parse a string as a base-16 number. This is more strict than `parseInt` as it
9 * will not allow any other characters, including (for example) "+", "-", and
10 * ".".
11 * @param hex A string containing a hexadecimal number.
12 * @returns The parsed integer, or `NaN` if the string is not a valid hex
13 * number.
14 */
15function parseHexToInt(hex) {
16 const isOnlyHexChars = !hex.match(/[^a-f0-9]/i);
17 return isOnlyHexChars ? parseInt(hex, 16) : NaN;
18}
19/**
20 * Check the validity and length of a hexadecimal code and optionally enforces
21 * a specific number of hex digits.
22 * @param hex The string to validate and parse.
23 * @param errorName The name of the error message to throw a `SyntaxError` with
24 * if `hex` is invalid. This is used to index `errorMessages`.
25 * @param enforcedLength If provided, will throw an error if `hex` is not
26 * exactly this many characters.
27 * @returns The parsed hex number as a normal number.
28 * @throws {SyntaxError} If the code is not valid.
29 */
30function validateAndParseHex(hex, errorName, enforcedLength) {
31 const parsedHex = parseHexToInt(hex);
32 if (Number.isNaN(parsedHex) ||
33 (enforcedLength !== undefined && enforcedLength !== hex.length)) {
34 throw new SyntaxError(errors_1.errorMessages.get(errorName));
35 }
36 return parsedHex;
37}
38/**
39 * Parse a two-digit hexadecimal character escape code.
40 * @param code The two-digit hexadecimal number that represents the character to
41 * output.
42 * @returns The single character represented by the code.
43 * @throws {SyntaxError} If the code is not valid hex or is not the right
44 * length.
45 */
46function parseHexadecimalCode(code) {
47 const parsedCode = validateAndParseHex(code, errors_1.ErrorType.MalformedHexadecimal, 2);
48 return String.fromCharCode(parsedCode);
49}
50/**
51 * Parse a four-digit Unicode character escape code.
52 * @param code The four-digit unicode number that represents the character to
53 * output.
54 * @param surrogateCode Optional four-digit unicode surrogate that represents
55 * the other half of the character to output.
56 * @returns The single character represented by the code.
57 * @throws {SyntaxError} If the codes are not valid hex or are not the right
58 * length.
59 */
60function parseUnicodeCode(code, surrogateCode) {
61 const parsedCode = validateAndParseHex(code, errors_1.ErrorType.MalformedUnicode, 4);
62 if (surrogateCode !== undefined) {
63 const parsedSurrogateCode = validateAndParseHex(surrogateCode, errors_1.ErrorType.MalformedUnicode, 4);
64 return String.fromCharCode(parsedCode, parsedSurrogateCode);
65 }
66 return String.fromCharCode(parsedCode);
67}
68/**
69 * Test if the text is surrounded by curly braces (`{}`).
70 * @param text Text to check.
71 * @returns `true` if the text is in the form `{*}`.
72 */
73function isCurlyBraced(text) {
74 return text.charAt(0) === "{" && text.charAt(text.length - 1) === "}";
75}
76/**
77 * Parse a Unicode code point character escape code.
78 * @param codePoint A unicode escape code point, including the surrounding curly
79 * braces.
80 * @returns The single character represented by the code.
81 * @throws {SyntaxError} If the code is not valid hex or does not have the
82 * surrounding curly braces.
83 */
84function parseUnicodeCodePointCode(codePoint) {
85 if (!isCurlyBraced(codePoint)) {
86 throw new SyntaxError(errors_1.errorMessages.get(errors_1.ErrorType.MalformedUnicode));
87 }
88 const withoutBraces = codePoint.slice(1, -1);
89 const parsedCode = validateAndParseHex(withoutBraces, errors_1.ErrorType.MalformedUnicode);
90 try {
91 return String.fromCodePoint(parsedCode);
92 }
93 catch (err) {
94 throw err instanceof RangeError
95 ? new SyntaxError(errors_1.errorMessages.get(errors_1.ErrorType.CodePointLimit))
96 : err;
97 }
98}
99// Have to give overload that takes boolean for when compiler doesn't know if
100// true or false
101function parseOctalCode(code, error = false) {
102 if (error) {
103 throw new SyntaxError(errors_1.errorMessages.get(errors_1.ErrorType.OctalDeprecation));
104 }
105 // The original regex only allows digits so we don't need to have a strict
106 // octal parser like hexToInt. Length is not enforced for octals.
107 const parsedCode = parseInt(code, 8);
108 return String.fromCharCode(parsedCode);
109}
110/**
111 * Map of unescaped letters to their corresponding special JS escape characters.
112 * Intentionally does not include characters that map to themselves like "\'".
113 */
114const singleCharacterEscapes = new Map([
115 ["b", "\b"],
116 ["f", "\f"],
117 ["n", "\n"],
118 ["r", "\r"],
119 ["t", "\t"],
120 ["v", "\v"],
121 ["0", "\0"]
122]);
123/**
124 * Parse a single character escape sequence and return the matching character.
125 * If none is matched, defaults to `code`.
126 * @param code A single character code.
127 */
128function parseSingleCharacterCode(code) {
129 return singleCharacterEscapes.get(code) || code;
130}
131/**
132 * Matches every escape sequence possible, including invalid ones.
133 *
134 * All capture groups (described below) are unique (only one will match), except
135 * for 4, which can only potentially match if 3 does.
136 *
137 * **Capture Groups:**
138 * 0. A single backslash
139 * 1. Hexadecimal code
140 * 2. Unicode code point code with surrounding curly braces
141 * 3. Unicode escape code with surrogate
142 * 4. Surrogate code
143 * 5. Unicode escape code without surrogate
144 * 6. Octal code _NOTE: includes "0"._
145 * 7. A single character (will never be \, x, u, or 0-3)
146 */
147const escapeMatch = /\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g;
148/**
149 * Replace raw escape character strings with their escape characters.
150 * @param raw A string where escape characters are represented as raw string
151 * values like `\'` rather than `'`.
152 * @param allowOctals If `true`, will process the now-deprecated octal escape
153 * sequences (ie, `\111`).
154 * @returns The processed string, with escape characters replaced by their
155 * respective actual Unicode characters.
156 */
157function unraw(raw, allowOctals = false) {
158 return raw.replace(escapeMatch, function (_, backslash, hex, codePoint, unicodeWithSurrogate, surrogate, unicode, octal, singleCharacter) {
159 // Compare groups to undefined because empty strings mean different errors
160 // Otherwise, `\u` would fail the same as `\` which is wrong.
161 if (backslash !== undefined) {
162 return "\\";
163 }
164 if (hex !== undefined) {
165 return parseHexadecimalCode(hex);
166 }
167 if (codePoint !== undefined) {
168 return parseUnicodeCodePointCode(codePoint);
169 }
170 if (unicodeWithSurrogate !== undefined) {
171 return parseUnicodeCode(unicodeWithSurrogate, surrogate);
172 }
173 if (unicode !== undefined) {
174 return parseUnicodeCode(unicode);
175 }
176 if (octal === "0") {
177 return "\0";
178 }
179 if (octal !== undefined) {
180 return parseOctalCode(octal, !allowOctals);
181 }
182 if (singleCharacter !== undefined) {
183 return parseSingleCharacterCode(singleCharacter);
184 }
185 throw new SyntaxError(errors_1.errorMessages.get(errors_1.ErrorType.EndOfString));
186 });
187}
188exports.unraw = unraw;
189exports.default = unraw;
Note: See TracBrowser for help on using the repository browser.