[Pkg-javascript-commits] [node-jsesc] 01/05: New upstream version 2.5.1

Julien Puydt julien.puydt at laposte.net
Tue Jun 27 12:04:17 UTC 2017


This is an automated email from the git hooks/post-receive script.

jpuydt-guest pushed a commit to branch master
in repository node-jsesc.

commit 6fda25202f74f05b37834b5c4f89c9af1ee578f5
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Tue Jun 27 14:01:21 2017 +0200

    New upstream version 2.5.1
---
 README.md      | 35 +++++++++++++++++++++++++----------
 jsesc.js       | 54 +++++++++++++++++++++++++++++++++++-------------------
 package.json   | 11 ++++++++---
 src/jsesc.js   | 52 ++++++++++++++++++++++++++++++++++------------------
 tests/tests.js | 36 +++++++++++++++++++++++++++++++++---
 5 files changed, 135 insertions(+), 53 deletions(-)

diff --git a/README.md b/README.md
index 60ee6ba..aae2b13 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,14 @@
 # jsesc [![Build status](https://travis-ci.org/mathiasbynens/jsesc.svg?branch=master)](https://travis-ci.org/mathiasbynens/jsesc) [![Code coverage status](https://coveralls.io/repos/mathiasbynens/jsesc/badge.svg)](https://coveralls.io/r/mathiasbynens/jsesc) [![Dependency status](https://gemnasium.com/mathiasbynens/jsesc.svg)](https://gemnasium.com/mathiasbynens/jsesc)
 
-This is a JavaScript library for [escaping JavaScript strings](https://mathiasbynens.be/notes/javascript-escapes) while generating the shortest possible valid ASCII-only output. [Here’s an online demo.](https://mothereff.in/js-escapes)
+Given some data, _jsesc_ returns a stringified representation of that data. jsesc is similar to `JSON.stringify()` except:
 
-This can be used to avoid [mojibake](https://en.wikipedia.org/wiki/Mojibake) and other encoding issues, or even to [avoid errors](https://twitter.com/annevk/status/380000829643571200) when passing JSON-formatted data (which may contain U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR, or [lone surrogates](https://esdiscuss.org/topic/code-points-vs-unicode-scalar-values#content-14)) to a JavaScript parser or an UTF-8 encoder, respectively.
+1. it outputs JavaScript instead of JSON [by default](#json), enabling support for data structures like ES6 maps and sets;
+2. it offers [many options](#api) to customize the output;
+3. its output is ASCII-safe [by default](#minimal), thanks to its use of [escape sequences](https://mathiasbynens.be/notes/javascript-escapes) where needed.
 
-Feel free to fork if you see possible improvements!
+For any input, jsesc generates the shortest possible valid printable-ASCII-only output. [Here’s an online demo.](https://mothereff.in/js-escapes)
+
+jsesc’s output can be used instead of `JSON.stringify`’s to avoid [mojibake](https://en.wikipedia.org/wiki/Mojibake) and other encoding issues, or even to [avoid errors](https://twitter.com/annevk/status/380000829643571200) when passing JSON-formatted data (which may contain U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR, or [lone surrogates](https://esdiscuss.org/topic/code-points-vs-unicode-scalar-values#content-14)) to a JavaScript parser or an UTF-8 encoder.
 
 ## Installation
 
@@ -57,24 +61,35 @@ The optional `options` argument accepts an object with the following options:
 The default value for the `quotes` option is `'single'`. This means that any occurrences of `'` in the input string are escaped as `\'`, so that the output can be used in a string literal wrapped in single quotes.
 
 ```js
-jsesc('Lorem ipsum "dolor" sit \'amet\' etc.');
+jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.');
 // → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.'
 
-jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
+jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
   'quotes': 'single'
 });
-// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.'
-// → "Lorem ipsum \"dolor\" sit \\'amet\\' etc."
+// → '`Lorem` ipsum "dolor" sit \\\'amet\\\' etc.'
+// → "`Lorem` ipsum \"dolor\" sit \\'amet\\' etc."
 ```
 
 If you want to use the output as part of a string literal wrapped in double quotes, set the `quotes` option to `'double'`.
 
 ```js
-jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
+jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
   'quotes': 'double'
 });
-// → 'Lorem ipsum \\"dolor\\" sit \'amet\' etc.'
-// → "Lorem ipsum \\\"dolor\\\" sit 'amet' etc."
+// → '`Lorem` ipsum \\"dolor\\" sit \'amet\' etc.'
+// → "`Lorem` ipsum \\\"dolor\\\" sit 'amet' etc."
+```
+
+If you want to use the output as part of a template literal (i.e. wrapped in backticks), set the `quotes` option to `'backtick'`.
+
+```js
+jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
+  'quotes': 'backtick'
+});
+// → '\\`Lorem\\` ipsum "dolor" sit \'amet\' etc.'
+// → "\\`Lorem\\` ipsum \"dolor\" sit 'amet' etc."
+// → `\\\`Lorem\\\` ipsum "dolor" sit 'amet' etc.`
 ```
 
 This setting also affects the output for arrays and objects:
diff --git a/jsesc.js b/jsesc.js
index 37ab2bf..5052af3 100644
--- a/jsesc.js
+++ b/jsesc.js
@@ -2,7 +2,7 @@
 
 const object = {};
 const hasOwnProperty = object.hasOwnProperty;
-const forOwn = function(object, callback) {
+const forOwn = (object, callback) => {
 	for (const key in object) {
 		if (hasOwnProperty.call(object, key)) {
 			callback(key, object[key]);
@@ -10,17 +10,17 @@ const forOwn = function(object, callback) {
 	}
 };
 
-const extend = function(destination, source) {
+const extend = (destination, source) => {
 	if (!source) {
 		return destination;
 	}
-	forOwn(source, function(key, value) {
+	forOwn(source, (key, value) => {
 		destination[key] = value;
 	});
 	return destination;
 };
 
-const forEach = function(array, callback) {
+const forEach = (array, callback) => {
 	const length = array.length;
 	let index = -1;
 	while (++index < length) {
@@ -31,25 +31,25 @@ const forEach = function(array, callback) {
 const toString = object.toString;
 const isArray = Array.isArray;
 const isBuffer = Buffer.isBuffer;
-const isObject = function(value) {
+const isObject = (value) => {
 	// This is a very simple check, but it’s good enough for what we need.
 	return toString.call(value) == '[object Object]';
 };
-const isString = function(value) {
+const isString = (value) => {
 	return typeof value == 'string' ||
 		toString.call(value) == '[object String]';
 };
-const isNumber = function(value) {
+const isNumber = (value) => {
 	return typeof value == 'number' ||
 		toString.call(value) == '[object Number]';
 };
-const isFunction = function(value) {
+const isFunction = (value) => {
 	return typeof value == 'function';
 };
-const isMap = function(value) {
+const isMap = (value) => {
 	return toString.call(value) == '[object Map]';
 };
-const isSet = function(value) {
+const isSet = (value) => {
 	return toString.call(value) == '[object Set]';
 };
 
@@ -73,8 +73,8 @@ const regexSingleEscape = /["'\\\b\f\n\r\t]/;
 const regexDigit = /[0-9]/;
 const regexWhitelist = /[ !#-&\(-\[\]-~]/;
 
-const jsesc = function(argument, options) {
-	const increaseIndentation = function() {
+const jsesc = (argument, options) => {
+	const increaseIndentation = () => {
 		oldIndent = indent;
 		++options.indentLevel;
 		indent = options.indent.repeat(options.indentLevel)
@@ -102,10 +102,19 @@ const jsesc = function(argument, options) {
 		defaults.wrap = true;
 	}
 	options = extend(defaults, options);
-	if (options.quotes != 'single' && options.quotes != 'double') {
+	if (
+		options.quotes != 'single' &&
+		options.quotes != 'double' &&
+		options.quotes != 'backtick'
+	) {
 		options.quotes = 'single';
 	}
-	const quote = options.quotes == 'double' ? '"' : '\'';
+	const quote = options.quotes == 'double' ?
+		'"' :
+		(options.quotes == 'backtick' ?
+			'`' :
+			'\''
+		);
 	const compact = options.compact;
 	const lowercaseHex = options.lowercaseHex;
 	let indent = options.indent.repeat(options.indentLevel);
@@ -143,9 +152,9 @@ const jsesc = function(argument, options) {
 		}
 		if (isBuffer(argument)) {
 			if (argument.length == 0) {
-				return 'Buffer()';
+				return 'Buffer.from([])';
 			}
-			return 'Buffer(' + jsesc(Array.from(argument), options) + ')';
+			return 'Buffer.from(' + jsesc(Array.from(argument), options) + ')';
 		}
 		if (isArray(argument)) {
 			result = [];
@@ -157,7 +166,7 @@ const jsesc = function(argument, options) {
 			if (!inline2) {
 				increaseIndentation();
 			}
-			forEach(argument, function(value) {
+			forEach(argument, (value) => {
 				isEmpty = false;
 				if (inline2) {
 					options.__inline2__ = false;
@@ -208,7 +217,7 @@ const jsesc = function(argument, options) {
 			result = [];
 			options.wrap = true;
 			increaseIndentation();
-			forOwn(argument, function(key, value) {
+			forOwn(argument, (key, value) => {
 				isEmpty = false;
 				result.push(
 					(compact ? '' : indent) +
@@ -263,6 +272,10 @@ const jsesc = function(argument, options) {
 				result += quote == character ? '\\"' : character;
 				continue;
 			}
+			if (character == '`') {
+				result += quote == character ? '\\`' : character;
+				continue;
+			}
 			if (character == '\'') {
 				result += quote == character ? '\\\'' : character;
 				continue;
@@ -299,6 +312,9 @@ const jsesc = function(argument, options) {
 	if (options.wrap) {
 		result = quote + result + quote;
 	}
+	if (quote == '`') {
+		result = result.replace(/\$\{/g, '\\\$\{');
+	}
 	if (options.isScriptContext) {
 		// https://mathiasbynens.be/notes/etago
 		return result
@@ -308,6 +324,6 @@ const jsesc = function(argument, options) {
 	return result;
 };
 
-jsesc.version = '2.4.0';
+jsesc.version = '2.5.1';
 
 module.exports = jsesc;
diff --git a/package.json b/package.json
index 332eb06..9164f70 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "jsesc",
-  "version": "2.4.0",
-  "description": "A JavaScript library for escaping JavaScript strings while generating the shortest possible valid output.",
+  "version": "2.5.1",
+  "description": "Given some data, jsesc returns the shortest possible stringified & ASCII-safe representation of that data.",
   "homepage": "https://mths.be/jsesc",
   "engines": {
     "node": ">=4"
@@ -10,9 +10,14 @@
   "bin": "bin/jsesc",
   "man": "man/jsesc.1",
   "keywords": [
-    "string",
+    "buffer",
     "escape",
     "javascript",
+    "json",
+    "map",
+    "set",
+    "string",
+    "stringify",
     "tool"
   ],
   "license": "MIT",
diff --git a/src/jsesc.js b/src/jsesc.js
index 31b9e93..d3eaff1 100644
--- a/src/jsesc.js
+++ b/src/jsesc.js
@@ -2,7 +2,7 @@
 
 const object = {};
 const hasOwnProperty = object.hasOwnProperty;
-const forOwn = function(object, callback) {
+const forOwn = (object, callback) => {
 	for (const key in object) {
 		if (hasOwnProperty.call(object, key)) {
 			callback(key, object[key]);
@@ -10,17 +10,17 @@ const forOwn = function(object, callback) {
 	}
 };
 
-const extend = function(destination, source) {
+const extend = (destination, source) => {
 	if (!source) {
 		return destination;
 	}
-	forOwn(source, function(key, value) {
+	forOwn(source, (key, value) => {
 		destination[key] = value;
 	});
 	return destination;
 };
 
-const forEach = function(array, callback) {
+const forEach = (array, callback) => {
 	const length = array.length;
 	let index = -1;
 	while (++index < length) {
@@ -31,25 +31,25 @@ const forEach = function(array, callback) {
 const toString = object.toString;
 const isArray = Array.isArray;
 const isBuffer = Buffer.isBuffer;
-const isObject = function(value) {
+const isObject = (value) => {
 	// This is a very simple check, but it’s good enough for what we need.
 	return toString.call(value) == '[object Object]';
 };
-const isString = function(value) {
+const isString = (value) => {
 	return typeof value == 'string' ||
 		toString.call(value) == '[object String]';
 };
-const isNumber = function(value) {
+const isNumber = (value) => {
 	return typeof value == 'number' ||
 		toString.call(value) == '[object Number]';
 };
-const isFunction = function(value) {
+const isFunction = (value) => {
 	return typeof value == 'function';
 };
-const isMap = function(value) {
+const isMap = (value) => {
 	return toString.call(value) == '[object Map]';
 };
-const isSet = function(value) {
+const isSet = (value) => {
 	return toString.call(value) == '[object Set]';
 };
 
@@ -73,8 +73,8 @@ const regexSingleEscape = /["'\\\b\f\n\r\t]/;
 const regexDigit = /[0-9]/;
 const regexWhitelist = /<%= whitelist %>/;
 
-const jsesc = function(argument, options) {
-	const increaseIndentation = function() {
+const jsesc = (argument, options) => {
+	const increaseIndentation = () => {
 		oldIndent = indent;
 		++options.indentLevel;
 		indent = options.indent.repeat(options.indentLevel)
@@ -102,10 +102,19 @@ const jsesc = function(argument, options) {
 		defaults.wrap = true;
 	}
 	options = extend(defaults, options);
-	if (options.quotes != 'single' && options.quotes != 'double') {
+	if (
+		options.quotes != 'single' &&
+		options.quotes != 'double' &&
+		options.quotes != 'backtick'
+	) {
 		options.quotes = 'single';
 	}
-	const quote = options.quotes == 'double' ? '"' : '\'';
+	const quote = options.quotes == 'double' ?
+		'"' :
+		(options.quotes == 'backtick' ?
+			'`' :
+			'\''
+		);
 	const compact = options.compact;
 	const lowercaseHex = options.lowercaseHex;
 	let indent = options.indent.repeat(options.indentLevel);
@@ -143,9 +152,9 @@ const jsesc = function(argument, options) {
 		}
 		if (isBuffer(argument)) {
 			if (argument.length == 0) {
-				return 'Buffer()';
+				return 'Buffer.from([])';
 			}
-			return 'Buffer(' + jsesc(Array.from(argument), options) + ')';
+			return 'Buffer.from(' + jsesc(Array.from(argument), options) + ')';
 		}
 		if (isArray(argument)) {
 			result = [];
@@ -157,7 +166,7 @@ const jsesc = function(argument, options) {
 			if (!inline2) {
 				increaseIndentation();
 			}
-			forEach(argument, function(value) {
+			forEach(argument, (value) => {
 				isEmpty = false;
 				if (inline2) {
 					options.__inline2__ = false;
@@ -208,7 +217,7 @@ const jsesc = function(argument, options) {
 			result = [];
 			options.wrap = true;
 			increaseIndentation();
-			forOwn(argument, function(key, value) {
+			forOwn(argument, (key, value) => {
 				isEmpty = false;
 				result.push(
 					(compact ? '' : indent) +
@@ -263,6 +272,10 @@ const jsesc = function(argument, options) {
 				result += quote == character ? '\\"' : character;
 				continue;
 			}
+			if (character == '`') {
+				result += quote == character ? '\\`' : character;
+				continue;
+			}
 			if (character == '\'') {
 				result += quote == character ? '\\\'' : character;
 				continue;
@@ -299,6 +312,9 @@ const jsesc = function(argument, options) {
 	if (options.wrap) {
 		result = quote + result + quote;
 	}
+	if (quote == '`') {
+		result = result.replace(/\$\{/g, '\\\$\{');
+	}
 	if (options.isScriptContext) {
 		// https://mathiasbynens.be/notes/etago
 		return result
diff --git a/tests/tests.js b/tests/tests.js
index 6c8e10c..4c8ae84 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -38,6 +38,30 @@ describe('common usage', function() {
 			'Invalid `quotes` setting'
 		);
 		assert.equal(
+			jsesc('foo${1+1}', {
+				'quotes': 'backtick'
+			}),
+			'foo\\${1+1}',
+			'`quotes: \'backtick\'`'
+		);
+		assert.equal(
+			jsesc('foo${1+1}', {
+				'quotes': 'backtick',
+				'wrap': true
+			}),
+			'`foo\\${1+1}`',
+			'`quotes: \'backtick\'` + `wrap: true`'
+		);
+		assert.equal(
+			jsesc('foo${1+1}</script>', {
+				'quotes': 'backtick',
+				'wrap': true,
+				'isScriptContext': true
+			}),
+			'`foo\\${1+1}<\\/script>`',
+			'`quotes: \'backtick\'` + `wrap: true` + `isScriptContext: true`'
+		);
+		assert.equal(
 			jsesc('\\x00'),
 			'\\\\x00',
 			'`\\\\x00` shouldn’t be changed to `\\\\0`'
@@ -358,7 +382,7 @@ describe('common usage', function() {
 			jsesc(
 				Buffer([0x13, 0x37, 0x42])
 			),
-			'Buffer([19,55,66])',
+			'Buffer.from([19,55,66])',
 			'Stringifying a Buffer'
 		);
 		assert.equal(
@@ -368,7 +392,7 @@ describe('common usage', function() {
 					'compact': false
 				}
 			),
-			'Buffer([\n\t19,\n\t55,\n\t66\n])',
+			'Buffer.from([\n\t19,\n\t55,\n\t66\n])',
 			'Stringifying a Buffer with `compact: false`'
 		);
 		// JSON
@@ -553,6 +577,12 @@ describe('advanced tests', function() {
 			'All Unicode symbols, space-separated, single quotes'
 		);
 		assert.ok(
+			eval('`' + jsesc(allSymbols, {
+				'quotes': 'backtick'
+			}) + '`') == allSymbols,
+			'All Unicode symbols, space-separated, template literal'
+		);
+		assert.ok(
 			eval(jsesc(allSymbols, {
 				'quotes': 'single',
 				'wrap': true
@@ -605,5 +635,5 @@ describe('advanced tests', function() {
 			'[\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\tnull,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\tnull,\n\t"str",\n\tnull,\n\tnull,\n\ttrue,\n\ttrue,\n\tfalse,\n\tfalse,\n\t{\n\t\t"foo": 42,\n\t\t"hah": [\n\t\t\t1,\n\t\t\t2,\n\t\t\t3,\n\t\t\t{\n\t\t\t\t"foo": 42\n\t\t\t}\n\t\t]\n\t}\n]',
 			'Escaping a non-flat array with all kinds of values, with `json: true, compact: false`'
 		);
-	}).timeout(15000);
+	}).timeout(25000);
 });

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-jsesc.git



More information about the Pkg-javascript-commits mailing list