Skip to content

Commit

Permalink
Enhanced object literals support (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
kwolfy authored and okuryu committed Dec 24, 2018
1 parent 24b2b4b commit 734e8c7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 6 deletions.
36 changes: 30 additions & 6 deletions index.js
Expand Up @@ -11,8 +11,11 @@ var UID = Math.floor(Math.random() * 0x10000000000).toString(16)
var PLACE_HOLDER_REGEXP = new RegExp('"@__(F|R|D)-' + UID + '-(\\d+)__@"', 'g');

var IS_NATIVE_CODE_REGEXP = /\{\s*\[native code\]\s*\}/g;
var IS_PURE_FUNCTION = /function.*?\(/;
var UNSAFE_CHARS_REGEXP = /[<>\/\u2028\u2029]/g;

var RESERVED_SYMBOLS = ['*', 'async'];

// Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
// Unicode char counterparts which are safe to use in JavaScript strings.
var ESCAPED_CHARS = {
Expand Down Expand Up @@ -68,6 +71,32 @@ module.exports = function serialize(obj, options) {
return value;
}

function serializeFunc(fn) {
var serializedFn = fn.toString();
if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) {
throw new TypeError('Serializing native function: ' + fn.name);
}

// pure functions, example: {key: function() {}}
if(IS_PURE_FUNCTION.test(serializedFn)) {
return serializedFn;
}

var argsStartsAt = serializedFn.indexOf('(');
var def = serializedFn.substr(0, argsStartsAt).trim().split(' ').filter(val => val.length > 0);
var nonReservedSymbols = def.filter(val => RESERVED_SYMBOLS.indexOf(val) === -1);

// enhanced literal objects, example: {key() {}}
if(nonReservedSymbols.length > 0) {
return (def.indexOf('async') > -1 ? 'async ' : '') + 'function'
+ (def.join('').indexOf('*') > -1 ? '*' : '')
+ serializedFn.substr(argsStartsAt);
}

// arrow functions
return serializedFn;
}

var str;

// Creates a JSON string representation of the value.
Expand Down Expand Up @@ -108,12 +137,7 @@ module.exports = function serialize(obj, options) {
}

var fn = functions[valueIndex];
var serializedFn = fn.toString();

if (IS_NATIVE_CODE_REGEXP.test(serializedFn)) {
throw new TypeError('Serializing native function: ' + fn.name);
}

return serializedFn;
return serializeFunc(fn);
});
}
16 changes: 16 additions & 0 deletions test/unit/serialize.js
Expand Up @@ -109,6 +109,22 @@ describe('serialize( obj )', function () {
try { serialize(Number); } catch (e) { err = e; }
expect(err).to.be.an.instanceOf(TypeError);
});

it('should serialize enhanced literal objects', function () {
var obj = {
foo() { return true; },
*bar() { return true; }
};

expect(serialize(obj)).to.equal('{"foo":function() { return true; },"bar":function*() { return true; }}');
});

it('should deserialize enhanced literal objects', function () {
var obj;
eval('obj = ' + serialize({ hello() { return true; } }));

expect(obj.hello()).to.equal(true);
});
});

describe('regexps', function () {
Expand Down

0 comments on commit 734e8c7

Please sign in to comment.