Skip to content

Commit

Permalink
v1.0.4
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayMakhonin committed Mar 9, 2019
1 parent 5db8955 commit f588b5d
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 100 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
1.0.4 / 2019-03-09
===================

* Detect circular structure

1.0.3 / 2019-03-09
===================

Expand Down
66 changes: 40 additions & 26 deletions dist/js/main/helpers/convert/jsToNodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ function addParentToChildNodes(node) {
}
}

function jsToNodes(jsObjectOrArray, createNodeFunc, level) {
const result = Array.from(jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level));
function jsToNodes(jsObjectOrArray, createNodeFunc, level, addedObjects) {
const result = Array.from(jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level, addedObjects));

if (result.length === 1) {
const value = result[0];
Expand All @@ -40,49 +40,63 @@ function jsToNodes(jsObjectOrArray, createNodeFunc, level) {
return result;
}

function* jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level) {
function* jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level, addedObjects) {
if (jsObjectOrArray == null) {
yield jsObjectOrArray;
return;
}

if (!level) {
level = 0;
if (addedObjects) {
if (addedObjects.has(jsObjectOrArray)) {
throw new Error('Detect circular structure on: ' + jsObjectOrArray);
}
} else {
addedObjects = new Set();
}

if (Array.isArray(jsObjectOrArray)) {
for (const item of jsObjectOrArray) {
if (typeof item === 'string') {
const node = createNodeFunc(null, item, level);
addedObjects.add(jsObjectOrArray);

try {
if (!level) {
level = 0;
}

if (Array.isArray(jsObjectOrArray)) {
for (const item of jsObjectOrArray) {
if (typeof item === 'string') {
const node = createNodeFunc(null, item, level);

if (node) {
yield node;
if (node) {
yield node;
}
} else if (item) {
yield* jsToNodesGenerator(item, createNodeFunc, level, addedObjects);
}
} else if (item) {
yield* jsToNodesGenerator(item, createNodeFunc, level);
}
}

return;
}
return;
}

if (typeof jsObjectOrArray === 'object') {
const nextLevel = level + 1;
if (typeof jsObjectOrArray === 'object') {
const nextLevel = level + 1;

for (const name in jsObjectOrArray) {
if (Object.prototype.hasOwnProperty.call(jsObjectOrArray, name)) {
const node = createNodeFunc(name, jsToNodes(jsObjectOrArray[name], createNodeFunc, nextLevel), level);
for (const name in jsObjectOrArray) {
if (Object.prototype.hasOwnProperty.call(jsObjectOrArray, name)) {
const node = createNodeFunc(name, jsToNodes(jsObjectOrArray[name], createNodeFunc, nextLevel, addedObjects), level);

if (node) {
yield node;
if (node) {
yield node;
}
}
}

return;
}

return;
yield jsObjectOrArray;
} finally {
addedObjects.delete(jsObjectOrArray);
}

yield jsObjectOrArray;
}

var _default = {
Expand Down
15 changes: 15 additions & 0 deletions dist/js/test/tests/main/helpers/convert/jsToNodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,19 @@ describe('main > helpers > convert > jsToNodes', function () {
}]
}]);
});
it('Detect circular structure', function () {
const jss = {
prop1: [{
prop2: {
prop3: []
}
}]
};
jss.prop1[1] = jss.prop1[0].prop2;
(0, _jsToNodes.jsToNodes)(jss, createNode);
jss.prop1[1] = jss.prop1[0];
(0, _jsToNodes.jsToNodes)(jss, createNode);
jss.prop1[1].prop2.prop3[1] = jss;
assert.throws(() => (0, _jsToNodes.jsToNodes)(jss, createNode), Error);
});
});
124 changes: 76 additions & 48 deletions dist/mjs/main/helpers/convert/jsToNodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export function addParentToChildNodes(node) {
}
}
}
export function jsToNodes(jsObjectOrArray, createNodeFunc, level) {
var result = Array.from(jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level));
export function jsToNodes(jsObjectOrArray, createNodeFunc, level, addedObjects) {
var result = Array.from(jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level, addedObjects));

if (result.length === 1) {
var value = result[0];
Expand All @@ -59,7 +59,7 @@ export function jsToNodes(jsObjectOrArray, createNodeFunc, level) {
return result;
}

function jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level) {
function jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level, addedObjects) {
var _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, item, node, nextLevel, name, _node;

return _regeneratorRuntime.wrap(function jsToNodesGenerator$(_context) {
Expand All @@ -78,147 +78,175 @@ function jsToNodesGenerator(jsObjectOrArray, createNodeFunc, level) {
return _context.abrupt("return");

case 4:
if (!addedObjects) {
_context.next = 9;
break;
}

if (!addedObjects.has(jsObjectOrArray)) {
_context.next = 7;
break;
}

throw new Error('Detect circular structure on: ' + jsObjectOrArray);

case 7:
_context.next = 10;
break;

case 9:
addedObjects = new Set();

case 10:
addedObjects.add(jsObjectOrArray);
_context.prev = 11;

if (!level) {
level = 0;
}

if (!Array.isArray(jsObjectOrArray)) {
_context.next = 40;
_context.next = 48;
break;
}

_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context.prev = 9;
_context.prev = 17;
_iterator2 = jsObjectOrArray[Symbol.iterator]();

case 11:
case 19:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
_context.next = 25;
_context.next = 33;
break;
}

item = _step2.value;

if (!(typeof item === 'string')) {
_context.next = 20;
_context.next = 28;
break;
}

node = createNodeFunc(null, item, level);

if (!node) {
_context.next = 18;
_context.next = 26;
break;
}

_context.next = 18;
_context.next = 26;
return node;

case 18:
_context.next = 22;
case 26:
_context.next = 30;
break;

case 20:
case 28:
if (!item) {
_context.next = 22;
_context.next = 30;
break;
}

return _context.delegateYield(jsToNodesGenerator(item, createNodeFunc, level), "t0", 22);
return _context.delegateYield(jsToNodesGenerator(item, createNodeFunc, level, addedObjects), "t0", 30);

case 22:
case 30:
_iteratorNormalCompletion2 = true;
_context.next = 11;
_context.next = 19;
break;

case 25:
_context.next = 31;
case 33:
_context.next = 39;
break;

case 27:
_context.prev = 27;
_context.t1 = _context["catch"](9);
case 35:
_context.prev = 35;
_context.t1 = _context["catch"](17);
_didIteratorError2 = true;
_iteratorError2 = _context.t1;

case 31:
_context.prev = 31;
_context.prev = 32;
case 39:
_context.prev = 39;
_context.prev = 40;

if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}

case 34:
_context.prev = 34;
case 42:
_context.prev = 42;

if (!_didIteratorError2) {
_context.next = 37;
_context.next = 45;
break;
}

throw _iteratorError2;

case 37:
return _context.finish(34);
case 45:
return _context.finish(42);

case 38:
return _context.finish(31);
case 46:
return _context.finish(39);

case 39:
case 47:
return _context.abrupt("return");

case 40:
case 48:
if (!(_typeof(jsObjectOrArray) === 'object')) {
_context.next = 53;
_context.next = 61;
break;
}

nextLevel = level + 1;
_context.t2 = _regeneratorRuntime.keys(jsObjectOrArray);

case 43:
case 51:
if ((_context.t3 = _context.t2()).done) {
_context.next = 52;
_context.next = 60;
break;
}

name = _context.t3.value;

if (!Object.prototype.hasOwnProperty.call(jsObjectOrArray, name)) {
_context.next = 50;
_context.next = 58;
break;
}

_node = createNodeFunc(name, jsToNodes(jsObjectOrArray[name], createNodeFunc, nextLevel), level);
_node = createNodeFunc(name, jsToNodes(jsObjectOrArray[name], createNodeFunc, nextLevel, addedObjects), level);

if (!_node) {
_context.next = 50;
_context.next = 58;
break;
}

_context.next = 50;
_context.next = 58;
return _node;

case 50:
_context.next = 43;
case 58:
_context.next = 51;
break;

case 52:
case 60:
return _context.abrupt("return");

case 53:
_context.next = 55;
case 61:
_context.next = 63;
return jsObjectOrArray;

case 55:
case 63:
_context.prev = 63;
addedObjects.delete(jsObjectOrArray);
return _context.finish(63);

case 66:
case "end":
return _context.stop();
}
}
}, _marked, null, [[9, 27, 31, 39], [32,, 34, 38]]);
}, _marked, null, [[11,, 63, 66], [17, 35, 39, 47], [40,, 42, 46]]);
}

export default {
Expand Down
17 changes: 17 additions & 0 deletions dist/mjs/test/tests/main/helpers/convert/jsToNodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,21 @@ describe('main > helpers > convert > jsToNodes', function () {
}]
}]);
});
it('Detect circular structure', function () {
var jss = {
prop1: [{
prop2: {
prop3: []
}
}]
};
jss.prop1[1] = jss.prop1[0].prop2;
jsToNodes(jss, createNode);
jss.prop1[1] = jss.prop1[0];
jsToNodes(jss, createNode);
jss.prop1[1].prop2.prop3[1] = jss;
assert.throws(function () {
return jsToNodes(jss, createNode);
}, Error);
});
});
Loading

0 comments on commit f588b5d

Please sign in to comment.