UNPKG

jsesc-es

Version:

Given some data, jsesc returns the shortest possible stringified & ASCII-safe representation of that data.

225 lines (222 loc) 7.94 kB
Object.defineProperty(exports, '__esModule', { value: true }); //#region src/version.ts const version = "1.0.2"; //#endregion //#region src/jsesc-es.ts const object = {}; const hasOwnProperty = object.hasOwnProperty; function forOwn(object$1, callback) { for (const key in object$1) if (hasOwnProperty.call(object$1, key)) callback(key, object$1[key]); } function extend(destination, source) { if (!source) return destination; forOwn(source, function(key, value) { destination[key] = value; }); return destination; } function forEach(array, callback) { const length = array.length; let index = -1; while (++index < length) callback(array[index]); } function fourHexEscape(hex) { return `\\u${`0000${hex}`.slice(-4)}`; } function hexadecimal(code, lowercase) { const hexadecimal$1 = code.toString(16); if (lowercase) return hexadecimal$1; return hexadecimal$1.toUpperCase(); } const toString = object.toString; const isArray = Array.isArray; function isBuffer(value) { return globalThis.Buffer && globalThis.Buffer.isBuffer && globalThis.Buffer.isBuffer(value); } function isObject(value) { return toString.call(value) === "[object Object]"; } function isString(value) { return typeof value === "string" || toString.call(value) === "[object String]"; } function isNumber(value) { return typeof value === "number" || toString.call(value) === "[object Number]"; } function isBigInt(value) { return typeof value === "bigint"; } function isFunction(value) { return typeof value === "function"; } function isMap(value) { return toString.call(value) === "[object Map]"; } function isSet(value) { return toString.call(value) === "[object Set]"; } const singleEscapes = { "\\": "\\\\", "\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", " ": "\\t" }; const regexSingleEscape = /[\\\b\f\n\r\t]/; const regexDigit = /\d/; const regexWhitespace = /[\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/; const escapeEverythingRegex = new RegExp("([\\uD800-\\uDBFF][\\uDC00-\\uDFFF])|([\\uD800-\\uDFFF])|(['`\"])|[\\s\\S]", "g"); const escapeNonAsciiRegex = new RegExp("([\\uD800-\\uDBFF][\\uDC00-\\uDFFF])|([\\uD800-\\uDFFF])|(['`\"])|[^ !\\u0023-\\u0026\\u0028-\\u005B\\u005D-\\u005F\\u0061-\\u007E]", "g"); function jsesc(argument, options = {}) { let oldIndent; let indent; const increaseIndentation = function() { oldIndent = indent; ++options.indentLevel; indent = options.indent.repeat(options.indentLevel); }; const defaults = { escapeEverything: false, minimal: false, isScriptContext: false, quotes: "single", wrap: false, es6: false, json: false, compact: true, lowercaseHex: false, numbers: "decimal", indent: " ", indentLevel: 0, __inline1__: false, __inline2__: false }; const json = options && options.json; if (json) { defaults.quotes = "double"; defaults.wrap = true; } options = extend(defaults, options); if (options.quotes !== "single" && options.quotes !== "double" && options.quotes !== "backtick") options.quotes = "single"; const quote = options.quotes === "double" ? "\"" : options.quotes === "backtick" ? "`" : "'"; const compact = options.compact; const lowercaseHex = options.lowercaseHex; indent = options.indent.repeat(options.indentLevel); oldIndent = ""; const inline1 = options.__inline1__; const inline2 = options.__inline2__; const newLine = compact ? "" : "\n"; let result; let isEmpty = true; const useBinNumbers = options.numbers === "binary"; const useOctNumbers = options.numbers === "octal"; const useDecNumbers = options.numbers === "decimal"; const useHexNumbers = options.numbers === "hexadecimal"; if (json && argument && typeof argument === "object" && argument !== null && "toJSON" in argument) { const objectWithToJSON = argument; if (isFunction(objectWithToJSON.toJSON)) argument = objectWithToJSON.toJSON(); } if (!isString(argument)) { if (isMap(argument)) { if (argument.size === 0) return "new Map()"; if (!compact) { options.__inline1__ = true; options.__inline2__ = false; } return `new Map(${jsesc(Array.from(argument), options)})`; } if (isSet(argument)) { if (argument.size === 0) return "new Set()"; return `new Set(${jsesc(Array.from(argument), options)})`; } if (isBuffer(argument)) { if (argument.length === 0) return "Buffer.from([])"; return `Buffer.from(${jsesc(Array.from(argument), options)})`; } if (isArray(argument)) { result = []; options.wrap = true; if (inline1) { options.__inline1__ = false; options.__inline2__ = true; } if (!inline2) increaseIndentation(); forEach(argument, function(value) { isEmpty = false; if (inline2) options.__inline2__ = false; result.push((compact || inline2 ? "" : indent) + jsesc(value, options)); }); if (isEmpty) return "[]"; if (inline2) return `[${result.join(", ")}]`; return `[${newLine}${result.join(`,${newLine}`)}${newLine}${compact ? "" : oldIndent}]`; } else if (isNumber(argument) || isBigInt(argument)) { if (json) return JSON.stringify(Number(argument)); let result$1; const numericValue = argument; if (useDecNumbers) result$1 = String(numericValue); else if (useHexNumbers) { let hexadecimal$1 = numericValue.toString(16); if (!lowercaseHex) hexadecimal$1 = hexadecimal$1.toUpperCase(); result$1 = `0x${hexadecimal$1}`; } else if (useBinNumbers) result$1 = `0b${numericValue.toString(2)}`; else if (useOctNumbers) result$1 = `0o${numericValue.toString(8)}`; if (isBigInt(argument)) return `${result$1}n`; return result$1; } else if (isBigInt(argument)) { if (json) return JSON.stringify(Number(argument)); return `${argument}n`; } else if (!isObject(argument)) { if (json) return JSON.stringify(argument) || "null"; if (isFunction(argument)) { let funcStr = String(argument).replace(/\s+/g, " "); funcStr = funcStr.replace(/"/g, "'"); return funcStr; } return String(argument); } else { result = []; options.wrap = true; increaseIndentation(); forOwn(argument, function(key, value) { isEmpty = false; result.push(`${(compact ? "" : indent) + jsesc(key, options)}:${compact ? "" : " "}${jsesc(value, options)}`); }); if (isEmpty) return "{}"; return `{${newLine}${result.join(`,${newLine}`)}${newLine}${compact ? "" : oldIndent}}`; } } const regex = options.escapeEverything ? escapeEverythingRegex : escapeNonAsciiRegex; result = argument.replace(regex, function(char, pair, lone, quoteChar, index, string) { if (pair) { if (options.minimal) return pair; const first = pair.charCodeAt(0); const second = pair.charCodeAt(1); if (options.es6) { const codePoint = (first - 55296) * 1024 + second - 56320 + 65536; const hex$1 = hexadecimal(codePoint, lowercaseHex); return `\\u{${hex$1}}`; } return fourHexEscape(hexadecimal(first, lowercaseHex)) + fourHexEscape(hexadecimal(second, lowercaseHex)); } if (lone) return fourHexEscape(hexadecimal(lone.charCodeAt(0), lowercaseHex)); if (char === "\0" && !json && !regexDigit.test(string.charAt(index + 1))) return "\\0"; if (quoteChar) { if (quoteChar === quote || options.escapeEverything) return `\\${quoteChar}`; return quoteChar; } if (regexSingleEscape.test(char)) return singleEscapes[char]; if (options.minimal && !regexWhitespace.test(char)) return char; const hex = hexadecimal(char.charCodeAt(0), lowercaseHex); if (json || hex.length > 2) return fourHexEscape(hex); return `\\x${`00${hex}`.slice(-2)}`; }); if (quote === "`") result = result.replace(/\$\{/g, "\\${"); if (options.isScriptContext) result = result.replace(new RegExp("<\\/(script|style)", "gi"), "<\\/$1").replace(/<!--/g, json ? "\\u003C!--" : "\\x3C!--"); if (options.wrap) result = quote + result + quote; return result; } jsesc.version = version; //#endregion exports.default = jsesc; exports.jsesc = jsesc; exports.version = version;