"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

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

var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));

var _symbol = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/symbol"));

var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/keys"));

var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));

var factorySymbol = (0, _symbol.default)('factory-symbol');

function isProtoFactory(v) {
  return v && v[factorySymbol];
}

function proto(baseRecord) {
  var ensureArray = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'auto';
  var baseKeys = (0, _keys.default)(baseRecord);

  function process(record) {
    var result = (0, _extends2.default)({}, record);
    baseKeys.forEach(function (key) {
      var _a;

      if (result[key] === proto.empty) {
        delete result[key];
        return;
      }

      var base = baseRecord[key];

      if (isProtoFactory(base)) {
        result[key] = base(result[key]);
      } else {
        result[key] = (_a = result[key]) !== null && _a !== void 0 ? _a : base;
      }
    });
    return result;
  }

  function factory(arg) {
    var isEnsureArray = ensureArray === 'auto' ? Array.isArray(arg) : ensureArray;

    if (isEnsureArray) {
      if (arg == null) {
        return [];
      }

      return (0, _map.default)(arg).call(arg, process);
    } else {
      return process(arg);
    }
  } // @ts-ignore


  factory[factorySymbol] = true;

  factory.extends = function (extRecord) {
    var extFactory = proto(extRecord, ensureArray);
    return function (arg) {
      return factory(extFactory(arg));
    };
  };

  return factory;
}

proto.empty = (0, _symbol.default)('proto.empty');

proto.string = function (v) {
  if (v != null && typeof v !== 'string') {
    throw new Error('must be string');
  }

  return v;
};

proto.string[factorySymbol] = true;

proto.number = function (v) {
  if (v != null && typeof v !== 'number') {
    throw new Error('must be number');
  }

  return v;
};

proto.number[factorySymbol] = true;

proto.notNull = function (v) {
  if (v == null) {
    throw new Error('must be not null');
  }

  return v;
};

proto.notNull[factorySymbol] = true;

proto.object = function (baseRecord) {
  return proto(baseRecord, false);
};

proto.array = function (baseRecord) {
  return proto(baseRecord, true);
};

var _default = proto;
exports.default = _default;