npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

js-char-escape

v1.0.9

Published

A fork of the jsec repository returns the shortest possible stringified & ASCII-safe representation of that data.

Downloads

6

Readme

js-char-escape Build status

Given some data, js-char-escape returns a stringified representation of that data to help prevent [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) Attacks in your application). js-char-escape is a fork of jsesc with a few additions such as exclude & excludeAccented.

js-char-escape is similar to JSON.stringify() except:

  1. it outputs JavaScript instead of JSON by default, enabling support for data structures like ES6 maps and sets;
  2. it offers many options to customize the output;
  3. its output is ASCII-safe by default, thanks to its use of escape sequences where needed.

For any input, js-char-escape generates the shortest possible valid printable-ASCII-only output. Here’s an online demo.

js-char-escape’s output can be used instead of JSON.stringify’s to avoid mojibake and other encoding issues, or even to avoid errors when passing JSON-formatted data (which may contain U+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATOR, or lone surrogates) to a JavaScript parser or an UTF-8 encoder.

Installation

Via npm:

npm install js-char-escape

In Node.js:

const js-char-escape = require('js-char-escape');

API

js-char-escape(value, options)

This function takes a value and returns an escaped version of the value where any characters that are not printable ASCII symbols are escaped using the shortest possible (but valid) escape sequences for use in JavaScript strings. The first supported value type is strings:

js-char-escape('Ich ♥ Bücher');
// → 'Ich \\u2665 B\\xFCcher'

js-char-escape('foo 𝌆 bar');
// → 'foo \\uD834\\uDF06 bar'

Instead of a string, the value can also be an array, an object, a map, a set, or a buffer. In such cases, js-char-escape returns a stringified version of the value where any characters that are not printable ASCII symbols are escaped in the same way.

// Escaping an array
js-char-escape([
  'Ich ♥ Bücher', 'foo 𝌆 bar'
]);
// → '[\'Ich \\u2665 B\\xFCcher\',\'foo \\uD834\\uDF06 bar\']'

// Escaping an object
js-char-escape({
  'Ich ♥ Bücher': 'foo 𝌆 bar'
});
// → '{\'Ich \\u2665 B\\xFCcher\':\'foo \\uD834\\uDF06 bar\'}'

The optional options argument accepts an object with the following options:

quotes

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-char-escape('`Lorem` ipsum "dolor" sit \'amet\' etc.');
// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.'

js-char-escape('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'single'
});
// → '`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-char-escape('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'double'
});
// → '`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-char-escape('`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:

js-char-escape({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'quotes': 'double'
});
// → '{"Ich \\u2665 B\\xFCcher":"foo \\uD834\\uDF06 bar"}'

js-char-escape([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'quotes': 'double'
});
// → '["Ich \\u2665 B\\xFCcher","foo \\uD834\\uDF06 bar"]'

numbers

The default value for the numbers option is 'decimal'. This means that any numeric values are represented using decimal integer literals. Other valid options are binary, octal, and hexadecimal, which result in binary integer literals, octal integer literals, and hexadecimal integer literals, respectively.

js-char-escape(42, {
  'numbers': 'binary'
});
// → '0b101010'

js-char-escape(42, {
  'numbers': 'octal'
});
// → '0o52'

js-char-escape(42, {
  'numbers': 'decimal'
});
// → '42'

js-char-escape(42, {
  'numbers': 'hexadecimal'
});
// → '0x2A'

wrap

The wrap option takes a boolean value (true or false), and defaults to false (disabled). When enabled, the output is a valid JavaScript string literal wrapped in quotes. The type of quotes can be specified through the quotes setting.

js-char-escape('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'single',
  'wrap': true
});
// → '\'Lorem ipsum "dolor" sit \\\'amet\\\' etc.\''
// → "\'Lorem ipsum \"dolor\" sit \\\'amet\\\' etc.\'"

js-char-escape('Lorem ipsum "dolor" sit \'amet\' etc.', {
  'quotes': 'double',
  'wrap': true
});
// → '"Lorem ipsum \\"dolor\\" sit \'amet\' etc."'
// → "\"Lorem ipsum \\\"dolor\\\" sit \'amet\' etc.\""

es6

The es6 option takes a boolean value (true or false), and defaults to false (disabled). When enabled, any astral Unicode symbols in the input are escaped using ECMAScript 6 Unicode code point escape sequences instead of using separate escape sequences for each surrogate half. If backwards compatibility with ES5 environments is a concern, don’t enable this setting. If the json setting is enabled, the value for the es6 setting is ignored (as if it was false).

// By default, the `es6` option is disabled:
js-char-escape('foo 𝌆 bar 💩 baz');
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz'

// To explicitly disable it:
js-char-escape('foo 𝌆 bar 💩 baz', {
  'es6': false
});
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz'

// To enable it:
js-char-escape('foo 𝌆 bar 💩 baz', {
  'es6': true
});
// → 'foo \\u{1D306} bar \\u{1F4A9} baz'

escapeEverything

The escapeEverything option takes a boolean value (true or false), and defaults to false (disabled). When enabled, all the symbols in the output are escaped — even printable ASCII symbols.

js-char-escape('lolwat"foo\'bar', {
  'escapeEverything': true
});
// → '\\x6C\\x6F\\x6C\\x77\\x61\\x74\\"\\x66\\x6F\\x6F\\\'\\x62\\x61\\x72'
// → "\\x6C\\x6F\\x6C\\x77\\x61\\x74\\\"\\x66\\x6F\\x6F\\'\\x62\\x61\\x72"

This setting also affects the output for string literals within arrays and objects.

minimal

The minimal option takes a boolean value (true or false), and defaults to false (disabled). When enabled, only a limited set of symbols in the output are escaped:

  • U+0000 \0
  • U+0008 \b
  • U+0009 \t
  • U+000A \n
  • U+000C \f
  • U+000D \r
  • U+005C \\
  • U+2028 \u2028
  • U+2029 \u2029
  • whatever symbol is being used for wrapping string literals (based on the quotes option)

Note: with this option enabled, js-char-escape output is no longer guaranteed to be ASCII-safe.

js-char-escape('foo\u2029bar\nbaz©qux𝌆flops', {
  'minimal': false
});
// → 'foo\\u2029bar\\nbaz©qux𝌆flops'

isScriptContext

The isScriptContext option takes a boolean value (true or false), and defaults to false (disabled). When enabled, occurrences of </script and </style in the output are escaped as <\/script and <\/style, and <!-- is escaped as \x3C!-- (or \u003C!-- when the json option is enabled). This setting is useful when js-char-escape’s output ends up as part of a <script> or <style> element in an HTML document.

js-char-escape('foo</script>bar', {
  'isScriptContext': true
});
// → 'foo<\\/script>bar'

compact

The compact option takes a boolean value (true or false), and defaults to true (enabled). When enabled, the output for arrays and objects is as compact as possible; it’s not formatted nicely.

js-char-escape({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': true // this is the default
});
// → '{\'Ich \u2665 B\xFCcher\':\'foo \uD834\uDF06 bar\'}'

js-char-escape({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false
});
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'

js-char-escape([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'compact': false
});
// → '[\n\t\'Ich \u2665 B\xFCcher\',\n\t\'foo \uD834\uDF06 bar\'\n]'

This setting has no effect on the output for strings.

indent

The indent option takes a string value, and defaults to '\t'. When the compact setting is enabled (true), the value of the indent option is used to format the output for arrays and objects.

js-char-escape({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false,
  'indent': '\t' // this is the default
});
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'

js-char-escape({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
  'compact': false,
  'indent': '  '
});
// → '{\n  \'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'

js-char-escape([ 'Ich ♥ Bücher', 'foo 𝌆 bar' ], {
  'compact': false,
  'indent': '  '
});
// → '[\n  \'Ich \u2665 B\xFCcher\',\n\  t\'foo \uD834\uDF06 bar\'\n]'

This setting has no effect on the output for strings.

indentLevel

The indentLevel option takes a numeric value, and defaults to 0. It represents the current indentation level, i.e. the number of times the value of the indent option is repeated.

js-char-escape(['a', 'b', 'c'], {
  'compact': false,
  'indentLevel': 1
});
// → '[\n\t\t\'a\',\n\t\t\'b\',\n\t\t\'c\'\n\t]'

js-char-escape(['a', 'b', 'c'], {
  'compact': false,
  'indentLevel': 2
});
// → '[\n\t\t\t\'a\',\n\t\t\t\'b\',\n\t\t\t\'c\'\n\t\t]'

json

The json option takes a boolean value (true or false), and defaults to false (disabled). When enabled, the output is valid JSON. Hexadecimal character escape sequences and the \v or \0 escape sequences are not used. Setting json: true implies quotes: 'double', wrap: true, es6: false, although these values can still be overridden if needed — but in such cases, the output won’t be valid JSON anymore.

js-char-escape('foo\x00bar\xFF\uFFFDbaz', {
  'json': true
});
// → '"foo\\u0000bar\\u00FF\\uFFFDbaz"'

js-char-escape({ 'foo\x00bar\xFF\uFFFDbaz': 'foo\x00bar\xFF\uFFFDbaz' }, {
  'json': true
});
// → '{"foo\\u0000bar\\u00FF\\uFFFDbaz":"foo\\u0000bar\\u00FF\\uFFFDbaz"}'

js-char-escape([ 'foo\x00bar\xFF\uFFFDbaz', 'foo\x00bar\xFF\uFFFDbaz' ], {
  'json': true
});
// → '["foo\\u0000bar\\u00FF\\uFFFDbaz","foo\\u0000bar\\u00FF\\uFFFDbaz"]'

// Values that are acceptable in JSON but aren’t strings, arrays, or object
// literals can’t be escaped, so they’ll just be preserved:
js-char-escape([ 'foo\x00bar', [1, '©', { 'foo': true, 'qux': null }], 42 ], {
  'json': true
});
// → '["foo\\u0000bar",[1,"\\u00A9",{"foo":true,"qux":null}],42]'
// Values that aren’t allowed in JSON are run through `JSON.stringify()`:
js-char-escape([ undefined, -Infinity ], {
  'json': true
});
// → '[null,null]'

Note: Using this option on objects or arrays that contain non-string values relies on JSON.stringify(). For legacy environments like IE ≤ 7, use a JSON polyfill.

lowercaseHex

The lowercaseHex option takes a boolean value (true or false), and defaults to false (disabled). When enabled, any alphabetical hexadecimal digits in escape sequences as well as any hexadecimal integer literals (see the numbers option) in the output are in lowercase.

js-char-escape('Ich ♥ Bücher', {
  'lowercaseHex': true
});
// → 'Ich \\u2665 B\\xfccher'
//                    ^^

js-char-escape(42, {
  'numbers': 'hexadecimal',
  'lowercaseHex': true
});
// → '0x2a'
//      ^^

exclude

The exclude option takes a String value for example "ä", and ignores any characters when doing ght escaping.

js-char-escape('käfer', {
  'isScriptContext': true,
  'exclude': 'ä'
});
// → 'käfer'

excludeAccented

The excludeAccented option takes a boolean value which defaults to false. Setting it to true ignores all of the following characters àáâäæãåāèéêëēėęîïíīįìôöòóœøōõûüùúūßśšçćčÿłžźżñńğ.

js-char-escape('àáâäæãåāèéêëēėęîïíīįìôöòóœøōõûüùúūßśšçćčÿłžźżñńğ', {
  'isScriptContext': true,
  'excludeAccented': true
});
// → 'àáâäæãåāèéêëēėęîïíīįìôöòóœøōõûüùúūßśšçćčÿłžźżñńğ'

js-char-escape.version

A string representing the semantic version number.

Using the js-char-escape binary

To use the js-char-escape binary in your shell, simply install js-char-escape globally using npm:

npm install -g js-char-escape

After that you’re able to escape strings from the command line:

$ js-char-escape 'föo ♥ bår 𝌆 baz'
f\xF6o \u2665 b\xE5r \uD834\uDF06 baz

To escape arrays or objects containing string values, use the -o/--object option:

$ js-char-escape --object '{ "föo": "♥", "bår": "𝌆 baz" }'
{'f\xF6o':'\u2665','b\xE5r':'\uD834\uDF06 baz'}

To prettify the output in such cases, use the -p/--pretty option:

$ js-char-escape --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
{
  'f\xF6o': '\u2665',
  'b\xE5r': '\uD834\uDF06 baz'
}

For valid JSON output, use the -j/--json option:

$ js-char-escape --json --pretty '{ "föo": "♥", "bår": "𝌆 baz" }'
{
  "f\u00F6o": "\u2665",
  "b\u00E5r": "\uD834\uDF06 baz"
}

Read a local JSON file, escape any non-ASCII symbols, and save the result to a new file:

$ js-char-escape --json --object < data-raw.json > data-escaped.json

Or do the same with an online JSON file:

$ curl -sL "http://git.io/aorKgQ" | js-char-escape --json --object > data-escaped.json

See js-char-escape --help for the full list of options.

Support

js-char-escape supports Node.js v6+ only.

Original Author

| twitter/mathias | |---| | Mathias Bynens |

License

This library is available under the MIT license.