{"size": 2251, "ext": "js", "max_stars_repo_path": "src/types/collection.js", "max_stars_repo_name": "ddsol/redux-schema", "max_stars_repo_stars_event_min_datetime": "2016-04-12T16:43:45.000Z", "max_stars_repo_stars_event_max_datetime": "2021-08-29T06:24:23.000Z", "max_issues_repo_path": "src/types/collection.js", "max_issues_repo_name": "ddsol/redux-schema", "max_issues_repo_issues_event_min_datetime": "2016-04-12T20:24:49.000Z", "max_issues_repo_issues_event_max_datetime": "2017-06-16T21:53:42.000Z", "max_forks_repo_path": "src/types/collection.js", "max_forks_repo_name": "ddsol/redux-schema", "max_forks_repo_forks_event_min_datetime": "2016-05-16T14:30:13.000Z", "max_forks_repo_forks_event_max_datetime": "2018-07-12T15:47:27.000Z"}
{"max_stars_count": 177, "max_issues_count": 5, "max_forks_count": 13, "avg_line_length": 33.1029411765, "max_line_length": 101, "alphanum_fraction": 0.5508662817}
import { namedFunction, dedent } from '../utils';
import parseType from '../parse/parse-type';
import { makeOwner } from './model';
import bare from '../modifiers/bare';

export default function collection(model, extraProperties) {
  if (!model.isModel) {
    throw new TypeError('Collection items must be Models');
  }
  function Collection(options) {
    let self          = { options, isCollection: true }
      , typeMoniker   = options.typeMoniker
      , parentMoniker = typeMoniker.slice(0, -1)
      , modelType     = model({
          ...options,
          typeMoniker: parentMoniker.concat(model.modelName),
          parent: options.self || self,
          self: null
        })
      , type          = {
          '*': modelType,
          create: bare(namedFunction(`create${modelType.name}`, function() {
            return this.model.apply(null, arguments);
          }), dedent`
            function(){
              return new ${modelType.name}'(...arguments);
            }`, !options.namedFunctions),
          get all() {
            return this.keys.map(id => this.get(id));
          },
          get model() {
            let self = this
              , BoundModel = namedFunction(modelType.name, function Model(...args) {
                   return modelType.call(this, makeOwner(self), ...args);
                }, modelType, !options.debug);
            BoundModel.prototype = modelType.prototype;
            Object.assign(BoundModel, modelType);
            return BoundModel;
          },
          remove(id) {
            if (id && id._meta && id._meta.idKey && id[id._meta.idKey]) {
              id = id[id._meta.idKey];
            }
            var val = this.get(id);
            if (!val) throw new Error(`Could not remove ${modelType.name}[${id}]: object not found`);
            this.set(id, undefined);
          }
        }
      , thisType
      ;

    if (extraProperties) {
      type = {...extraProperties, ...type};
    }

    thisType = parseType({ ...options, self }, type);

    thisType.name = `collection(${modelType.name})`;
    thisType.collection = model.collection;
    thisType.model = modelType;
    return Object.assign(self, thisType);
  }

  Collection.isType = true;
  return Collection;
}

