@dmail/uneval
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -7,332 +7,10 @@ "use strict"; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var _index = require("./primitive/index.js"); | ||
// https://github.com/jsenv/core/blob/959e76068b62c23d7047f6a8c7a3d6582ac25177/src/api/util/uneval.js | ||
// https://github.com/joliss/js-string-escape/blob/master/index.js | ||
// http://javascript.crockford.com/remedial.html | ||
var quote = function quote(value) { | ||
var string = String(value); | ||
var i = 0; | ||
var j = string.length; | ||
var escapedString = ""; | ||
while (i < j) { | ||
var char = string[i]; | ||
var escapedChar = void 0; | ||
if (char === '"' || char === "'" || char === "\\") { | ||
escapedChar = "\\".concat(char); | ||
} else if (char === "\n") { | ||
escapedChar = "\\n"; | ||
} else if (char === "\r") { | ||
escapedChar = "\\r"; | ||
} else if (char === "\u2028") { | ||
escapedChar = "\\u2028"; | ||
} else if (char === "\u2029") { | ||
escapedChar = "\\u2029"; | ||
} else { | ||
escapedChar = char; | ||
} | ||
escapedString += escapedChar; | ||
i++; | ||
Object.defineProperty(exports, "uneval", { | ||
enumerable: true, | ||
get: function get() { | ||
return _index.unevalPrimitive; | ||
} | ||
return escapedString; | ||
}; | ||
var getPrimitiveType = function getPrimitiveType(value) { | ||
if (value === null) { | ||
return "null"; | ||
} | ||
if (value === undefined) { | ||
return "undefined"; | ||
} | ||
return _typeof(value); | ||
}; | ||
var toString = Object.prototype.toString; | ||
var getCompositeType = function getCompositeType(object) { | ||
var toStringResult = toString.call(object); // returns format is '[object ${tagName}]'; | ||
// and we want ${tagName} | ||
var tagName = toStringResult.slice("[object ".length, -1); | ||
if (tagName === "Object") { | ||
var objectConstructorName = object.constructor.name; | ||
if (objectConstructorName !== "Object") { | ||
return objectConstructorName; | ||
} | ||
} | ||
return tagName; | ||
}; | ||
var hasOwnProperty = Object.prototype.hasOwnProperty; | ||
function getPropertyNames(value) { | ||
var names = []; | ||
for (var name in value) { | ||
if (hasOwnProperty.call(value, name)) { | ||
names.push(name); | ||
} | ||
} | ||
return names; | ||
} | ||
var newLineAndIndentation = function newLineAndIndentation(indent) { | ||
return "\n" + "\t".repeat(indent); | ||
}; // eslint-disable-line prefer-template | ||
var primitiveSources = {}; | ||
var compositeSources = {}; | ||
Object.assign(primitiveSources, { | ||
boolean: function boolean(_boolean) { | ||
return _boolean.toString(); | ||
}, | ||
function: function _function(fn, _ref) { | ||
var format = _ref.format, | ||
skipFunctionBody = _ref.skipFunctionBody; | ||
if (skipFunctionBody) { | ||
return fn.name ? "function ".concat(fn.name) : "function"; | ||
} | ||
return format(fn.toString()); | ||
}, | ||
null: function _null() { | ||
return "null"; | ||
}, | ||
number: function number(_number) { | ||
return _number.toString(); | ||
}, | ||
object: function object(_object, _ref2) { | ||
var unevalComposite = _ref2.unevalComposite; | ||
return unevalComposite(getCompositeType(_object), _object); | ||
}, | ||
string: function string(_string) { | ||
return "\"".concat(quote(_string), "\""); | ||
}, | ||
symbol: function symbol(_symbol, _ref3) { | ||
var format = _ref3.format; | ||
return format("symbol"); | ||
}, | ||
undefined: function undefined() { | ||
return "undefined"; | ||
} | ||
}); | ||
var unevalInstance = function unevalInstance(instance, _ref4) { | ||
var type = _ref4.type, | ||
uneval = _ref4.uneval, | ||
format = _ref4.format; | ||
return format("".concat(type, "(").concat(uneval(instance.valueOf()), ")")); | ||
}; | ||
Object.assign(compositeSources, { | ||
Array: function Array(array, _ref5) { | ||
var seen = _ref5.seen, | ||
depth = _ref5.depth, | ||
uneval = _ref5.uneval, | ||
format = _ref5.format, | ||
pretty = _ref5.pretty; | ||
if (seen) { | ||
if (seen.indexOf(array) > -1) { | ||
return "[]"; | ||
} | ||
seen.push(array); | ||
} else { | ||
seen = [array]; | ||
} | ||
depth = depth ? depth + 1 : 1; | ||
var valuesSource = ""; | ||
var i = 0; | ||
var j = array.length; | ||
while (i < j) { | ||
var valueSource = uneval(array[i], { | ||
seen: seen, | ||
depth: depth | ||
}); | ||
if (pretty) { | ||
if (i === 0) { | ||
valuesSource += valueSource; | ||
} else { | ||
valuesSource += ",".concat(newLineAndIndentation(depth)).concat(valueSource); | ||
} | ||
} else if (i === 0) { | ||
valuesSource += valueSource; | ||
} else { | ||
valuesSource += ", ".concat(valueSource); | ||
} | ||
i++; | ||
} | ||
var arraySource = void 0; | ||
if (valuesSource.length) { | ||
if (pretty) { | ||
arraySource = "[".concat(newLineAndIndentation(depth)).concat(valuesSource).concat(newLineAndIndentation(depth - 1), "]"); | ||
} else { | ||
arraySource = "[".concat(valuesSource, "]"); | ||
} | ||
} else { | ||
arraySource = "[]"; | ||
} | ||
return format(arraySource); | ||
}, | ||
Boolean: unevalInstance, | ||
Date: unevalInstance, | ||
Error: function Error(error, _ref6) { | ||
var expose = _ref6.expose; | ||
return unevalInstance(error.message, expose({ | ||
type: error.name | ||
})); | ||
}, | ||
Number: unevalInstance, | ||
RegExp: function RegExp(regexp) { | ||
return regexp.toString(); | ||
}, | ||
Object: function Object(object, _ref7) { | ||
var seen = _ref7.seen, | ||
depth = _ref7.depth, | ||
uneval = _ref7.uneval, | ||
format = _ref7.format, | ||
pretty = _ref7.pretty; | ||
if (seen) { | ||
if (seen.indexOf(object) > -1) { | ||
return "{}"; | ||
} | ||
seen.push(object); | ||
} else { | ||
seen = [object]; | ||
} | ||
depth = depth ? depth + 1 : 1; | ||
var propertiesSource = ""; | ||
var propertyNames = getPropertyNames(object); | ||
var i = 0; | ||
var j = propertyNames.length; | ||
while (i < j) { | ||
var propertyName = propertyNames[i]; | ||
var propertyNameSource = uneval(propertyName); | ||
var propertyValueSource = uneval(object[propertyName], { | ||
seen: seen, | ||
depth: depth | ||
}); | ||
if (pretty) { | ||
if (i === 0) { | ||
propertiesSource += "".concat(propertyNameSource, ": ").concat(propertyValueSource); | ||
} else { | ||
propertiesSource += ",".concat(newLineAndIndentation(depth)).concat(propertyNameSource, ": ").concat(propertyValueSource); | ||
} | ||
} else if (i === 0) { | ||
propertiesSource += "".concat(propertyNameSource, ": ").concat(propertyValueSource); | ||
} else { | ||
propertiesSource += ", ".concat(propertyNameSource, ": ").concat(propertyValueSource); | ||
} | ||
i++; | ||
} | ||
var objectSource = void 0; | ||
if (propertiesSource.length) { | ||
if (pretty) { | ||
objectSource = "{".concat(newLineAndIndentation(depth)).concat(propertiesSource).concat(newLineAndIndentation(depth - 1), "}"); | ||
} else { | ||
objectSource = "{ ".concat(propertiesSource, " }"); | ||
} | ||
} else { | ||
objectSource = "{}"; | ||
} | ||
return format(objectSource); | ||
}, | ||
String: unevalInstance, | ||
// Symbol: (symbol, { unevalPrimitive }) => unevalPrimitive("symbol", symbol), | ||
// ici faudrais désactiver les parenthèses jusque pour l'object qu'on uneval | ||
// mais préserver la valeur par défaut pour ceux qui sont nested | ||
Other: function Other(object, _ref8) { | ||
var type = _ref8.type, | ||
format = _ref8.format, | ||
unevalComposite = _ref8.unevalComposite; | ||
return format("".concat(type, "(").concat(unevalComposite("Object", object), ")")); | ||
} | ||
}); | ||
var uneval = exports.uneval = function uneval(value) { | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { | ||
parenthesis: false, | ||
new: false, | ||
skipFunctionBody: true, | ||
pretty: true | ||
}; | ||
var expose = function expose() { | ||
for (var _len = arguments.length, properties = Array(_len), _key = 0; _key < _len; _key++) { | ||
properties[_key] = arguments[_key]; | ||
} | ||
return Object.assign.apply(Object, [{}, options].concat(properties)); | ||
}; | ||
var localUneval = function localUneval(value) { | ||
var localOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
return uneval(value, expose(localOptions)); | ||
}; | ||
var format = function format(string) { | ||
var formattedString = string; | ||
if (options.parenthesis) { | ||
formattedString = "(".concat(string, ")"); | ||
} | ||
if (options.new) { | ||
formattedString = "new ".concat(formattedString); | ||
} | ||
return formattedString; | ||
}; | ||
var unevalPrimitive = function unevalPrimitive(type, value) { | ||
return primitiveSources[type](value, expose({ | ||
type: type | ||
})); | ||
}; | ||
var unevalComposite = function unevalComposite(type, value) { | ||
var handlerType = type in compositeSources ? type : "Other"; | ||
return compositeSources[handlerType](value, expose({ | ||
type: type | ||
})); | ||
}; | ||
Object.assign(options, { | ||
expose: expose, | ||
uneval: localUneval, | ||
format: format, | ||
unevalPrimitive: unevalPrimitive, | ||
unevalComposite: unevalComposite | ||
}); | ||
return unevalPrimitive(getPrimitiveType(value), value); | ||
}; | ||
//# sourceMappingURL=uneval.js.map |
@@ -11,43 +11,31 @@ "use strict"; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
var expectUneval = function expectUneval(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value), expectedUneval); | ||
return _assert2["default"].equal((0, _uneval.uneval)(value), expectedUneval); | ||
}; | ||
var expectUnevalShort = function expectUnevalShort(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value, { | ||
pretty: false | ||
}), expectedUneval); | ||
var expectUnevalCompact = function expectUnevalCompact(value, expectedUneval) { | ||
return _assert2["default"].equal((0, _uneval.uneval)(value, { compact: true }), expectedUneval); | ||
}; | ||
var expectUnevalWithNew = function expectUnevalWithNew(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value, { | ||
new: true | ||
}), expectedUneval); | ||
return _assert2["default"].equal((0, _uneval.uneval)(value, { useNew: true }), expectedUneval); | ||
}; | ||
var expectUnevalWithParenthesis = function expectUnevalWithParenthesis(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value, { | ||
parenthesis: true | ||
}), expectedUneval); | ||
return _assert2["default"].equal((0, _uneval.uneval)(value, { parenthesis: true }), expectedUneval); | ||
}; | ||
var expectUnevalWithNewAndParenthesis = function expectUnevalWithNewAndParenthesis(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value, { | ||
parenthesis: true, | ||
new: true | ||
}), expectedUneval); | ||
return _assert2["default"].equal((0, _uneval.uneval)(value, { parenthesis: true, useNew: true }), expectedUneval); | ||
}; | ||
var expectUnevalWithFunctionBody = function expectUnevalWithFunctionBody(value, expectedUneval) { | ||
return _assert2.default.equal((0, _uneval.uneval)(value, { | ||
skipFunctionBody: false | ||
}), expectedUneval); | ||
return _assert2["default"].equal((0, _uneval.uneval)(value, { showFunctionBody: true }), expectedUneval); | ||
}; | ||
/* eslint-disable no-new-wrappers, no-new-object, no-array-constructor */ | ||
(0, _testCheap.test)("uneval.js", function (_ref) { | ||
var ensure = _ref.ensure; | ||
ensure("boolean uneval", function () { | ||
@@ -61,9 +49,8 @@ expectUneval(true, "true"); | ||
}); | ||
ensure("arrow function", function () { | ||
expectUneval(function () {}, "function"); | ||
var named = function named() {}; | ||
expectUneval(named, "function named"); | ||
expectUnevalWithFunctionBody(named, "function named() {}"); // because of babel most function body are converted back to regular function | ||
expectUnevalWithFunctionBody(named, "function named() {}"); | ||
@@ -75,7 +62,9 @@ expectUnevalWithFunctionBody(function () {}, "function () {}"); | ||
}); | ||
ensure("function", function () {// no need, arrow function are enougth | ||
}); | ||
ensure("function", function () {}); | ||
ensure("null", function () { | ||
expectUneval(null, "null"); | ||
}); | ||
ensure("number/Number", function () { | ||
@@ -89,2 +78,3 @@ expectUneval(0, "0"); | ||
}); | ||
ensure("object/Object", function () { | ||
@@ -94,8 +84,7 @@ var emptyObject = {}; | ||
expectUneval(new Object({}), "{}"); | ||
var foo = { | ||
foo: true, | ||
bar: false | ||
}; | ||
expectUneval(foo, "{\n\t\"foo\": true,\n\t\"bar\": false\n}"); | ||
expectUnevalShort(foo, "{ \"foo\": true, \"bar\": false }"); | ||
var foo = { foo: true, bar: false }; | ||
expectUneval(foo, "{\n \"foo\": true,\n \"bar\": false\n}"); | ||
expectUnevalCompact(foo, "{\"foo\": true, \"bar\": false}"); | ||
var objectWithInheritedEnumerableProperty = Object.create({ | ||
@@ -105,9 +94,7 @@ foo: true | ||
expectUneval(objectWithInheritedEnumerableProperty, "{}"); | ||
var nested = { | ||
foo: { | ||
name: "dam" | ||
} | ||
}; | ||
expectUneval(nested, "{\n\t\"foo\": {\n\t\t\"name\": \"dam\"\n\t}\n}"); | ||
expectUnevalShort(nested, "{ \"foo\": { \"name\": \"dam\" } }"); | ||
var nested = { foo: { name: "dam" } }; | ||
expectUneval(nested, "{\n \"foo\": {\n \"name\": \"dam\"\n }\n}"); | ||
expectUnevalCompact(nested, "{\"foo\": {\"name\": \"dam\"}}"); | ||
var circularObject = { | ||
@@ -117,3 +104,4 @@ foo: true | ||
circularObject.self = circularObject; | ||
expectUneval(circularObject, "{\n\t\"foo\": true,\n\t\"self\": {}\n}"); | ||
expectUneval(circularObject, "{\n \"foo\": true,\n \"self\": Symbol.for('circular')\n}"); | ||
var nestedCircularObject = { | ||
@@ -126,4 +114,5 @@ foo: true | ||
}; | ||
expectUneval(nestedCircularObject, "{\n\t\"foo\": true,\n\t\"nested\": {\n\t\t\"bar\": true,\n\t\t\"parent\": {}\n\t}\n}"); | ||
expectUneval(nestedCircularObject, "{\n \"foo\": true,\n \"nested\": {\n \"bar\": true,\n \"parent\": Symbol.for('circular')\n }\n}"); | ||
}); | ||
ensure("string/String", function () { | ||
@@ -141,8 +130,11 @@ expectUneval("", "\"\""); | ||
}); | ||
ensure("symbol/Symbol", function () { | ||
expectUneval(Symbol(), "symbol"); | ||
expectUneval(Symbol(), "Symbol"); | ||
}); | ||
ensure("undefined", function () { | ||
expectUneval(undefined, "undefined"); | ||
}); | ||
ensure("regexp/Regexp", function () { | ||
@@ -152,2 +144,3 @@ expectUneval(/ok/g, "/ok/g"); | ||
}); | ||
ensure("Error", function () { | ||
@@ -157,27 +150,33 @@ expectUneval(new Error("here"), "Error(\"here\")"); | ||
}); | ||
ensure("Date", function () { | ||
expectUneval(new Date(), "Date(".concat(Date.now(), ")")); | ||
expectUneval(new Date(), "Date(" + Date.now() + ")"); | ||
}); | ||
ensure("Custom instance", function () { | ||
var CustomConstructor = function CustomConstructor() { | ||
this.foo = true; | ||
}; | ||
var customInstance = new CustomConstructor(); | ||
expectUneval(customInstance, "CustomConstructor({\n \"foo\": true\n})"); | ||
}); | ||
ensure("literal array/Array", function () { | ||
var emptyArray = []; | ||
expectUneval(emptyArray, "[]"); | ||
var newArray = new Array("foo", 1); | ||
expectUneval(newArray, "[\n\t\"foo\",\n\t1\n]"); | ||
expectUnevalShort(newArray, "[\"foo\", 1]"); | ||
expectUneval(newArray, "[\n \"foo\",\n 1\n]"); | ||
expectUnevalCompact(newArray, "[\"foo\", 1]"); | ||
var nestedArray = [[]]; | ||
expectUnevalShort(nestedArray, "[[]]"); | ||
expectUnevalCompact(nestedArray, "[[]]"); | ||
var circularArray = [0]; | ||
circularArray.push(circularArray); | ||
expectUneval(circularArray, "[\n\t0,\n\t[]\n]"); // other instance | ||
expectUneval(circularArray, "[\n 0,\n Symbol.for('circular')\n]"); | ||
var CustomConstructor = function CustomConstructor() { | ||
this.foo = true; | ||
}; | ||
var customInstance = new CustomConstructor(); | ||
expectUneval(customInstance, "CustomConstructor({\n\t\"foo\": true\n})"); | ||
expectUneval([Symbol()], "[\n\tsymbol\n]"); | ||
expectUneval([Symbol()], "[\n Symbol\n]"); | ||
}); | ||
}); | ||
/* eslint-enable no-new-wrappers, no-new-object */ | ||
//# sourceMappingURL=uneval.test.js.map |
{ | ||
"name": "@dmail/uneval", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"license": "MIT", | ||
@@ -16,3 +16,4 @@ "repository": { | ||
"dist", | ||
"src" | ||
"src", | ||
"index.js" | ||
], | ||
@@ -26,5 +27,5 @@ "engines": { | ||
"@dmail/prettiest": "0.2.1", | ||
"@dmail/shared-config": "1.1.1", | ||
"@dmail/test-cheap": "0.0.2", | ||
"babel-cli": "7.0.0-beta.0", | ||
"@dmail/shared-config": "5.0.0", | ||
"@dmail/test-cheap": "0.2.0", | ||
"babel-cli": "6.26.0", | ||
"babel-core": "7.0.0-beta.0", | ||
@@ -37,3 +38,3 @@ "babel-eslint": "8.0.0", | ||
"nyc": "11.2.1", | ||
"prettier": "1.7.0", | ||
"prettier": "1.9.1", | ||
"rimraf": "2.6.2" | ||
@@ -48,5 +49,5 @@ }, | ||
"code-format": "prettiest", | ||
"code-list": "prettiest-list", | ||
"test-before": "npm run code-clean && npm run code-lint && npm run code-format && npm run code-compile", | ||
"test-list": "test-list", | ||
"code-list": "prettiest-list", | ||
"test-before": "npm run code-lint && npm run code-format && npm run code-compile", | ||
"test-run": "test-run", | ||
@@ -60,2 +61,3 @@ "test": "npm run test-before && npm run test-run", | ||
"test-cover-lcov": "nyc report --reporter=text-lcov > coverage.lcov", | ||
"test-cover-upload": "codecov --token=7e0621a2-dbc9-485d-a150-3870d30ba3ae", | ||
"repo-reset": "npm run code-clean && npm run test-cover-clean && rimraf node_modules", | ||
@@ -62,0 +64,0 @@ "repo-reinstall": "npm run repo-reset && npm install", |
# uneval | ||
[![npm](https://badge.fury.io/js/%40dmail%2Funeval.svg)](https://badge.fury.io/js/%40dmail%2Funeval) | ||
[![build](https://travis-ci.org/dmail/uneval.svg)](http://travis-ci.org/dmail/uneval) | ||
[![build](https://travis-ci.org/dmail/uneval.svg?branch=master)](http://travis-ci.org/dmail/uneval) | ||
[![codecov](https://codecov.io/gh/dmail/uneval/branch/master/graph/badge.svg)](https://codecov.io/gh/dmail/uneval) | ||
Turn JavaScript values into their source strings | ||
> Turn JavaScript values into source strings | ||
## Installing / Getting started | ||
```shell | ||
npm install @dmail/uneval | ||
``` | ||
```javascript | ||
import { uneval } from "@dmail/uneval" | ||
console.log( | ||
uneval({ | ||
string: "dmail", | ||
number: 10, | ||
date: new Date(), | ||
regExp: /ok/, | ||
}), | ||
) | ||
``` | ||
Executing above code logs in the console | ||
```javascript | ||
{ | ||
"string": "dmail", | ||
"number": 10, | ||
"date": Date(1527257307798), | ||
"regExp": /ok/ | ||
} | ||
``` | ||
## Style guide | ||
Prettier and eslint are used to ensure code style and format | ||
## API | ||
* [api documentation](./docs/api.md) | ||
## Licensing | ||
MIT |
// https://github.com/jsenv/core/blob/959e76068b62c23d7047f6a8c7a3d6582ac25177/src/api/util/uneval.js | ||
// https://github.com/joliss/js-string-escape/blob/master/index.js | ||
// http://javascript.crockford.com/remedial.html | ||
const quote = value => { | ||
const string = String(value) | ||
let i = 0 | ||
const j = string.length | ||
var escapedString = "" | ||
while (i < j) { | ||
const char = string[i] | ||
let escapedChar | ||
if (char === '"' || char === "'" || char === "\\") { | ||
escapedChar = `\\${char}` | ||
} else if (char === "\n") { | ||
escapedChar = "\\n" | ||
} else if (char === "\r") { | ||
escapedChar = "\\r" | ||
} else if (char === "\u2028") { | ||
escapedChar = "\\u2028" | ||
} else if (char === "\u2029") { | ||
escapedChar = "\\u2029" | ||
} else { | ||
escapedChar = char | ||
} | ||
escapedString += escapedChar | ||
i++ | ||
} | ||
return escapedString | ||
} | ||
const getPrimitiveType = value => { | ||
if (value === null) { | ||
return "null" | ||
} | ||
if (value === undefined) { | ||
return "undefined" | ||
} | ||
return typeof value | ||
} | ||
const toString = Object.prototype.toString | ||
const getCompositeType = object => { | ||
const toStringResult = toString.call(object) | ||
// returns format is '[object ${tagName}]'; | ||
// and we want ${tagName} | ||
const tagName = toStringResult.slice("[object ".length, -1) | ||
if (tagName === "Object") { | ||
const objectConstructorName = object.constructor.name | ||
if (objectConstructorName !== "Object") { | ||
return objectConstructorName | ||
} | ||
} | ||
return tagName | ||
} | ||
const hasOwnProperty = Object.prototype.hasOwnProperty | ||
function getPropertyNames(value) { | ||
const names = [] | ||
for (let name in value) { | ||
if (hasOwnProperty.call(value, name)) { | ||
names.push(name) | ||
} | ||
} | ||
return names | ||
} | ||
const newLineAndIndentation = indent => "\n" + "\t".repeat(indent) // eslint-disable-line prefer-template | ||
const primitiveSources = {} | ||
const compositeSources = {} | ||
Object.assign(primitiveSources, { | ||
boolean: boolean => boolean.toString(), | ||
function: (fn, { format, skipFunctionBody }) => { | ||
if (skipFunctionBody) { | ||
return fn.name ? `function ${fn.name}` : "function" | ||
} | ||
return format(fn.toString()) | ||
}, | ||
null: () => "null", | ||
number: number => number.toString(), | ||
object: (object, { unevalComposite }) => unevalComposite(getCompositeType(object), object), | ||
string: string => `"${quote(string)}"`, | ||
symbol: (symbol, { format }) => format("symbol"), | ||
undefined: () => "undefined" | ||
}) | ||
const unevalInstance = (instance, { type, uneval, format }) => | ||
format(`${type}(${uneval(instance.valueOf())})`) | ||
Object.assign(compositeSources, { | ||
Array: (array, { seen, depth, uneval, format, pretty }) => { | ||
if (seen) { | ||
if (seen.indexOf(array) > -1) { | ||
return "[]" | ||
} | ||
seen.push(array) | ||
} else { | ||
seen = [array] | ||
} | ||
depth = depth ? depth + 1 : 1 | ||
let valuesSource = "" | ||
let i = 0 | ||
const j = array.length | ||
while (i < j) { | ||
const valueSource = uneval(array[i], { seen, depth }) | ||
if (pretty) { | ||
if (i === 0) { | ||
valuesSource += valueSource | ||
} else { | ||
valuesSource += `,${newLineAndIndentation(depth)}${valueSource}` | ||
} | ||
} else if (i === 0) { | ||
valuesSource += valueSource | ||
} else { | ||
valuesSource += `, ${valueSource}` | ||
} | ||
i++ | ||
} | ||
let arraySource | ||
if (valuesSource.length) { | ||
if (pretty) { | ||
arraySource = `[${newLineAndIndentation(depth)}${valuesSource}${newLineAndIndentation( | ||
depth - 1 | ||
)}]` | ||
} else { | ||
arraySource = `[${valuesSource}]` | ||
} | ||
} else { | ||
arraySource = "[]" | ||
} | ||
return format(arraySource) | ||
}, | ||
Boolean: unevalInstance, | ||
Date: unevalInstance, | ||
Error: (error, { expose }) => unevalInstance(error.message, expose({ type: error.name })), | ||
Number: unevalInstance, | ||
RegExp: regexp => regexp.toString(), | ||
Object: (object, { seen, depth, uneval, format, pretty }) => { | ||
if (seen) { | ||
if (seen.indexOf(object) > -1) { | ||
return "{}" | ||
} | ||
seen.push(object) | ||
} else { | ||
seen = [object] | ||
} | ||
depth = depth ? depth + 1 : 1 | ||
let propertiesSource = "" | ||
const propertyNames = getPropertyNames(object) | ||
let i = 0 | ||
const j = propertyNames.length | ||
while (i < j) { | ||
const propertyName = propertyNames[i] | ||
const propertyNameSource = uneval(propertyName) | ||
const propertyValueSource = uneval(object[propertyName], { seen, depth }) | ||
if (pretty) { | ||
if (i === 0) { | ||
propertiesSource += `${propertyNameSource}: ${propertyValueSource}` | ||
} else { | ||
propertiesSource += `,${newLineAndIndentation( | ||
depth | ||
)}${propertyNameSource}: ${propertyValueSource}` | ||
} | ||
} else if (i === 0) { | ||
propertiesSource += `${propertyNameSource}: ${propertyValueSource}` | ||
} else { | ||
propertiesSource += `, ${propertyNameSource}: ${propertyValueSource}` | ||
} | ||
i++ | ||
} | ||
let objectSource | ||
if (propertiesSource.length) { | ||
if (pretty) { | ||
objectSource = `{${newLineAndIndentation(depth)}${propertiesSource}${newLineAndIndentation( | ||
depth - 1 | ||
)}}` | ||
} else { | ||
objectSource = `{ ${propertiesSource} }` | ||
} | ||
} else { | ||
objectSource = "{}" | ||
} | ||
return format(objectSource) | ||
}, | ||
String: unevalInstance, | ||
// Symbol: (symbol, { unevalPrimitive }) => unevalPrimitive("symbol", symbol), | ||
// ici faudrais désactiver les parenthèses jusque pour l'object qu'on uneval | ||
// mais préserver la valeur par défaut pour ceux qui sont nested | ||
Other: (object, { type, format, unevalComposite }) => | ||
format(`${type}(${unevalComposite("Object", object)})`) | ||
}) | ||
export const uneval = ( | ||
value, | ||
options = { | ||
parenthesis: false, | ||
new: false, | ||
skipFunctionBody: true, | ||
pretty: true | ||
} | ||
) => { | ||
const expose = (...properties) => Object.assign({}, options, ...properties) | ||
const localUneval = (value, localOptions = {}) => uneval(value, expose(localOptions)) | ||
const format = string => { | ||
let formattedString = string | ||
if (options.parenthesis) { | ||
formattedString = `(${string})` | ||
} | ||
if (options.new) { | ||
formattedString = `new ${formattedString}` | ||
} | ||
return formattedString | ||
} | ||
const unevalPrimitive = (type, value) => primitiveSources[type](value, expose({ type })) | ||
const unevalComposite = (type, value) => { | ||
const handlerType = type in compositeSources ? type : "Other" | ||
return compositeSources[handlerType](value, expose({ type })) | ||
} | ||
Object.assign(options, { | ||
expose, | ||
uneval: localUneval, | ||
format, | ||
unevalPrimitive, | ||
unevalComposite | ||
}) | ||
return unevalPrimitive(getPrimitiveType(value), value) | ||
} | ||
export { unevalPrimitive as uneval } from "./primitive/index.js" |
@@ -6,12 +6,17 @@ import { uneval } from "./uneval.js" | ||
const expectUneval = (value, expectedUneval) => assert.equal(uneval(value), expectedUneval) | ||
const expectUnevalShort = (value, expectedUneval) => | ||
assert.equal(uneval(value, { pretty: false }), expectedUneval) | ||
const expectUnevalCompact = (value, expectedUneval) => | ||
assert.equal(uneval(value, { compact: true }), expectedUneval) | ||
const expectUnevalWithNew = (value, expectedUneval) => | ||
assert.equal(uneval(value, { new: true }), expectedUneval) | ||
assert.equal(uneval(value, { useNew: true }), expectedUneval) | ||
const expectUnevalWithParenthesis = (value, expectedUneval) => | ||
assert.equal(uneval(value, { parenthesis: true }), expectedUneval) | ||
assert.equal(uneval(value, { parenthesis: true }), expectedUneval) | ||
const expectUnevalWithNewAndParenthesis = (value, expectedUneval) => | ||
assert.equal(uneval(value, { parenthesis: true, new: true }), expectedUneval) | ||
assert.equal(uneval(value, { parenthesis: true, useNew: true }), expectedUneval) | ||
const expectUnevalWithFunctionBody = (value, expectedUneval) => | ||
assert.equal(uneval(value, { skipFunctionBody: false }), expectedUneval) | ||
assert.equal(uneval(value, { showFunctionBody: true }), expectedUneval) | ||
@@ -21,189 +26,191 @@ /* eslint-disable no-new-wrappers, no-new-object, no-array-constructor */ | ||
test("uneval.js", ({ ensure }) => { | ||
ensure("boolean uneval", () => { | ||
expectUneval(true, "true") | ||
expectUneval(false, "false") | ||
expectUneval(new Boolean(true), "Boolean(true)") | ||
expectUnevalWithParenthesis(new Boolean(true), "(Boolean(true))") | ||
expectUnevalWithNew(new Boolean(true), "new Boolean(true)") | ||
expectUnevalWithNewAndParenthesis(new Boolean(true), "new (Boolean(true))") | ||
}) | ||
ensure("boolean uneval", () => { | ||
expectUneval(true, "true") | ||
expectUneval(false, "false") | ||
expectUneval(new Boolean(true), "Boolean(true)") | ||
expectUnevalWithParenthesis(new Boolean(true), "(Boolean(true))") | ||
expectUnevalWithNew(new Boolean(true), "new Boolean(true)") | ||
expectUnevalWithNewAndParenthesis(new Boolean(true), "new (Boolean(true))") | ||
}) | ||
ensure("arrow function", () => { | ||
expectUneval(() => {}, `function`) | ||
const named = () => {} | ||
expectUneval(named, `function named`) | ||
expectUnevalWithFunctionBody(named, `function named() {}`) | ||
ensure("arrow function", () => { | ||
expectUneval(() => {}, `function`) | ||
const named = () => {} | ||
expectUneval(named, `function named`) | ||
expectUnevalWithFunctionBody(named, `function named() {}`) | ||
// because of babel most function body are converted back to regular function | ||
expectUnevalWithFunctionBody(() => {}, "function () {}") | ||
expectUnevalWithFunctionBody( | ||
() => true, | ||
`function () { | ||
// because of babel most function body are converted back to regular function | ||
expectUnevalWithFunctionBody(() => {}, "function () {}") | ||
expectUnevalWithFunctionBody( | ||
() => true, | ||
`function () { | ||
return true; | ||
}` | ||
) | ||
}) | ||
}`, | ||
) | ||
}) | ||
ensure("function", () => { | ||
// no need, arrow function are enougth | ||
}) | ||
ensure("function", () => { | ||
// no need, arrow function are enougth | ||
}) | ||
ensure("null", () => { | ||
expectUneval(null, "null") | ||
}) | ||
ensure("null", () => { | ||
expectUneval(null, "null") | ||
}) | ||
ensure("number/Number", () => { | ||
expectUneval(0, "0") | ||
expectUneval(1, "1") | ||
expectUneval(new Number(0), "Number(0)") | ||
expectUnevalWithParenthesis(new Number(0), "(Number(0))") | ||
expectUnevalWithNew(new Number(0), "new Number(0)") | ||
expectUnevalWithNewAndParenthesis(new Number(0), "new (Number(0))") | ||
}) | ||
ensure("number/Number", () => { | ||
expectUneval(0, "0") | ||
expectUneval(1, "1") | ||
expectUneval(new Number(0), "Number(0)") | ||
expectUnevalWithParenthesis(new Number(0), "(Number(0))") | ||
expectUnevalWithNew(new Number(0), "new Number(0)") | ||
expectUnevalWithNewAndParenthesis(new Number(0), "new (Number(0))") | ||
}) | ||
ensure("object/Object", () => { | ||
const emptyObject = {} | ||
expectUneval(emptyObject, "{}") | ||
expectUneval(new Object({}), "{}") | ||
ensure("object/Object", () => { | ||
const emptyObject = {} | ||
expectUneval(emptyObject, "{}") | ||
expectUneval(new Object({}), "{}") | ||
const foo = { foo: true, bar: false } | ||
expectUneval( | ||
foo, | ||
`{ | ||
"foo": true, | ||
"bar": false | ||
}` | ||
) | ||
expectUnevalShort(foo, `{ "foo": true, "bar": false }`) | ||
const foo = { foo: true, bar: false } | ||
expectUneval( | ||
foo, | ||
`{ | ||
"foo": true, | ||
"bar": false | ||
}`, | ||
) | ||
expectUnevalCompact(foo, `{"foo": true, "bar": false}`) | ||
const objectWithInheritedEnumerableProperty = Object.create({ | ||
foo: true | ||
}) | ||
expectUneval(objectWithInheritedEnumerableProperty, "{}") | ||
const objectWithInheritedEnumerableProperty = Object.create({ | ||
foo: true, | ||
}) | ||
expectUneval(objectWithInheritedEnumerableProperty, "{}") | ||
const nested = { foo: { name: "dam" } } | ||
expectUneval( | ||
nested, | ||
`{ | ||
"foo": { | ||
"name": "dam" | ||
} | ||
}` | ||
) | ||
expectUnevalShort(nested, `{ "foo": { "name": "dam" } }`) | ||
const nested = { foo: { name: "dam" } } | ||
expectUneval( | ||
nested, | ||
`{ | ||
"foo": { | ||
"name": "dam" | ||
} | ||
}`, | ||
) | ||
expectUnevalCompact(nested, `{"foo": {"name": "dam"}}`) | ||
const circularObject = { | ||
foo: true | ||
} | ||
circularObject.self = circularObject | ||
expectUneval( | ||
circularObject, | ||
`{ | ||
"foo": true, | ||
"self": {} | ||
}` | ||
) | ||
const circularObject = { | ||
foo: true, | ||
} | ||
circularObject.self = circularObject | ||
expectUneval( | ||
circularObject, | ||
`{ | ||
"foo": true, | ||
"self": Symbol.for('circular') | ||
}`, | ||
) | ||
const nestedCircularObject = { | ||
foo: true | ||
} | ||
nestedCircularObject.nested = { | ||
bar: true, | ||
parent: nestedCircularObject | ||
} | ||
expectUneval( | ||
nestedCircularObject, | ||
`{ | ||
"foo": true, | ||
"nested": { | ||
"bar": true, | ||
"parent": {} | ||
} | ||
}` | ||
) | ||
}) | ||
const nestedCircularObject = { | ||
foo: true, | ||
} | ||
nestedCircularObject.nested = { | ||
bar: true, | ||
parent: nestedCircularObject, | ||
} | ||
expectUneval( | ||
nestedCircularObject, | ||
`{ | ||
"foo": true, | ||
"nested": { | ||
"bar": true, | ||
"parent": Symbol.for('circular') | ||
} | ||
}`, | ||
) | ||
}) | ||
ensure("string/String", () => { | ||
expectUneval("", `""`) | ||
expectUneval("dam", `"dam"`) | ||
expectUneval("don't", `"don\\\'t"`) | ||
expectUneval(`his name is "dam"`, `"his name is \\\"dam\\\""`) | ||
expectUneval("a\nb", `"a\\nb"`) | ||
expectUneval("a\rb", `"a\\rb"`) | ||
expectUneval("a\u2028b", `"a\\u2028b"`) | ||
expectUneval("a\u2029b", `"a\\u2029b"`) | ||
expectUneval(new String(""), `String("")`) | ||
expectUneval(new String("dam"), `String("dam")`) | ||
}) | ||
ensure("string/String", () => { | ||
expectUneval("", `""`) | ||
expectUneval("dam", `"dam"`) | ||
expectUneval("don't", `"don\\\'t"`) | ||
expectUneval(`his name is "dam"`, `"his name is \\\"dam\\\""`) | ||
expectUneval("a\nb", `"a\\nb"`) | ||
expectUneval("a\rb", `"a\\rb"`) | ||
expectUneval("a\u2028b", `"a\\u2028b"`) | ||
expectUneval("a\u2029b", `"a\\u2029b"`) | ||
expectUneval(new String(""), `String("")`) | ||
expectUneval(new String("dam"), `String("dam")`) | ||
}) | ||
ensure("symbol/Symbol", () => { | ||
expectUneval(Symbol(), "symbol") | ||
}) | ||
ensure("symbol/Symbol", () => { | ||
expectUneval(Symbol(), "Symbol") | ||
}) | ||
ensure("undefined", () => { | ||
expectUneval(undefined, "undefined") | ||
}) | ||
ensure("undefined", () => { | ||
expectUneval(undefined, "undefined") | ||
}) | ||
ensure("regexp/Regexp", () => { | ||
expectUneval(/ok/g, "/ok/g") | ||
expectUneval(new RegExp("foo", "g"), "/foo/g") | ||
}) | ||
ensure("regexp/Regexp", () => { | ||
expectUneval(/ok/g, "/ok/g") | ||
expectUneval(new RegExp("foo", "g"), "/foo/g") | ||
}) | ||
ensure("Error", () => { | ||
expectUneval(new Error("here"), `Error("here")`) | ||
expectUneval(new RangeError("here"), `RangeError("here")`) | ||
}) | ||
ensure("Error", () => { | ||
expectUneval(new Error("here"), `Error("here")`) | ||
expectUneval(new RangeError("here"), `RangeError("here")`) | ||
}) | ||
ensure("Date", () => { | ||
expectUneval(new Date(), `Date(${Date.now()})`) | ||
}) | ||
ensure("Date", () => { | ||
expectUneval(new Date(), `Date(${Date.now()})`) | ||
}) | ||
ensure("literal array/Array", () => { | ||
const emptyArray = [] | ||
expectUneval(emptyArray, `[]`) | ||
ensure("Custom instance", () => { | ||
// other instance | ||
const CustomConstructor = function() { | ||
this.foo = true | ||
} | ||
const customInstance = new CustomConstructor() | ||
expectUneval( | ||
customInstance, | ||
`CustomConstructor({ | ||
"foo": true | ||
})`, | ||
) | ||
}) | ||
const newArray = new Array("foo", 1) | ||
expectUneval( | ||
newArray, | ||
`[ | ||
"foo", | ||
1 | ||
]` | ||
) | ||
expectUnevalShort(newArray, `["foo", 1]`) | ||
ensure("literal array/Array", () => { | ||
const emptyArray = [] | ||
expectUneval(emptyArray, `[]`) | ||
const nestedArray = [[]] | ||
expectUnevalShort(nestedArray, `[[]]`) | ||
const newArray = new Array("foo", 1) | ||
expectUneval( | ||
newArray, | ||
`[ | ||
"foo", | ||
1 | ||
]`, | ||
) | ||
expectUnevalCompact(newArray, `["foo", 1]`) | ||
const circularArray = [0] | ||
circularArray.push(circularArray) | ||
expectUneval( | ||
circularArray, | ||
`[ | ||
0, | ||
[] | ||
]` | ||
) | ||
const nestedArray = [[]] | ||
expectUnevalCompact(nestedArray, `[[]]`) | ||
// other instance | ||
const CustomConstructor = function() { | ||
this.foo = true | ||
} | ||
const customInstance = new CustomConstructor() | ||
expectUneval( | ||
customInstance, | ||
`CustomConstructor({ | ||
"foo": true | ||
})` | ||
) | ||
const circularArray = [0] | ||
circularArray.push(circularArray) | ||
expectUneval( | ||
circularArray, | ||
`[ | ||
0, | ||
Symbol.for('circular') | ||
]`, | ||
) | ||
expectUneval( | ||
[Symbol()], | ||
`[ | ||
symbol | ||
]` | ||
) | ||
}) | ||
expectUneval( | ||
[Symbol()], | ||
`[ | ||
Symbol | ||
]`, | ||
) | ||
}) | ||
}) | ||
/* eslint-enable no-new-wrappers, no-new-object */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
70277
29
1009
50
1