decycle.js 3.84 KB
"use strict";

require("core-js/modules/es6.object.define-property");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = decycle;

require("core-js/modules/es7.symbol.async-iterator");

require("core-js/modules/es6.symbol");

require("core-js/modules/es6.function.name");

require("core-js/modules/es6.array.for-each");

require("core-js/modules/es6.array.is-array");

require("core-js/modules/es6.number.constructor");

require("core-js/modules/web.dom.iterable");

require("core-js/modules/es6.array.iterator");

require("core-js/modules/es6.string.iterator");

require("core-js/modules/es6.weak-map");

var _errors = require("./errors");

var _getPropertiesList = _interopRequireDefault(require("./util/getPropertiesList"));

var _typeReplacer = _interopRequireDefault(require("./util/typeReplacer"));

var _omitProperty = _interopRequireDefault(require("./util/omitProperty"));

var _constants = require("../constants");

var _types = require("./types");

var _configureDepth = require("./types/object/configureDepth");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

var hasOwnProperty = Object.prototype.hasOwnProperty;

function decycle(object) {
  var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
  var objects = new WeakMap();
  var isCyclic = false;

  var res = function derez(value, path, _depth, _branchDepthMax) {
    var oldPath;
    var obj;
    var maxDepth = _branchDepthMax;
    var result = (0, _typeReplacer.default)(value);

    if (result) {
      return result.value;
    }

    var type = _typeof(value);

    if (value instanceof Boolean || value instanceof Number || value instanceof String) {
      return value;
    }

    if (type === 'object' && value !== null) {
      oldPath = objects.get(value);

      if (oldPath !== undefined) {
        isCyclic = true;
        return {
          $ref: oldPath
        };
      }

      try {
        objects.set(value, path);
      } catch (error) {
        console.error(error); // eslint-disable-line no-console

        return new _errors.DecycleError(error.message);
      }

      if (Array.isArray(value)) {
        obj = [];

        for (var i = 0; i < value.length; i += 1) {
          obj[i] = derez(value[i], "".concat(path, "[").concat(i, "]"), _depth + 1, maxDepth);
        }
      } else {
        obj = _types.objectType.serialize(value);
        var newDepth;

        if (hasOwnProperty.call(obj, _configureDepth.DEPTH_KEY)) {
          if (_depth + 1 < maxDepth) {
            var depthKey = obj[_configureDepth.DEPTH_KEY];
            newDepth = depthKey === 0 ? 0 : _depth + depthKey;
            maxDepth = newDepth >= depth ? depth : newDepth;
          }

          delete obj[_configureDepth.DEPTH_KEY];
        }

        if (_depth <= maxDepth) {
          (0, _getPropertiesList.default)(value).forEach(function (name) {
            if (!(0, _omitProperty.default)(name)) {
              try {
                obj[name] = derez(value[name], "".concat(path, "[").concat(JSON.stringify(name), "]"), _depth + 1, maxDepth);
              } catch (error) {
                console.error(error); // eslint-disable-line no-console

                obj[name] = new _errors.DecycleError(error.message);
              }
            }
          });
        }
      }

      if (_depth === 0 && value instanceof Object && isCyclic) {
        obj[_constants.CYCLIC_KEY] = true;
      }

      return obj;
    }

    return value;
  }(object, '$', 0, depth);

  return res;
}