define('ember-cli-mirage/db', ['exports', 'ember-cli-mirage/db-collection', 'ember-cli-mirage/identity-manager', 'ember-cli-mirage/utils/inflector', 'lodash/cloneDeep'], function (exports, _dbCollection, _identityManager, _inflector, _cloneDeep2) {
  'use strict';

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

  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  var _createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

  var Db = function () {
    function Db(initialData, identityManagers) {
      _classCallCheck(this, Db);

      this._collections = [];

      this.registerIdentityManagers(identityManagers);

      if (initialData) {
        this.loadData(initialData);
      }
    }

    /**
     * @method loadData
     * @param data
     * @public
     */


    _createClass(Db, [{
      key: 'loadData',
      value: function loadData(data) {
        for (var key in data) {
          this.createCollection(key, (0, _cloneDeep2.default)(data[key]));
        }
      }
    }, {
      key: 'dump',
      value: function dump() {
        return this._collections.reduce(function (data, collection) {
          data[collection.name] = collection.all();

          return data;
        }, {});
      }
    }, {
      key: 'createCollection',
      value: function createCollection(name, initialData) {
        if (!this[name]) {
          var _IdentityManager = this.identityManagerFor(name);
          var newCollection = new _dbCollection.default(name, initialData, _IdentityManager);

          // Public API has a convenient array interface. It comes at the cost of
          // returning a copy of all records to avoid accidental mutations.
          Object.defineProperty(this, name, {
            get: function get() {
              var recordsCopy = newCollection.all();

              ['insert', 'find', 'findBy', 'where', 'update', 'remove', 'firstOrCreate'].forEach(function (method) {
                recordsCopy[method] = function () {
                  return newCollection[method].apply(newCollection, arguments);
                };
              });

              return recordsCopy;
            }
          });

          // Private API does not have the array interface. This means internally, only
          // db-collection methods can be used. This is so records aren't copied redundantly
          // internally, which leads to accidental O(n^2) operations (e.g., createList).
          Object.defineProperty(this, '_' + name, {
            get: function get() {
              var recordsCopy = [];

              ['insert', 'find', 'findBy', 'where', 'update', 'remove', 'firstOrCreate'].forEach(function (method) {
                recordsCopy[method] = function () {
                  return newCollection[method].apply(newCollection, arguments);
                };
              });

              return recordsCopy;
            }
          });

          this._collections.push(newCollection);
        } else if (initialData) {
          this[name].insert(initialData);
        }

        return this;
      }
    }, {
      key: 'createCollections',
      value: function createCollections() {
        var _this = this;

        for (var _len = arguments.length, collections = Array(_len), _key = 0; _key < _len; _key++) {
          collections[_key] = arguments[_key];
        }

        collections.forEach(function (c) {
          return _this.createCollection(c);
        });
      }
    }, {
      key: 'emptyData',
      value: function emptyData() {
        this._collections.forEach(function (c) {
          return c.remove();
        });
      }
    }, {
      key: 'identityManagerFor',
      value: function identityManagerFor(name) {
        return this._identityManagers[(0, _inflector.singularize)(name)] || this._identityManagers.application || _identityManager.default;
      }
    }, {
      key: 'registerIdentityManagers',
      value: function registerIdentityManagers(identityManagers) {
        this._identityManagers = identityManagers || {};
      }
    }]);

    return Db;
  }();

  exports.default = Db;
});