[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