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
JavaScript
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;