define('@cardstack/test-support/jsonapi-factory', ['exports', 'dag-map'], function (exports, _dagMap) {
  'use strict';

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

  var _slicedToArray = function () {
    function sliceIterator(arr, i) {
      var _arr = [];
      var _n = true;
      var _d = false;
      var _e = undefined;

      try {
        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
          _arr.push(_s.value);

          if (i && _arr.length === i) break;
        }
      } catch (err) {
        _d = true;
        _e = err;
      } finally {
        try {
          if (!_n && _i["return"]) _i["return"]();
        } finally {
          if (_d) throw _e;
        }
      }

      return _arr;
    }

    return function (arr, i) {
      if (Array.isArray(arr)) {
        return arr;
      } else if (Symbol.iterator in Object(arr)) {
        return sliceIterator(arr, i);
      } else {
        throw new TypeError("Invalid attempt to destructure non-iterable instance");
      }
    };
  }();

  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 idGenerator = 0;

  var JSONAPIFactory = function () {
    function JSONAPIFactory() {
      _classCallCheck(this, JSONAPIFactory);

      this.data = [];
    }

    _createClass(JSONAPIFactory, [{
      key: 'addResource',
      value: function addResource(type) {
        var id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;

        if (id == null) {
          id = idGenerator++;
        }
        var resource = { type: type, id: String(id) };
        this.data.push(resource);
        resource.type = type;
        return new ResourceFactory(resource);
      }
    }, {
      key: 'getResource',
      value: function getResource(type, id) {
        var resource = this.data.find(function (r) {
          return r.type === type && r.id === String(id);
        });
        if (!resource) {
          throw new Error('no such resource ' + type + ' ' + id);
        }
        return new ResourceFactory(resource);
      }
    }, {
      key: 'getModels',
      value: function getModels() {
        var dag = new _dagMap.default();
        this.data.forEach(function (model) {
          var dependsOn = [];
          if (model.relationships) {
            Object.keys(model.relationships).forEach(function (rel) {
              var data = model.relationships[rel].data;
              if (Array.isArray(data)) {
                dependsOn = dependsOn.concat(data.map(function (ref) {
                  return ref.type + '/' + ref.id;
                }));
              } else {
                dependsOn.push(data.type + '/' + data.id);
              }
            });
          }
          dependsOn.push('content-types/' + model.type);

          // These are all boostrap schema and we need to not include them
          // here to avoid circularity.
          dependsOn = dependsOn.filter(function (dep) {
            return !['content-types/content-types', 'content-types/fields', 'fields/fields'].includes(dep);
          });

          dag.add(model.type + '/' + model.id, model, [], dependsOn);
        });
        var output = [];
        dag.each(function (key, value) {
          if (value) {
            output.push(value);
          }
        });
        return output;
      }
    }, {
      key: 'importModels',
      value: function importModels(models) {
        this.data = this.data.concat(models);
      }
    }]);

    return JSONAPIFactory;
  }();

  exports.default = JSONAPIFactory;

  var ResourceFactory = function () {
    function ResourceFactory(data) {
      _classCallCheck(this, ResourceFactory);

      this.data = data;
      this.id = data.id;
      this.type = data.type;
    }

    _createClass(ResourceFactory, [{
      key: 'withAttributes',
      value: function withAttributes(attrs) {
        var _iteratorNormalCompletion = true;
        var _didIteratorError = false;
        var _iteratorError = undefined;

        try {
          for (var _iterator = Object.entries(attrs)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
            var _ref = _step.value;

            var _ref2 = _slicedToArray(_ref, 2);

            var fieldName = _ref2[0];
            var value = _ref2[1];

            if (!this.data.attributes) {
              this.data.attributes = {};
            }
            this.data.attributes[dasherize(fieldName)] = value;
          }
        } catch (err) {
          _didIteratorError = true;
          _iteratorError = err;
        } finally {
          try {
            if (!_iteratorNormalCompletion && _iterator.return) {
              _iterator.return();
            }
          } finally {
            if (_didIteratorError) {
              throw _iteratorError;
            }
          }
        }

        return this;
      }
    }, {
      key: 'withRelated',
      value: function withRelated(fieldName, value) {
        if (!value) {
          throw new Error('No value for ' + fieldName);
        }
        if (!this.data.relationships) {
          this.data.relationships = {};
        }
        var data = void 0;
        if (Array.isArray(value)) {
          data = value.map(function (entry) {
            return { type: entry.type, id: entry.id };
          });
        } else {
          data = { type: value.type, id: value.id };
        }
        this.data.relationships[dasherize(fieldName)] = { data: data };
        return this;
      }
    }, {
      key: 'asDocument',
      value: function asDocument() {
        return { data: this.data };
      }
    }]);

    return ResourceFactory;
  }();

  function dasherize(camelCase) {
    return camelCase.replace(/([a-z])([A-Z])/g, function (a, b, c) {
      return b + '-' + c.toLowerCase();
    });
  }
});