From 3ac44ceecba3bdcdbb84999bc53f2cedac882afc Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Wed, 3 Aug 2016 21:03:53 -0700 Subject: [PATCH] 3.0.0-rc.4 --- dist/js-data.es2015.js | 4273 ++++++++++++++++++------------------ dist/js-data.es2015.js.map | 2 +- dist/js-data.js | 4273 ++++++++++++++++++------------------ dist/js-data.js.map | 2 +- dist/js-data.min.js | 8 +- dist/js-data.min.map | 2 +- 6 files changed, 4259 insertions(+), 4301 deletions(-) diff --git a/dist/js-data.es2015.js b/dist/js-data.es2015.js index 0fe14413..36ae9dd6 100644 --- a/dist/js-data.es2015.js +++ b/dist/js-data.es2015.js @@ -1,6 +1,6 @@ /*! * js-data -* @version 3.0.0-rc.3 - Homepage +* @version 3.0.0-rc.4 - Homepage * @author js-data project authors * @copyright (c) 2014-2016 js-data project authors * @license MIT @@ -734,10 +734,10 @@ var utils = { } else if (classProps.strictEs6Class) { _subClass.__proto__ = superClass; // eslint-disable-line } else { - utils.forOwn(superClass, function (value, key) { - _subClass[key] = value; - }); - } + utils.forOwn(superClass, function (value, key) { + _subClass[key] = value; + }); + } if (!_subClass.hasOwnProperty('__super__')) { Object.defineProperty(_subClass, '__super__', { configurable: true, @@ -1692,6 +1692,22 @@ var utils = { } }; +var safeSetProp = function safeSetProp(record, field, value) { + if (record && record._set) { + record._set('props.' + field, value); + } else { + utils.set(record, field, value); + } +}; + +var safeSetLink = function safeSetLink(record, field, value) { + if (record && record._set) { + record._set('links.' + field, value); + } else { + utils.set(record, field, value); + } +}; + /** * A base class which gives instances private properties. * @@ -4507,1307 +4523,1406 @@ var Collection$1 = Component$1.extend({ * @since 3.0.0 */ -var DOMAIN$5 = 'Record'; +// TODO: remove this when the rest of the project is cleaned +var belongsToType = 'belongsTo'; +var hasManyType = 'hasMany'; +var hasOneType = 'hasOne'; -var superMethod = function superMethod(mapper, name) { - var store = mapper.datastore; - if (store && store[name]) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +var DOMAIN$6 = 'Relation'; - return store[name].apply(store, [mapper.name].concat(args)); - }; - } - return mapper[name].bind(mapper); -}; +function Relation(relatedMapper) { + var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; -/** - * js-data's Record class. An instance of `Record` corresponds to an in-memory - * representation of a single row or document in a database, Firebase, - * localstorage, etc. Basically, a `Record` instance represents whatever kind of - * entity in your persistence layer that has a primary key. - * - * ```javascript - * import {Record} from 'js-data' - * ``` - * - * @example Record#constructor - * // Normally you would do: import {Record} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Record} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * // Instantiate a plain record - * let record = new Record() - * console.log('record: ' + JSON.stringify(record)) - * - * // You can supply properties on instantiation - * record = new Record({ name: 'John' }) - * console.log('record: ' + JSON.stringify(record)) - * - * @example Record#constructor2 - * // Normally you would do: import {Mapper} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Mapper} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * // Instantiate a record that's associated with a Mapper: - * const UserMapper = new Mapper({ name: 'user' }) - * const User = UserMapper.recordClass - * const user = UserMapper.createRecord({ name: 'John' }) - * const user2 = new User({ name: 'Sally' }) - * console.log('user: ' + JSON.stringify(user)) - * console.log('user2: ' + JSON.stringify(user2)) - * - * @example Record#constructor3 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * - * // Instantiate a record that's associated with a store's Mapper - * const user = store.createRecord('user', { name: 'John' }) - * console.log('user: ' + JSON.stringify(user)) - * - * @example Record#constructor4 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * // Validate on instantiation - * const user = store.createRecord('user', { name: 1234 }) - * console.log('user: ' + JSON.stringify(user)) - * - * @example Record#constructor5 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * // Skip validation on instantiation - * const user = store.createRecord('user', { name: 1234 }, { noValidate: true }) - * console.log('user: ' + JSON.stringify(user)) - * console.log('user.isValid(): ' + user.isValid()) - * - * @class Record - * @extends Component - * @param {Object} [props] The initial properties of the new Record instance. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.noValidate=false] Whether to skip validation on the - * initial properties. - * @since 3.0.0 - */ -function Record(props, opts) { - utils.classCallCheck(this, Record); - Settable.call(this); - props || (props = {}); - opts || (opts = {}); - var _set = this._set; - // TODO: Optimize these strings - _set('creating', true); - if (opts.noValidate) { - _set('noValidate', true); - } - // Set the idAttribute value first, if it exists. - var mapper = this.constructor.mapper; - var id = mapper ? utils.get(props, mapper.idAttribute) : undefined; - if (id !== undefined) { - utils.set(this, mapper.idAttribute, id); + utils.classCallCheck(this, Relation); + + options.type = this.constructor.TYPE_NAME; + this.validateOptions(relatedMapper, options); + + if ((typeof relatedMapper === 'undefined' ? 'undefined' : _typeof(relatedMapper)) === 'object') { + Object.defineProperty(this, 'relatedMapper', { value: relatedMapper }); } - utils.fillIn(this, props); - _set('creating', false); - _set('noValidate', false); - _set('previous', utils.plainCopy(props)); + + Object.defineProperty(this, 'inverse', { writable: true }); + utils.fillIn(this, options); } -var Record$1 = Component$1.extend({ - constructor: Record, +Relation.extend = utils.extend; - /** - * Returns the {@link Mapper} paired with this record's class, if any. - * - * @method Record#_mapper - * @returns {Mapper} The {@link Mapper} paired with this record's class, if any. - * @since 3.0.0 - */ - _mapper: function _mapper() { - var mapper = this.constructor.mapper; - if (!mapper) { - throw utils.err(DOMAIN$5 + '#_mapper', '')(404, 'mapper'); - } - return mapper; +utils.addHiddenPropsToTarget(Relation.prototype, { + get canAutoAddLinks() { + return this.add === undefined || !!this.add; }, + get relatedCollection() { + return this.mapper.datastore.getCollection(this.relation); + }, - /** - * Lifecycle hook. - * - * @method Record#afterLoadRelations - * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. - * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. - * @since 3.0.0 - */ - afterLoadRelations: function afterLoadRelations() {}, + validateOptions: function validateOptions(related, opts) { + var DOMAIN_ERR = 'new ' + DOMAIN$6; + var localField = opts.localField; + if (!localField) { + throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField); + } - /** - * Lifecycle hook. - * - * @method Record#beforeLoadRelations - * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. - * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. - * @since 3.0.0 - */ - beforeLoadRelations: function beforeLoadRelations() {}, + var foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey; + if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) { + throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey); + } + if (utils.isString(related)) { + opts.relation = related; + if (!utils.isFunction(opts.getRelation)) { + throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation); + } + } else if (related) { + opts.relation = related.name; + } else { + throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related); + } + }, + assignTo: function assignTo(mapper) { + this.name = mapper.name; + Object.defineProperty(this, 'mapper', { value: mapper }); - /** - * Return the change history of this record since it was instantiated or - * {@link Record#commit} was called. - * - * @method Record#changeHistory - * @since 3.0.0 - */ - changeHistory: function changeHistory() { - return (this._get('history') || []).slice(); + mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] }); + mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] }); + mapper.relationList.push(this); + mapper.relationFields.push(this.localField); + }, + canFindLinkFor: function canFindLinkFor() { + return !!(this.foreignKey || this.localKey); + }, + getRelation: function getRelation() { + return this.relatedMapper; + }, + getForeignKey: function getForeignKey(record) { + return utils.get(record, this.mapper.idAttribute); }, + setForeignKey: function setForeignKey(record, relatedRecord) { + if (!record || !relatedRecord) { + return; + } - - /** - * Return changes to this record since it was instantiated or - * {@link Record#commit} was called. - * - * @example Record#changes - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user changes: ' + JSON.stringify(user.changes())) - * user.name = 'John' - * console.log('user changes: ' + JSON.stringify(user.changes())) - * - * @method Record#changes - * @param [opts] Configuration options. - * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. - * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. - * @returns {Object} Object describing the changes to this record since it was - * instantiated or its {@link Record#commit} method was last called. - * @since 3.0.0 - */ - changes: function changes(opts) { - opts || (opts = {}); - return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); + this._setForeignKey(record, relatedRecord); }, + _setForeignKey: function _setForeignKey(record, relatedRecords) { + var _this = this; + var idAttribute = this.mapper.idAttribute; - /** - * Make the record's current in-memory state it's only state, with any - * previous property values being set to current values. - * - * @example Record#commit - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user hasChanges: ' + user.hasChanges()) - * user.name = 'John' - * console.log('user hasChanges: ' + user.hasChanges()) - * user.commit() - * console.log('user hasChanges: ' + user.hasChanges()) - * - * @method Record#commit - * @since 3.0.0 - */ - commit: function commit() { - this._set('changed'); // unset - this._set('history', []); // clear history - this._set('previous', utils.plainCopy(this)); + if (!utils.isArray(relatedRecords)) { + relatedRecords = [relatedRecords]; + } + + relatedRecords.forEach(function (relatedRecord) { + utils.set(relatedRecord, _this.foreignKey, utils.get(record, idAttribute)); + }); + }, + getLocalField: function getLocalField(record) { + return utils.get(record, this.localField); + }, + setLocalField: function setLocalField(record, relatedData) { + return utils.set(record, this.localField, relatedData); }, + getInverse: function getInverse(mapper) { + if (!this.inverse) { + this.findInverseRelation(mapper); + } + return this.inverse; + }, + findInverseRelation: function findInverseRelation(mapper) { + var _this2 = this; - /** - * Call {@link Mapper#destroy} using this record's primary key. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('user') - * store.find('user', 1234).then((user) => { - * console.log(user.id) // 1234 - * - * // Destroy this user from the database - * return user.destroy() - * }) - * - * @method Record#destroy - * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}. - * @returns {Promise} The result of calling {@link Mapper#destroy} with the - * primary key of this record. - * @since 3.0.0 - */ - destroy: function destroy(opts) { - opts || (opts = {}); - var mapper = this._mapper(); - return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts); + this.getRelation().relationList.forEach(function (def) { + if (def.getRelation() === mapper && _this2.isInversedTo(def)) { + _this2.inverse = def; + return true; + } + }); + }, + isInversedTo: function isInversedTo(def) { + return !def.foreignKey || def.foreignKey === this.foreignKey; }, + addLinkedRecords: function addLinkedRecords(records) { + var _this3 = this; + var datastore = this.mapper.datastore; - /** - * Return the value at the given path for this instance. - * - * @example Record#get - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * - * const user = store.createRecord('user', { name: 'Bob' }) - * console.log('user.get("name"): ' + user.get('name')) - * - * @method Record#get - * @param {string} key Path of value to retrieve. - * @returns {*} Value at path. - * @since 3.0.0 - */ - 'get': function get(key) { - return utils.get(this, key); - }, + records.forEach(function (record) { + var relatedData = _this3.getLocalField(record); + if (utils.isFunction(_this3.add)) { + relatedData = _this3.add(datastore, _this3, record); + } else if (relatedData) { + relatedData = _this3.linkRecord(record, relatedData); + } - /** - * Return whether this record has changed since it was instantiated or - * {@link Record#commit} was called. - * - * @example Record#hasChanges - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user hasChanges: ' + user.hasChanges()) - * user.name = 'John' - * console.log('user hasChanges: ' + user.hasChanges()) - * user.commit() - * console.log('user hasChanges: ' + user.hasChanges()) - * - * @method Record#hasChanges - * @param [opts] Configuration options. - * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. - * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. - * @returns {boolean} Return whether the record has changed since it was - * instantiated or since its {@link Record#commit} method was called. - * @since 3.0.0 - */ - hasChanges: function hasChanges(opts) { - var quickHasChanges = !!(this._get('changed') || []).length; - return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); + var isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length; + + if (isEmptyLinks && _this3.canFindLinkFor(record)) { + relatedData = _this3.findExistingLinksFor(record); + } + + if (relatedData) { + _this3.setLocalField(record, relatedData); + } + }); + }, + removeLinkedRecords: function removeLinkedRecords(relatedMapper, records) { + var localField = this.localField; + records.forEach(function (record) { + utils.set(record, localField, undefined); + }); }, + linkRecord: function linkRecord(record, relatedRecord) { + var relatedId = utils.get(relatedRecord, this.mapper.idAttribute); + if (relatedId === undefined) { + var unsaved = this.relatedCollection.unsaved(); + if (unsaved.indexOf(relatedRecord) === -1) { + if (this.canAutoAddLinks) { + relatedRecord = this.relatedCollection.add(relatedRecord); + } + } + } else { + if (relatedRecord !== this.relatedCollection.get(relatedId)) { + this.setForeignKey(record, relatedRecord); - /** - * Return whether the record is unsaved. Records that have primary keys are - * considered "saved". Records without primary keys are considered "unsaved". - * - * @example Record#isNew - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * id: 1234 - * }) - * const user2 = store.createRecord('user') - * console.log('user isNew: ' + user.isNew()) // false - * console.log('user2 isNew: ' + user2.isNew()) // true - * - * @method Record#isNew - * @returns {boolean} Whether the record is unsaved. - * @since 3.0.0 - */ - isNew: function isNew(opts) { - return utils.get(this, this._mapper().idAttribute) === undefined; + if (this.canAutoAddLinks) { + relatedRecord = this.relatedCollection.add(relatedRecord); + } + } + } + + return relatedRecord; }, - /** - * Return whether the record in its current state passes validation. - * - * @example Record#isValid - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * const user = store.createRecord('user', { - * name: 1234 - * }, { - * noValidate: true // this allows us to put the record into an invalid state - * }) - * console.log('user isValid: ' + user.isValid()) - * user.name = 'John' - * console.log('user isValid: ' + user.isValid()) - * - * @method Record#isValid - * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. - * @returns {boolean} Whether the record in its current state passes - * validation. - * @since 3.0.0 - */ - isValid: function isValid(opts) { - return !this._mapper().validate(this, opts); + // e.g. user hasMany post via "foreignKey", so find all posts of user + findExistingLinksByForeignKey: function findExistingLinksByForeignKey(id) { + if (id === undefined || id === null) { + return; + } + return this.relatedCollection.filter(defineProperty({}, this.foreignKey, id)); + } +}); + +var BelongsToRelation = Relation.extend({ + getForeignKey: function getForeignKey(record) { + return utils.get(record, this.foreignKey); }, + _setForeignKey: function _setForeignKey(record, relatedRecord) { + utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute)); + }, + findExistingLinksFor: function findExistingLinksFor(record) { + // console.log('\tBelongsTo#findExistingLinksFor', record) + if (!record) { + return; + } + var relatedId = utils.get(record, this.foreignKey); + if (relatedId !== undefined && relatedId !== null) { + return this.relatedCollection.get(relatedId); + } + } +}, { + TYPE_NAME: 'belongsTo' +}); +var HasManyRelation = Relation.extend({ + validateOptions: function validateOptions(related, opts) { + Relation.prototype.validateOptions.call(this, related, opts); - /** - * Lazy load relations of this record, to be attached to the record once their - * loaded. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('user', { - * relations: { - * hasMany: { - * post: { - * localField: 'posts', - * foreignKey: 'user_id' - * } - * } - * } - * }) - * store.defineMapper('post', { - * relations: { - * belongsTo: { - * user: { - * localField: 'user', - * foreignKey: 'user_id' - * } - * } - * } - * }) - * store.find('user', 1234).then((user) => { - * console.log(user.id) // 1234 - * - * // Load the user's post relations - * return user.loadRelations(['post']) - * }).then((user) => { - * console.log(user.posts) // [{...}, {...}, ...] - * }) - * - * @method Record#loadRelations - * @param {string[]} [relations] List of relations to load. Can use localField - * names or Mapper names to pick relations. - * @param {Object} [opts] Configuration options. - * @returns {Promise} Resolves with the record, with the loaded relations now - * attached. - * @since 3.0.0 - */ - loadRelations: function loadRelations(relations, opts) { - var _this = this; + var localKeys = opts.localKeys; + var foreignKeys = opts.foreignKeys; + var foreignKey = opts.foreignKey; - var op = void 0; - var mapper = this._mapper(); - // Default values for arguments - relations || (relations = []); - if (utils.isString(relations)) { - relations = [relations]; + if (!foreignKey && !localKeys && !foreignKeys) { + throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey); } - opts || (opts = {}); - opts.with = relations; + }, + canFindLinkFor: function canFindLinkFor(record) { + var hasForeignKeys = this.foreignKey || this.foreignKeys; + return !!(hasForeignKeys || this.localKeys && utils.get(record, this.localKeys)); + }, + linkRecord: function linkRecord(record, relatedRecords) { + var _this = this; - // Fill in "opts" with the Model's configuration - utils._(opts, mapper); - opts.adapter = mapper.getAdapterName(opts); + var relatedCollection = this.relatedCollection; + var canAutoAddLinks = this.canAutoAddLinks; + var foreignKey = this.foreignKey; + var unsaved = this.relatedCollection.unsaved(); - // beforeLoadRelations lifecycle hook - op = opts.op = 'beforeLoadRelations'; - return utils.resolve(this[op](relations, opts)).then(function () { - // Now delegate to the adapter - op = opts.op = 'loadRelations'; - mapper.dbg(op, _this, relations, opts); - var tasks = []; - var task = void 0; - utils.forEachRelation(mapper, opts, function (def, optsCopy) { - var relatedMapper = def.getRelation(); - optsCopy.raw = false; - if (utils.isFunction(def.load)) { - task = def.load(mapper, def, _this, opts); - } else if (def.type === 'hasMany' || def.type === 'hasOne') { - if (def.foreignKey) { - task = superMethod(relatedMapper, 'findAll')(defineProperty({}, def.foreignKey, utils.get(_this, mapper.idAttribute)), optsCopy).then(function (relatedData) { - if (def.type === 'hasOne') { - return relatedData.length ? relatedData[0] : undefined; - } - return relatedData; - }); - } else if (def.localKeys) { - task = superMethod(relatedMapper, 'findAll')({ - where: defineProperty({}, relatedMapper.idAttribute, { - 'in': utils.get(_this, def.localKeys) - }) - }); - } else if (def.foreignKeys) { - task = superMethod(relatedMapper, 'findAll')({ - where: defineProperty({}, def.foreignKeys, { - 'contains': utils.get(_this, mapper.idAttribute) - }) - }, opts); - } - } else if (def.type === 'belongsTo') { - var key = utils.get(_this, def.foreignKey); - if (utils.isSorN(key)) { - task = superMethod(relatedMapper, 'find')(key, optsCopy); - } + return relatedRecords.map(function (relatedRecord) { + var relatedId = relatedCollection.recordId(relatedRecord); + + if (relatedId === undefined && unsaved.indexOf(relatedRecord) === -1 || relatedRecord !== relatedCollection.get(relatedId)) { + if (foreignKey) { + // TODO: slow, could be optimized? But user loses hook + _this.setForeignKey(record, relatedRecord); } - if (task) { - task = task.then(function (relatedData) { - def.setLocalField(_this, relatedData); - }); - tasks.push(task); + if (canAutoAddLinks) { + relatedRecord = relatedCollection.add(relatedRecord); } - }); - return Promise.all(tasks); - }).then(function () { - // afterLoadRelations lifecycle hook - op = opts.op = 'afterLoadRelations'; - return utils.resolve(_this[op](relations, opts)).then(function () { - return _this; - }); + } + + return relatedRecord; }); }, + findExistingLinksFor: function findExistingLinksFor(record) { + var id = utils.get(record, this.mapper.idAttribute); + var ids = this.localKeys ? utils.get(record, this.localKeys) : null; + var records = void 0; + if (id !== undefined && this.foreignKey) { + records = this.findExistingLinksByForeignKey(id); + } else if (this.localKeys && ids) { + records = this.findExistingLinksByLocalKeys(ids); + } else if (id !== undefined && this.foreignKeys) { + records = this.findExistingLinksByForeignKeys(id); + } - /** - * Return the properties with which this record was instantiated. - * - * @example Record#previous - * // import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * name: 'William' - * }) - * console.log('user previous: ' + JSON.stringify(user.previous())) - * user.name = 'Bob' - * console.log('user previous: ' + JSON.stringify(user.previous())) - * user.commit() - * console.log('user previous: ' + JSON.stringify(user.previous())) - * - * @method Record#previous - * @param {string} [key] If specified, return just the initial value of the - * given key. - * @returns {Object} The initial properties of this record. - * @since 3.0.0 - */ - previous: function previous(key) { - if (key) { - return this._get('previous.' + key); + if (records && records.length) { + return records; } - return this._get('previous'); }, - /** - * Revert changes to this record back to the properties it had when it was - * instantiated. - * - * @example Record#revert - * // import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * name: 'William' - * }) - * console.log('user: ' + JSON.stringify(user)) - * user.name = 'Bob' - * console.log('user: ' + JSON.stringify(user)) - * user.revert() - * console.log('user: ' + JSON.stringify(user)) - * - * @method Record#revert - * @param {Object} [opts] Configuration options. - * @param {string[]} [opts.preserve] Array of strings or Regular Expressions - * denoting properties that should not be reverted. - * @since 3.0.0 - */ - revert: function revert(opts) { - var _this2 = this; - - var previous = this._get('previous'); - opts || (opts = {}); - opts.preserve || (opts.preserve = []); - utils.forOwn(this, function (value, key) { - if (key !== _this2._mapper().idAttribute && !previous.hasOwnProperty(key) && _this2.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) { - delete _this2[key]; - } + // e.g. user hasMany group via "foreignKeys", so find all users of a group + findExistingLinksByLocalKeys: function findExistingLinksByLocalKeys(ids) { + return this.relatedCollection.filter({ + where: defineProperty({}, this.mapper.idAttribute, { + 'in': ids + }) }); - utils.forOwn(previous, function (value, key) { - if (opts.preserve.indexOf(key) === -1) { - _this2[key] = value; - } - }); - this.commit(); }, - /** - * Delegates to {@link Mapper#create} or {@link Mapper#update}. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('session') - * const session = store.createRecord('session', { topic: 'Node.js' }) - * - * // Create a new record in the database - * session.save().then(() => { - * console.log(session.id) // 1234 - * - * session.skill_level = 'beginner' - * - * // Update the record in the database - * return user.save() - * }) - * - * @method Record#save - * @param {Object} [opts] Configuration options. See {@link Mapper#create} and - * {@link Mapper#update}. - * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`. - * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when - * `opts.changesOnly` is `true`. - * @param {Array} [opts.ignore] Passed to {@link Record#changes} when - * `opts.changesOnly` is `true`. - * @returns {Promise} The result of calling {@link Mapper#create} or - * {@link Mapper#update}. - * @since 3.0.0 - */ - save: function save(opts) { - var _this3 = this; - - opts || (opts = {}); - var mapper = this._mapper(); - var id = utils.get(this, mapper.idAttribute); - var props = this; + // e.g. group hasMany user via "localKeys", so find all groups that own a user + findExistingLinksByForeignKeys: function findExistingLinksByForeignKeys(id) { + return this.relatedCollection.filter({ + where: defineProperty({}, this.foreignKeys, { + 'contains': id + }) + }); + } +}, { + TYPE_NAME: 'hasMany' +}); - var postProcess = function postProcess(result) { - var record = opts.raw ? result.data : result; - if (record) { - utils.deepMixIn(_this3, record); - _this3.commit(); - } - return result; - }; +var HasOneRelation = Relation.extend({ + findExistingLinksFor: function findExistingLinksFor(relatedMapper, record) { + var recordId = utils.get(record, relatedMapper.idAttribute); + var records = this.findExistingLinksByForeignKey(recordId); - if (id === undefined) { - return superMethod(mapper, 'create')(props, opts).then(postProcess); - } - if (opts.changesOnly) { - var changes = this.changes(opts); - props = {}; - utils.fillIn(props, changes.added); - utils.fillIn(props, changes.changed); + if (records && records.length) { + return records[0]; } - return superMethod(mapper, 'update')(id, props, opts).then(postProcess); - }, + } +}, { + TYPE_NAME: 'hasOne' +}); +[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) { + Relation[RelationType.TYPE_NAME] = function (related, options) { + return new RelationType(related, options); + }; +}); - /** - * Set the value for a given key, or the values for the given keys if "key" is - * an object. Triggers change events on those properties that have `track: true` - * in {@link Mapper#schema}. - * - * @example Record#set - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * - * const user = store.createRecord('user') - * console.log('user: ' + JSON.stringify(user)) - * - * user.set('name', 'Bob') - * console.log('user: ' + JSON.stringify(user)) - * - * user.set({ age: 30, role: 'admin' }) - * console.log('user: ' + JSON.stringify(user)) - * - * @fires Record#change - * @method Record#set - * @param {(string|Object)} key Key to set or hash of key-value pairs to set. - * @param {*} [value] Value to set for the given key. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.silent=false] Whether to trigger change events. - * @since 3.0.0 - */ - 'set': function set(key, value, opts) { - if (utils.isObject(key)) { - opts = value; - } - opts || (opts = {}); - if (opts.silent) { - this._set('silent', true); - } - utils.set(this, key, value); - if (!this._get('eventId')) { - this._set('silent'); // unset - } - }, +/** + * BelongsTo relation decorator. You probably won't use this directly. + * + * @name module:js-data.belongsTo + * @method + * @param {Mapper} related The relation the target belongs to. + * @param {Object} opts Configuration options. + * @param {string} opts.foreignKey The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ +var belongsTo = function belongsTo(related, opts) { + return function (mapper) { + Relation.belongsTo(related, opts).assignTo(mapper); + }; +}; +/** + * HasMany relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasMany + * @method + * @param {Mapper} related The relation of which the target has many. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ +var hasMany = function hasMany(related, opts) { + return function (mapper) { + Relation.hasMany(related, opts).assignTo(mapper); + }; +}; - /** - * Return a plain object representation of this record. If the class from - * which this record was created has a Mapper, then {@link Mapper#toJSON} will - * be called with this record instead. - * - * @example Record#toJSON - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * const user = store.createRecord('user', { - * name: 'John', - * $$hashKey: '1234' - * }) - * console.log('user: ' + JSON.stringify(user.toJSON())) - * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true }))) - * - * @method Record#toJSON - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.strict] Whether to exclude properties that are not - * defined in {@link Mapper#schema}. - * @param {string[]} [opts.with] Array of relation names or relation fields - * to include in the representation. Only available as an option if the class - * from which this record was created has a Mapper and this record resides in - * an instance of {@link DataStore}. - * @returns {Object} Plain object representation of this record. - * @since 3.0.0 - */ - toJSON: function toJSON(opts) { - var _this4 = this; +/** + * HasOne relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasOne + * @method + * @param {Mapper} related The relation of which the target has one. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ +var hasOne = function hasOne(related, opts) { + return function (mapper) { + Relation.hasOne(related, opts).assignTo(mapper); + }; +}; - var mapper = this.constructor.mapper; - if (mapper) { - return mapper.toJSON(this, opts); - } else { - var _ret = function () { - var json = {}; - utils.forOwn(_this4, function (prop, key) { - json[key] = utils.plainCopy(prop); - }); - return { - v: json - }; - }(); +var DOMAIN$5 = 'Record'; - if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; - } - }, +var superMethod = function superMethod(mapper, name) { + var store = mapper.datastore; + if (store && store[name]) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + return store[name].apply(store, [mapper.name].concat(args)); + }; + } + return mapper[name].bind(mapper); +}; - /** - * Unset the value for a given key. Triggers change events on those properties - * that have `track: true` in {@link Mapper#schema}. +/** + * js-data's Record class. An instance of `Record` corresponds to an in-memory + * representation of a single row or document in a database, Firebase, + * localstorage, etc. Basically, a `Record` instance represents whatever kind of + * entity in your persistence layer that has a primary key. + * + * ```javascript + * import {Record} from 'js-data' + * ``` + * + * @example Record#constructor + * // Normally you would do: import {Record} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Record} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a plain record + * let record = new Record() + * console.log('record: ' + JSON.stringify(record)) + * + * // You can supply properties on instantiation + * record = new Record({ name: 'John' }) + * console.log('record: ' + JSON.stringify(record)) + * + * @example Record#constructor2 + * // Normally you would do: import {Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a record that's associated with a Mapper: + * const UserMapper = new Mapper({ name: 'user' }) + * const User = UserMapper.recordClass + * const user = UserMapper.createRecord({ name: 'John' }) + * const user2 = new User({ name: 'Sally' }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user2: ' + JSON.stringify(user2)) + * + * @example Record#constructor3 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user') + * + * // Instantiate a record that's associated with a store's Mapper + * const user = store.createRecord('user', { name: 'John' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor4 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Validate on instantiation + * const user = store.createRecord('user', { name: 1234 }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor5 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Skip validation on instantiation + * const user = store.createRecord('user', { name: 1234 }, { noValidate: true }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user.isValid(): ' + user.isValid()) + * + * @class Record + * @extends Component + * @param {Object} [props] The initial properties of the new Record instance. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.noValidate=false] Whether to skip validation on the + * initial properties. + * @since 3.0.0 + */ +function Record(props, opts) { + utils.classCallCheck(this, Record); + Settable.call(this); + props || (props = {}); + opts || (opts = {}); + var _set = this._set; + // TODO: Optimize these strings + _set('creating', true); + if (opts.noValidate) { + _set('noValidate', true); + } + // Set the idAttribute value first, if it exists. + var mapper = this.constructor.mapper; + var id = mapper ? utils.get(props, mapper.idAttribute) : undefined; + if (id !== undefined) { + utils.set(this, mapper.idAttribute, id); + } + utils.fillIn(this, props); + _set('creating', false); + _set('noValidate', false); + _set('previous', utils.plainCopy(props)); +} + +var Record$1 = Component$1.extend({ + constructor: Record, + + /** + * Returns the {@link Mapper} paired with this record's class, if any. * - * @example Record#unset + * @method Record#_mapper + * @returns {Mapper} The {@link Mapper} paired with this record's class, if any. + * @since 3.0.0 + */ + _mapper: function _mapper() { + var mapper = this.constructor.mapper; + if (!mapper) { + throw utils.err(DOMAIN$5 + '#_mapper', '')(404, 'mapper'); + } + return mapper; + }, + + + /** + * Lifecycle hook. + * + * @method Record#afterLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */ + afterLoadRelations: function afterLoadRelations() {}, + + + /** + * Lifecycle hook. + * + * @method Record#beforeLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */ + beforeLoadRelations: function beforeLoadRelations() {}, + + + /** + * Return the change history of this record since it was instantiated or + * {@link Record#commit} was called. + * + * @method Record#changeHistory + * @since 3.0.0 + */ + changeHistory: function changeHistory() { + return (this._get('history') || []).slice(); + }, + + + /** + * Return changes to this record since it was instantiated or + * {@link Record#commit} was called. + * + * @example Record#changes * // Normally you would do: import {Container} from 'js-data' * const JSData = require('js-data@3.0.0-beta.10') * const {Container} = JSData * console.log('Using JSData v' + JSData.version.full) + * * const store = new Container() * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user changes: ' + JSON.stringify(user.changes())) + * user.name = 'John' + * console.log('user changes: ' + JSON.stringify(user.changes())) * - * const user = store.createRecord('user', { - * name: 'John' - * }) - * console.log('user: ' + JSON.stringify(user)) - * - * user.unset('name') - * console.log('user: ' + JSON.stringify(user)) - * - * @method Record#unset - * @param {string} key Key to unset. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @method Record#changes + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {Object} Object describing the changes to this record since it was + * instantiated or its {@link Record#commit} method was last called. * @since 3.0.0 */ - unset: function unset(key, opts) { - this.set(key, undefined, opts); + changes: function changes(opts) { + opts || (opts = {}); + return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); }, /** - * Validate this record based on its current properties. + * Make the record's current in-memory state it's only state, with any + * previous property values being set to current values. * - * @example Record#validate + * @example Record#commit * // Normally you would do: import {Container} from 'js-data' * const JSData = require('js-data@3.0.0-beta.10') * const {Container} = JSData * console.log('Using JSData v' + JSData.version.full) + * * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * const user = store.createRecord('user', { - * name: 1234 - * }, { - * noValidate: true // this allows us to put the record into an invalid state - * }) - * console.log('user validation: ' + JSON.stringify(user.validate())) + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) * user.name = 'John' - * console.log('user validation: ' + user.validate()) + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) * - * @method Record#validate - * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. - * @returns {*} Array of errors or `undefined` if no errors. + * @method Record#commit * @since 3.0.0 */ - validate: function validate(opts) { - return this._mapper().validate(this, opts); - } -}); + commit: function commit() { + this._set('changed'); // unset + this._set('history', []); // clear history + this._set('previous', utils.plainCopy(this)); + }, -/** - * Allow records to emit events. - * - * An record's registered listeners are stored in the record's private data. - */ -utils.eventify(Record.prototype, function () { - return this._get('events'); -}, function (value) { - this._set('events', value); -}); - -var DOMAIN$6 = 'Schema'; - -/** - * A function map for each of the seven primitive JSON types defined by the core specification. - * Each function will check a given value and return true or false if the value is an instance of that type. - * ``` - * types.integer(1) // returns true - * types.string({}) // returns false - * ``` - * http://json-schema.org/latest/json-schema-core.html#anchor8 - * @name Schema.types - * @type {Object} - */ -var types = { - array: utils.isArray, - boolean: utils.isBoolean, - integer: utils.isInteger, - 'null': utils.isNull, - number: utils.isNumber, - object: utils.isObject, - string: utils.isString -}; - -/** - * @ignore - */ -var segmentToString = function segmentToString(segment, prev) { - var str = ''; - if (segment) { - if (utils.isNumber(segment)) { - str += '[' + segment + ']'; - } else if (prev) { - str += '.' + segment; - } else { - str += '' + segment; - } - } - return str; -}; - -/** - * @ignore - */ -var makePath = function makePath(opts) { - opts || (opts = {}); - var path = ''; - var segments = opts.path || []; - segments.forEach(function (segment) { - path += segmentToString(segment, path); - }); - path += segmentToString(opts.prop, path); - return path; -}; - -/** - * @ignore - */ -var makeError = function makeError(actual, expected, opts) { - return { - expected: expected, - actual: '' + actual, - path: makePath(opts) - }; -}; - -/** - * @ignore - */ -var addError = function addError(actual, expected, opts, errors) { - errors.push(makeError(actual, expected, opts)); -}; - -/** - * @ignore - */ -var maxLengthCommon = function maxLengthCommon(keyword, value, schema, opts) { - var max = schema[keyword]; - if (value.length > max) { - return makeError(value.length, 'length no more than ' + max, opts); - } -}; - -/** - * @ignore - */ -var minLengthCommon = function minLengthCommon(keyword, value, schema, opts) { - var min = schema[keyword]; - if (value.length < min) { - return makeError(value.length, 'length no less than ' + min, opts); - } -}; -/** - * A map of all object member validation functions for each keyword defined in the JSON Schema. - * @name Schema.validationKeywords - * @type {Object} - */ -var validationKeywords = { /** - * Validates the provided value against all schemas defined in the Schemas `allOf` keyword. - * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value. + * Call {@link Mapper#destroy} using this record's primary key. * - * The value of this keyword MUST be an array. This array MUST have at least one element. - * Each element of this array MUST be a valid JSON Schema. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' * - * see http://json-schema.org/latest/json-schema-validation.html#anchor82 + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user') + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 * - * @name Schema.validationKeywords.allOf - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `allOf` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * // Destroy this user from the database + * return user.destroy() + * }) + * + * @method Record#destroy + * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}. + * @returns {Promise} The result of calling {@link Mapper#destroy} with the + * primary key of this record. + * @since 3.0.0 */ - - allOf: function allOf(value, schema, opts) { - var allErrors = []; - schema.allOf.forEach(function (_schema) { - allErrors = allErrors.concat(_validate(value, _schema, opts) || []); - }); - return allErrors.length ? undefined : allErrors; + destroy: function destroy(opts) { + opts || (opts = {}); + var mapper = this._mapper(); + return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts); }, /** - * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword. - * The instance is valid against this keyword if and only if it is valid against - * at least one of the schemas in this keyword's value. + * Return the value at the given path for this instance. * - * The value of this keyword MUST be an array. This array MUST have at least one element. - * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema. - * see http://json-schema.org/latest/json-schema-validation.html#anchor85 + * @example Record#get + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') * - * @name Schema.validationKeywords.anyOf - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `anyOf` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * const user = store.createRecord('user', { name: 'Bob' }) + * console.log('user.get("name"): ' + user.get('name')) + * + * @method Record#get + * @param {string} key Path of value to retrieve. + * @returns {*} Value at path. + * @since 3.0.0 */ - anyOf: function anyOf(value, schema, opts) { - var validated = false; - var allErrors = []; - schema.anyOf.forEach(function (_schema) { - var errors = _validate(value, _schema, opts); - if (errors) { - allErrors = allErrors.concat(errors); - } else { - validated = true; - } - }); - return validated ? undefined : allErrors; + 'get': function get(key) { + return utils.get(this, key); }, /** - * http://json-schema.org/latest/json-schema-validation.html#anchor70 + * Return whether this record has changed since it was instantiated or + * {@link Record#commit} was called. * - * @name Schema.validationKeywords.dependencies - * @method - * @param {*} value TODO - * @param {Object} schema TODO - * @param {Object} opts TODO + * @example Record#hasChanges + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) + * user.name = 'John' + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) + * + * @method Record#hasChanges + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {boolean} Return whether the record has changed since it was + * instantiated or since its {@link Record#commit} method was called. + * @since 3.0.0 */ - dependencies: function dependencies(value, schema, opts) { - // TODO + hasChanges: function hasChanges(opts) { + var quickHasChanges = !!(this._get('changed') || []).length; + return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); }, /** - * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword - * Validation succeeds if the value is deeply equal to one of the values in the array. - * see http://json-schema.org/latest/json-schema-validation.html#anchor76 + * Return whether the record is unsaved. Records that have primary keys are + * considered "saved". Records without primary keys are considered "unsaved". * - * @name Schema.validationKeywords.enum - * @method - * @param {*} value Value to validate - * @param {Object} schema Schema containing the `enum` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#isNew + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * id: 1234 + * }) + * const user2 = store.createRecord('user') + * console.log('user isNew: ' + user.isNew()) // false + * console.log('user2 isNew: ' + user2.isNew()) // true + * + * @method Record#isNew + * @returns {boolean} Whether the record is unsaved. + * @since 3.0.0 */ - enum: function _enum(value, schema, opts) { - var possibleValues = schema['enum']; - if (utils.findIndex(possibleValues, function (item) { - return utils.deepEqual(item, value); - }) === -1) { - return makeError(value, 'one of (' + possibleValues.join(', ') + ')', opts); - } + isNew: function isNew(opts) { + return utils.get(this, this._mapper().idAttribute) === undefined; }, /** - * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword - * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules. + * Return whether the record in its current state passes validation. * - * @name Schema.validationKeywords.items - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the items keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#isValid + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user isValid: ' + user.isValid()) + * user.name = 'John' + * console.log('user isValid: ' + user.isValid()) + * + * @method Record#isValid + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {boolean} Whether the record in its current state passes + * validation. + * @since 3.0.0 */ - items: function items(value, schema, opts) { - opts || (opts = {}); - // TODO: additionalItems - var items = schema.items; - var errors = []; - var checkingTuple = utils.isArray(items); - var length = value.length; - for (var prop = 0; prop < length; prop++) { - if (checkingTuple) { - // Validating a tuple, instead of just checking each item against the - // same schema - items = schema.items[prop]; + isValid: function isValid(opts) { + return !this._mapper().validate(this, opts); + }, + removeInverseRelation: function removeInverseRelation(currentParent, id, inverseDef, idAttribute) { + var _this = this; + + if (inverseDef.type === hasOneType) { + safeSetLink(currentParent, inverseDef.localField, undefined); + } else if (inverseDef.type === hasManyType) { + // e.g. remove comment from otherPost.comments + var children = utils.get(currentParent, inverseDef.localField); + if (id === undefined) { + utils.remove(children, function (child) { + return child === _this; + }); + } else { + utils.remove(children, function (child) { + return child === _this || id === utils.get(child, idAttribute); + }); } - opts.prop = prop; - errors = errors.concat(_validate(value[prop], items, opts) || []); } - return errors.length ? errors : undefined; }, + setupInverseRelation: function setupInverseRelation(record, id, inverseDef, idAttribute) { + var _this2 = this; - - /** - * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword - * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword. - * http://json-schema.org/latest/json-schema-validation.html#anchor17 - * - * @name Schema.validationKeywords.maximum - * @method - * @param {*} value Number to validate against the keyword. - * @param {Object} schema Schema containing the `maximum` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - maximum: function maximum(value, schema, opts) { - // Must be a number - var maximum = schema.maximum; - // Must be a boolean - // Depends on maximum - // default: false - var exclusiveMaximum = schema.exclusiveMaximum; - if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof maximum === 'undefined' ? 'undefined' : _typeof(maximum)) && !(exclusiveMaximum ? maximum > value : maximum >= value)) { - return exclusiveMaximum ? makeError(value, 'no more than nor equal to ' + maximum, opts) : makeError(value, 'no more than ' + maximum, opts); + // Update (set) inverse relation + if (inverseDef.type === hasOneType) { + // e.g. someUser.profile = profile + safeSetLink(record, inverseDef.localField, this); + } else if (inverseDef.type === hasManyType) { + // e.g. add comment to somePost.comments + var children = utils.get(record, inverseDef.localField); + if (id === undefined) { + utils.noDupeAdd(children, this, function (child) { + return child === _this2; + }); + } else { + utils.noDupeAdd(children, this, function (child) { + return child === _this2 || id === utils.get(child, idAttribute); + }); + } } }, /** - * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword. - * Validation succeeds if the length of the array is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor42 + * Lazy load relations of this record, to be attached to the record once their + * loaded. * - * @name Schema.validationKeywords.maxItems - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `maxItems` keyword. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user', { + * relations: { + * hasMany: { + * post: { + * localField: 'posts', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.defineMapper('post', { + * relations: { + * belongsTo: { + * user: { + * localField: 'user', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 + * + * // Load the user's post relations + * return user.loadRelations(['post']) + * }).then((user) => { + * console.log(user.posts) // [{...}, {...}, ...] + * }) + * + * @method Record#loadRelations + * @param {string[]} [relations] List of relations to load. Can use localField + * names or Mapper names to pick relations. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @returns {Promise} Resolves with the record, with the loaded relations now + * attached. + * @since 3.0.0 */ - maxItems: function maxItems(value, schema, opts) { - if (utils.isArray(value)) { - return maxLengthCommon('maxItems', value, schema, opts); + loadRelations: function loadRelations(relations, opts) { + var _this3 = this; + + var op = void 0; + var mapper = this._mapper(); + + // Default values for arguments + relations || (relations = []); + if (utils.isString(relations)) { + relations = [relations]; } - }, + opts || (opts = {}); + opts.with = relations; + // Fill in "opts" with the Model's configuration + utils._(opts, mapper); + opts.adapter = mapper.getAdapterName(opts); - /** - * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword. - * Validation succeeds if the length of the string is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor26 - * - * @name Schema.validationKeywords.maxLength - * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `maxLength` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - maxLength: function maxLength(value, schema, opts) { - return maxLengthCommon('maxLength', value, schema, opts); + // beforeLoadRelations lifecycle hook + op = opts.op = 'beforeLoadRelations'; + return utils.resolve(this[op](relations, opts)).then(function () { + // Now delegate to the adapter + op = opts.op = 'loadRelations'; + mapper.dbg(op, _this3, relations, opts); + var tasks = []; + var task = void 0; + utils.forEachRelation(mapper, opts, function (def, optsCopy) { + var relatedMapper = def.getRelation(); + optsCopy.raw = false; + if (utils.isFunction(def.load)) { + task = def.load(mapper, def, _this3, opts); + } else if (def.type === 'hasMany' || def.type === 'hasOne') { + if (def.foreignKey) { + task = superMethod(relatedMapper, 'findAll')(defineProperty({}, def.foreignKey, utils.get(_this3, mapper.idAttribute)), optsCopy).then(function (relatedData) { + if (def.type === 'hasOne') { + return relatedData.length ? relatedData[0] : undefined; + } + return relatedData; + }); + } else if (def.localKeys) { + task = superMethod(relatedMapper, 'findAll')({ + where: defineProperty({}, relatedMapper.idAttribute, { + 'in': utils.get(_this3, def.localKeys) + }) + }); + } else if (def.foreignKeys) { + task = superMethod(relatedMapper, 'findAll')({ + where: defineProperty({}, def.foreignKeys, { + 'contains': utils.get(_this3, mapper.idAttribute) + }) + }, opts); + } + } else if (def.type === 'belongsTo') { + var key = utils.get(_this3, def.foreignKey); + if (utils.isSorN(key)) { + task = superMethod(relatedMapper, 'find')(key, optsCopy); + } + } + if (task) { + task = task.then(function (relatedData) { + def.setLocalField(_this3, relatedData); + }); + tasks.push(task); + } + }); + return Promise.all(tasks); + }).then(function () { + // afterLoadRelations lifecycle hook + op = opts.op = 'afterLoadRelations'; + return utils.resolve(_this3[op](relations, opts)).then(function () { + return _this3; + }); + }); }, /** - * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword. - * Validation succeeds if the object's property count is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor54 + * Return the properties with which this record was instantiated. * - * @name Schema.validationKeywords.maxProperties - * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `maxProperties` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#previous + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.name = 'Bob' + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.commit() + * console.log('user previous: ' + JSON.stringify(user.previous())) + * + * @method Record#previous + * @param {string} [key] If specified, return just the initial value of the + * given key. + * @returns {Object} The initial properties of this record. + * @since 3.0.0 */ - maxProperties: function maxProperties(value, schema, opts) { - // validate only objects - if (!utils.isObject(value)) return; - var maxProperties = schema.maxProperties; - var length = Object.keys(value).length; - if (length > maxProperties) { - return makeError(length, 'no more than ' + maxProperties + ' properties', opts); + previous: function previous(key) { + if (key) { + return this._get('previous.' + key); } + return this._get('previous'); }, /** - * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword - * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword. - * http://json-schema.org/latest/json-schema-validation.html#anchor21 + * Revert changes to this record back to the properties it had when it was + * instantiated. * - * @name Schema.validationKeywords.minimum - * @method - * @param {*} value Number to validate against the keyword. - * @param {Object} schema Schema containing the `minimum` keyword. + * @example Record#revert + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user: ' + JSON.stringify(user)) + * user.name = 'Bob' + * console.log('user: ' + JSON.stringify(user)) + * user.revert() + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#revert * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {string[]} [opts.preserve] Array of strings or Regular Expressions + * denoting properties that should not be reverted. + * @since 3.0.0 */ - minimum: function minimum(value, schema, opts) { - // Must be a number - var minimum = schema.minimum; - // Must be a boolean - // Depends on minimum - // default: false - var exclusiveMinimum = schema.exclusiveMinimum; - if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof minimum === 'undefined' ? 'undefined' : _typeof(minimum)) && !(exclusiveMinimum ? value > minimum : value >= minimum)) { - return exclusiveMinimum ? makeError(value, 'no less than nor equal to ' + minimum, opts) : makeError(value, 'no less than ' + minimum, opts); - } + revert: function revert(opts) { + var _this4 = this; + + var previous = this._get('previous'); + opts || (opts = {}); + opts.preserve || (opts.preserve = []); + utils.forOwn(this, function (value, key) { + if (key !== _this4._mapper().idAttribute && !previous.hasOwnProperty(key) && _this4.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) { + delete _this4[key]; + } + }); + utils.forOwn(previous, function (value, key) { + if (opts.preserve.indexOf(key) === -1) { + _this4[key] = value; + } + }); + this.commit(); }, /** - * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword. - * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor45 + * Delegates to {@link Mapper#create} or {@link Mapper#update}. * - * @name Schema.validationKeywords.minItems - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `minItems` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('session') + * const session = store.createRecord('session', { topic: 'Node.js' }) + * + * // Create a new record in the database + * session.save().then(() => { + * console.log(session.id) // 1234 + * + * session.skill_level = 'beginner' + * + * // Update the record in the database + * return user.save() + * }) + * + * @method Record#save + * @param {Object} [opts] Configuration options. See {@link Mapper#create} and + * {@link Mapper#update}. + * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`. + * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @param {Array} [opts.ignore] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @returns {Promise} The result of calling {@link Mapper#create} or + * {@link Mapper#update}. + * @since 3.0.0 */ - minItems: function minItems(value, schema, opts) { - if (utils.isArray(value)) { - return minLengthCommon('minItems', value, schema, opts); - } - }, + save: function save(opts) { + var _this5 = this; + opts || (opts = {}); + var mapper = this._mapper(); + var id = utils.get(this, mapper.idAttribute); + var props = this; - /** - * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword. - * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor29 - * - * @name Schema.validationKeywords.minLength - * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `minLength` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - minLength: function minLength(value, schema, opts) { - return minLengthCommon('minLength', value, schema, opts); + var postProcess = function postProcess(result) { + var record = opts.raw ? result.data : result; + if (record) { + utils.deepMixIn(_this5, record); + _this5.commit(); + } + return result; + }; + + if (id === undefined) { + return superMethod(mapper, 'create')(props, opts).then(postProcess); + } + if (opts.changesOnly) { + var changes = this.changes(opts); + props = {}; + utils.fillIn(props, changes.added); + utils.fillIn(props, changes.changed); + } + return superMethod(mapper, 'update')(id, props, opts).then(postProcess); }, /** - * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword. - * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor57 + * Set the value for a given key, or the values for the given keys if "key" is + * an object. Triggers change events on those properties that have `track: true` + * in {@link Mapper#schema}. * - * @name Schema.validationKeywords.minProperties - * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `minProperties` keyword. + * @example Record#set + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set('name', 'Bob') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set({ age: 30, role: 'admin' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @fires Record#change + * @method Record#set + * @param {(string|Object)} key Key to set or hash of key-value pairs to set. + * @param {*} [value] Value to set for the given key. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 */ - minProperties: function minProperties(value, schema, opts) { - // validate only objects - if (!utils.isObject(value)) return; - var minProperties = schema.minProperties; - var length = Object.keys(value).length; - if (length < minProperties) { - return makeError(length, 'no more than ' + minProperties + ' properties', opts); + 'set': function set(key, value, opts) { + if (utils.isObject(key)) { + opts = value; + } + opts || (opts = {}); + if (opts.silent) { + this._set('silent', true); + } + utils.set(this, key, value); + if (!this._get('eventId')) { + this._set('silent'); // unset } }, /** - * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword. - * Validation succeeds if the number can be divided equally into the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor14 + * Return a plain object representation of this record. If the class from + * which this record was created has a Mapper, then {@link Mapper#toJSON} will + * be called with this record instead. * - * @name Schema.validationKeywords.multipleOf - * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing the `multipleOf` keyword. + * @example Record#toJSON + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * const user = store.createRecord('user', { + * name: 'John', + * $$hashKey: '1234' + * }) + * console.log('user: ' + JSON.stringify(user.toJSON())) + * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true }))) + * + * @method Record#toJSON * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.strict] Whether to exclude properties that are not + * defined in {@link Mapper#schema}. + * @param {string[]} [opts.with] Array of relation names or relation fields + * to include in the representation. Only available as an option if the class + * from which this record was created has a Mapper and this record resides in + * an instance of {@link DataStore}. + * @returns {Object} Plain object representation of this record. + * @since 3.0.0 */ - multipleOf: function multipleOf(value, schema, opts) { - var multipleOf = schema.multipleOf; - if (utils.isNumber(value)) { - if (value / multipleOf % 1 !== 0) { - return makeError(value, 'multipleOf ' + multipleOf, opts); - } + toJSON: function toJSON(opts) { + var _this6 = this; + + var mapper = this.constructor.mapper; + if (mapper) { + return mapper.toJSON(this, opts); + } else { + var _ret = function () { + var json = {}; + utils.forOwn(_this6, function (prop, key) { + json[key] = utils.plainCopy(prop); + }); + return { + v: json + }; + }(); + + if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; } }, /** - * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword. - * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value. + * Unset the value for a given key. Triggers change events on those properties + * that have `track: true` in {@link Mapper#schema}. * - * see http://json-schema.org/latest/json-schema-validation.html#anchor91 - * @name Schema.validationKeywords.not - * @method - * @param {*} value to be checked. - * @param {Object} schema Schema containing the not keyword. + * @example Record#unset + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user', { + * name: 'John' + * }) + * console.log('user: ' + JSON.stringify(user)) + * + * user.unset('name') + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#unset + * @param {string} key Key to unset. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 */ - not: function not(value, schema, opts) { - if (!_validate(value, schema.not, opts)) { - // TODO: better messaging - return makeError('succeeded', 'should have failed', opts); + unset: function unset(key, opts) { + this.set(key, undefined, opts); + }, + + + /** + * Validate this record based on its current properties. + * + * @example Record#validate + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user validation: ' + JSON.stringify(user.validate())) + * user.name = 'John' + * console.log('user validation: ' + user.validate()) + * + * @method Record#validate + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {*} Array of errors or `undefined` if no errors. + * @since 3.0.0 + */ + validate: function validate(opts) { + return this._mapper().validate(this, opts); + } +}); + +/** + * Allow records to emit events. + * + * An record's registered listeners are stored in the record's private data. + */ +utils.eventify(Record.prototype, function () { + return this._get('events'); +}, function (value) { + this._set('events', value); +}); + +var DOMAIN$7 = 'Schema'; + +/** + * A function map for each of the seven primitive JSON types defined by the core specification. + * Each function will check a given value and return true or false if the value is an instance of that type. + * ``` + * types.integer(1) // returns true + * types.string({}) // returns false + * ``` + * http://json-schema.org/latest/json-schema-core.html#anchor8 + * @name Schema.types + * @type {Object} + */ +var types = { + array: utils.isArray, + boolean: utils.isBoolean, + integer: utils.isInteger, + 'null': utils.isNull, + number: utils.isNumber, + object: utils.isObject, + string: utils.isString +}; + +/** + * @ignore + */ +var segmentToString = function segmentToString(segment, prev) { + var str = ''; + if (segment) { + if (utils.isNumber(segment)) { + str += '[' + segment + ']'; + } else if (prev) { + str += '.' + segment; + } else { + str += '' + segment; } + } + return str; +}; + +/** + * @ignore + */ +var makePath = function makePath(opts) { + opts || (opts = {}); + var path = ''; + var segments = opts.path || []; + segments.forEach(function (segment) { + path += segmentToString(segment, path); + }); + path += segmentToString(opts.prop, path); + return path; +}; + +/** + * @ignore + */ +var makeError = function makeError(actual, expected, opts) { + return { + expected: expected, + actual: '' + actual, + path: makePath(opts) + }; +}; + +/** + * @ignore + */ +var addError = function addError(actual, expected, opts, errors) { + errors.push(makeError(actual, expected, opts)); +}; + +/** + * @ignore + */ +var maxLengthCommon = function maxLengthCommon(keyword, value, schema, opts) { + var max = schema[keyword]; + if (value.length > max) { + return makeError(value.length, 'length no more than ' + max, opts); + } +}; + +/** + * @ignore + */ +var minLengthCommon = function minLengthCommon(keyword, value, schema, opts) { + var min = schema[keyword]; + if (value.length < min) { + return makeError(value.length, 'length no less than ' + min, opts); + } +}; + +/** + * A map of all object member validation functions for each keyword defined in the JSON Schema. + * @name Schema.validationKeywords + * @type {Object} + */ +var validationKeywords = { + /** + * Validates the provided value against all schemas defined in the Schemas `allOf` keyword. + * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value. + * + * The value of this keyword MUST be an array. This array MUST have at least one element. + * Each element of this array MUST be a valid JSON Schema. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor82 + * + * @name Schema.validationKeywords.allOf + * @method + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `allOf` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + allOf: function allOf(value, schema, opts) { + var allErrors = []; + schema.allOf.forEach(function (_schema) { + allErrors = allErrors.concat(_validate(value, _schema, opts) || []); + }); + return allErrors.length ? undefined : allErrors; }, /** - * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword. - * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value. + * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword. + * The instance is valid against this keyword if and only if it is valid against + * at least one of the schemas in this keyword's value. * - * see http://json-schema.org/latest/json-schema-validation.html#anchor88 - * @name Schema.validationKeywords.oneOf + * The value of this keyword MUST be an array. This array MUST have at least one element. + * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema. + * see http://json-schema.org/latest/json-schema-validation.html#anchor85 + * + * @name Schema.validationKeywords.anyOf * @method - * @param {*} value to be checked. - * @param {Object} schema Schema containing the `oneOf` keyword. + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `anyOf` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - oneOf: function oneOf(value, schema, opts) { + anyOf: function anyOf(value, schema, opts) { var validated = false; var allErrors = []; - schema.oneOf.forEach(function (_schema) { + schema.anyOf.forEach(function (_schema) { var errors = _validate(value, _schema, opts); if (errors) { allErrors = allErrors.concat(errors); - } else if (validated) { - allErrors = [makeError('valid against more than one', 'valid against only one', opts)]; - validated = false; - return false; } else { validated = true; } @@ -5817,1087 +5932,1011 @@ var validationKeywords = { /** - * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword. - * Validation succeeds if the string is a match of the regex value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor70 * - * see http://json-schema.org/latest/json-schema-validation.html#anchor33 - * @name Schema.validationKeywords.pattern + * @name Schema.validationKeywords.dependencies * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `pattern` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {*} value TODO + * @param {Object} schema TODO + * @param {Object} opts TODO */ - pattern: function pattern(value, schema, opts) { - var pattern = schema.pattern; - if (utils.isString(value) && !value.match(pattern)) { - return makeError(value, pattern, opts); - } + dependencies: function dependencies(value, schema, opts) { + // TODO }, /** - * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword. - * Validation succeeds if the object's property are valid with each of the schema's in the provided map. - * Validation also depends on the additionalProperties and or patternProperties. - * - * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info. + * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword + * Validation succeeds if the value is deeply equal to one of the values in the array. + * see http://json-schema.org/latest/json-schema-validation.html#anchor76 * - * @name Schema.validationKeywords.properties + * @name Schema.validationKeywords.enum * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `properties` keyword. + * @param {*} value Value to validate + * @param {Object} schema Schema containing the `enum` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - properties: function properties(value, schema, opts) { - opts || (opts = {}); - // Can be a boolean or an object - // Technically the default is an "empty schema", but here "true" is - // functionally the same - var additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties; - // "s": The property set of the instance to validate. - var toValidate = {}; - // "p": The property set from "properties". - // Default is an object - var properties = schema.properties || {}; - // "pp": The property set from "patternProperties". - // Default is an object - var patternProperties = schema.patternProperties || {}; - var errors = []; - - // Collect set "s" - utils.forOwn(value, function (_value, prop) { - toValidate[prop] = undefined; - }); - // Remove from "s" all elements of "p", if any. - utils.forOwn(properties || {}, function (_schema, prop) { - // if (value[prop] === undefined && _schema['default'] !== undefined) { - // value[prop] = utils.copy(_schema['default']) - // } - opts.prop = prop; - errors = errors.concat(_validate(value[prop], _schema, opts) || []); - delete toValidate[prop]; - }); - // For each regex in "pp", remove all elements of "s" which this regex - // matches. - utils.forOwn(patternProperties, function (_schema, pattern) { - utils.forOwn(toValidate, function (undef, prop) { - if (prop.match(pattern)) { - opts.prop = prop; - errors = errors.concat(_validate(value[prop], _schema, opts) || []); - delete toValidate[prop]; - } - }); - }); - var keys = Object.keys(toValidate); - // If "s" is not empty, validation fails - if (additionalProperties === false) { - if (keys.length) { - addError('extra fields: ' + keys.join(', '), 'no extra fields', opts, errors); - } - } else if (utils.isObject(additionalProperties)) { - // Otherwise, validate according to provided schema - keys.forEach(function (prop) { - opts.prop = prop; - errors = errors.concat(_validate(value[prop], additionalProperties, opts) || []); - }); + enum: function _enum(value, schema, opts) { + var possibleValues = schema['enum']; + if (utils.findIndex(possibleValues, function (item) { + return utils.deepEqual(item, value); + }) === -1) { + return makeError(value, 'one of (' + possibleValues.join(', ') + ')', opts); } - return errors.length ? errors : undefined; }, /** - * Validates the provided object's has all properties listed in the Schema's `properties` keyword array. - * Validation succeeds if the object contains all properties provided in the array value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor61 + * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword + * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules. * - * @name Schema.validationKeywords.required + * @name Schema.validationKeywords.items * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `required` keyword. + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the items keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - required: function required(value, schema, opts) { + items: function items(value, schema, opts) { opts || (opts = {}); - var required = schema.required; + // TODO: additionalItems + var items = schema.items; var errors = []; - if (!opts.existingOnly) { - required.forEach(function (prop) { - if (utils.get(value, prop) === undefined) { - var prevProp = opts.prop; - opts.prop = prop; - addError(undefined, 'a value', opts, errors); - opts.prop = prevProp; - } - }); + var checkingTuple = utils.isArray(items); + var length = value.length; + for (var prop = 0; prop < length; prop++) { + if (checkingTuple) { + // Validating a tuple, instead of just checking each item against the + // same schema + items = schema.items[prop]; + } + opts.prop = prop; + errors = errors.concat(_validate(value[prop], items, opts) || []); } return errors.length ? errors : undefined; }, /** - * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor79 + * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword + * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor17 * - * @name Schema.validationKeywords.type + * @name Schema.validationKeywords.maximum * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `type` keyword. + * @param {*} value Number to validate against the keyword. + * @param {Object} schema Schema containing the `maximum` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - type: function type(value, schema, opts) { - var type = schema.type; - var validType = void 0; - // Can be one of several types - if (utils.isString(type)) { - type = [type]; - } - // Try to match the value against an expected type - type.forEach(function (_type) { - // TODO: throw an error if type is not defined - if (types[_type](value, schema, opts)) { - // Matched a type - validType = _type; - return false; - } - }); - // Value did not match any expected type - if (!validType) { - return makeError(value !== undefined && value !== null ? typeof value === 'undefined' ? 'undefined' : _typeof(value) : '' + value, 'one of (' + type.join(', ') + ')', opts); - } - // Run keyword validators for matched type - // http://json-schema.org/latest/json-schema-validation.html#anchor12 - var validator = typeGroupValidators[validType]; - if (validator) { - return validator(value, schema, opts); + maximum: function maximum(value, schema, opts) { + // Must be a number + var maximum = schema.maximum; + // Must be a boolean + // Depends on maximum + // default: false + var exclusiveMaximum = schema.exclusiveMaximum; + if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof maximum === 'undefined' ? 'undefined' : _typeof(maximum)) && !(exclusiveMaximum ? maximum > value : maximum >= value)) { + return exclusiveMaximum ? makeError(value, 'no more than nor equal to ' + maximum, opts) : makeError(value, 'no more than ' + maximum, opts); } }, /** - * Validates the provided array values are unique. - * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true - * see http://json-schema.org/latest/json-schema-validation.html#anchor49 + * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword. + * Validation succeeds if the length of the array is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor42 * - * @name Schema.validationKeywords.uniqueItems + * @name Schema.validationKeywords.maxItems * @method * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `uniqueItems` keyword. + * @param {Object} schema Schema containing the `maxItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - uniqueItems: function uniqueItems(value, schema, opts) { - if (value && value.length && schema.uniqueItems) { - var length = value.length; - var item = void 0, - i = void 0, - j = void 0; - // Check n - 1 items - for (i = length - 1; i > 0; i--) { - item = value[i]; - // Only compare against unchecked items - for (j = i - 1; j >= 0; j--) { - // Found a duplicate - if (utils.deepEqual(item, value[j])) { - return makeError(item, 'no duplicates', opts); - } - } - } - } - } -}; - -/** - * @ignore - */ -var validateKeyword = function validateKeyword(op, value, schema, opts) { - return schema[op] !== undefined && validationKeywords[op](value, schema, opts); -}; - -/** - * @ignore - */ -var runOps = function runOps(ops, value, schema, opts) { - var errors = []; - ops.forEach(function (op) { - errors = errors.concat(validateKeyword(op, value, schema, opts) || []); - }); - return errors.length ? errors : undefined; -}; - -var ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']; -var ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']; -var NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']; -var OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']; -var STRING_OPS = ['maxLength', 'minLength', 'pattern']; - -/** - * http://json-schema.org/latest/json-schema-validation.html#anchor75 - * @ignore - */ -var validateAny = function validateAny(value, schema, opts) { - return runOps(ANY_OPS, value, schema, opts); -}; - -/** - * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification. - * - * @name Schema.validate - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ -var _validate = function _validate(value, schema, opts) { - var errors = []; - opts || (opts = {}); - opts.ctx || (opts.ctx = { value: value, schema: schema }); - var shouldPop = void 0; - var prevProp = opts.prop; - if (schema === undefined) { - return; - } - if (!utils.isObject(schema)) { - throw utils.err(DOMAIN$6 + '#validate')(500, 'Invalid schema at path: "' + opts.path + '"'); - } - if (opts.path === undefined) { - opts.path = []; - } - // Track our location as we recurse - if (opts.prop !== undefined) { - shouldPop = true; - opts.path.push(opts.prop); - opts.prop = undefined; - } - // Validate against parent schema - if (schema['extends']) { - // opts.path = path - // opts.prop = prop - if (utils.isFunction(schema['extends'].validate)) { - errors = errors.concat(schema['extends'].validate(value, opts) || []); - } else { - errors = errors.concat(_validate(value, schema['extends'], opts) || []); - } - } - if (value === undefined) { - // Check if property is required - if (schema.required === true && !opts.existingOnly) { - addError(value, 'a value', opts, errors); - } - if (shouldPop) { - opts.path.pop(); - opts.prop = prevProp; + maxItems: function maxItems(value, schema, opts) { + if (utils.isArray(value)) { + return maxLengthCommon('maxItems', value, schema, opts); } - return errors.length ? errors : undefined; - } - - errors = errors.concat(validateAny(value, schema, opts) || []); - if (shouldPop) { - opts.path.pop(); - opts.prop = prevProp; - } - return errors.length ? errors : undefined; -}; - -// These strings are cached for optimal performance of the change detection -// boolean - Whether a Record is changing in the current execution frame -var changingPath = 'changing'; -// string[] - Properties that have changed in the current execution frame -var changedPath = 'changed'; -// Object[] - History of change records -var changeHistoryPath = 'history'; -// boolean - Whether a Record is currently being instantiated -var creatingPath = 'creating'; -// number - The setTimeout change event id of a Record, if any -var eventIdPath = 'eventId'; -// boolean - Whether to skip validation for a Record's currently changing property -var noValidatePath = 'noValidate'; -// boolean - Whether to skip change notification for a Record's currently -// changing property -var silentPath = 'silent'; -var validationFailureMsg = 'validation failed'; - -/** - * Assemble a property descriptor which will be added to the prototype of - * {@link Mapper#recordClass}. This method is called when - * {@link Mapper#applySchema} is set to `true`. - * - * @ignore - */ -var makeDescriptor = function makeDescriptor(prop, schema, opts) { - var descriptor = { - // Better to allow configurability, but at the user's own risk - configurable: true, - // These properties are enumerable by default, but regardless of their - // enumerability, they won't be "own" properties of individual records - enumerable: schema.enumerable === undefined ? true : !!schema.enumerable - }; - // Cache a few strings for optimal performance - var keyPath = 'props.' + prop; - var previousPath = 'previous.' + prop; - var getter = opts.getter; - var setter = opts.setter; - var unsetter = opts.unsetter; - var track = utils.isBoolean(opts.track) ? opts.track : schema.track; + }, - descriptor.get = function () { - return this._get(keyPath); - }; - if (utils.isFunction(schema.get)) { - (function () { - var originalGet = descriptor.get; - descriptor.get = function () { - return schema.get.call(this, originalGet); - }; - })(); - } - - descriptor.set = function (value) { - var _this = this; + /** + * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword. + * Validation succeeds if the length of the string is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor26 + * + * @name Schema.validationKeywords.maxLength + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `maxLength` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + maxLength: function maxLength(value, schema, opts) { + return maxLengthCommon('maxLength', value, schema, opts); + }, - // These are accessed a lot - var _get = this[getter]; - var _set = this[setter]; - var _unset = this[unsetter]; - // Optionally check that the new value passes validation - if (!_get(noValidatePath)) { - var errors = schema.validate(value, { path: [prop] }); - if (errors) { - // Immediately throw an error, preventing the record from getting into - // an invalid state - var error = new Error(validationFailureMsg); - error.errors = errors; - throw error; - } + /** + * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword. + * Validation succeeds if the object's property count is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor54 + * + * @name Schema.validationKeywords.maxProperties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `maxProperties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + maxProperties: function maxProperties(value, schema, opts) { + // validate only objects + if (!utils.isObject(value)) return; + var maxProperties = schema.maxProperties; + var length = Object.keys(value).length; + if (length > maxProperties) { + return makeError(length, 'no more than ' + maxProperties + ' properties', opts); } - // TODO: Make it so tracking can be turned on for all properties instead of - // only per-property - if (track && !_get(creatingPath)) { - (function () { - var previous = _get(previousPath); - var current = _get(keyPath); - var changing = _get(changingPath); - var changed = _get(changedPath); - - if (!changing) { - // Track properties that are changing in the current event loop - changed = []; - } + }, - // Add changing properties to this array once at most - var index = changed.indexOf(prop); - if (current !== value && index === -1) { - changed.push(prop); - } - if (previous === value) { - if (index >= 0) { - changed.splice(index, 1); - } - } - // No changes in current event loop - if (!changed.length) { - changing = false; - _unset(changingPath); - _unset(changedPath); - // Cancel pending change event - if (_get(eventIdPath)) { - clearTimeout(_get(eventIdPath)); - _unset(eventIdPath); - } - } - // Changes detected in current event loop - if (!changing && changed.length) { - _set(changedPath, changed); - _set(changingPath, true); - // Saving the timeout id allows us to batch all changes in the same - // event loop into a single "change" - // TODO: Optimize - _set(eventIdPath, setTimeout(function () { - // Previous event loop where changes were gathered has ended, so - // notify any listeners of those changes and prepare for any new - // changes - _unset(changedPath); - _unset(eventIdPath); - _unset(changingPath); - // TODO: Optimize - if (!_get(silentPath)) { - var i = void 0; - for (i = 0; i < changed.length; i++) { - _this.emit('change:' + changed[i], _this, utils.get(_this, changed[i])); - } - var changes = _this.changes(); - var changeRecord = utils.plainCopy(changes); - changeRecord.timestamp = new Date().getTime(); - var changeHistory = _get(changeHistoryPath) || []; - _set(changeHistoryPath, changeHistory); - changeHistory.push(changeRecord); - _this.emit('change', _this, changes); - } - _unset(silentPath); - }, 0)); - } - })(); - } - _set(keyPath, value); - return value; - }; - if (utils.isFunction(schema.set)) { - (function () { - var originalSet = descriptor.set; - descriptor.set = function (value) { - return schema.set.call(this, value, originalSet); - }; - })(); - } + /** + * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword + * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor21 + * + * @name Schema.validationKeywords.minimum + * @method + * @param {*} value Number to validate against the keyword. + * @param {Object} schema Schema containing the `minimum` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + minimum: function minimum(value, schema, opts) { + // Must be a number + var minimum = schema.minimum; + // Must be a boolean + // Depends on minimum + // default: false + var exclusiveMinimum = schema.exclusiveMinimum; + if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof minimum === 'undefined' ? 'undefined' : _typeof(minimum)) && !(exclusiveMinimum ? value > minimum : value >= minimum)) { + return exclusiveMinimum ? makeError(value, 'no less than nor equal to ' + minimum, opts) : makeError(value, 'no less than ' + minimum, opts); + } + }, - return descriptor; -}; -/** - * A map of validation functions grouped by type. - * - * @name Schema.typeGroupValidators - * @type {Object} - */ -var typeGroupValidators = { /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an array. - * The validation keywords for the type `array` are: - *``` - * ['items', 'maxItems', 'minItems', 'uniqueItems'] - *``` - * see http://json-schema.org/latest/json-schema-validation.html#anchor25 + * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword. + * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor45 * - * @name Schema.typeGroupValidators.array + * @name Schema.validationKeywords.minItems * @method * @param {*} value Array to be validated. - * @param {Object} schema Schema containing at least one array keyword. + * @param {Object} schema Schema containing the `minItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - array: function array(value, schema, opts) { - return runOps(ARRAY_OPS, value, schema, opts); + minItems: function minItems(value, schema, opts) { + if (utils.isArray(value)) { + return minLengthCommon('minItems', value, schema, opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer. - * The validation keywords for the type `integer` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * @name Schema.typeGroupValidators.integer + * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword. + * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor29 + * + * @name Schema.validationKeywords.minLength * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `integer` keyword. + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `minLength` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - integer: function integer(value, schema, opts) { - // Additional validations for numerics are the same - return typeGroupValidators.numeric(value, schema, opts); + minLength: function minLength(value, schema, opts) { + return minLengthCommon('minLength', value, schema, opts); }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an number. - * The validation keywords for the type `number` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * @name Schema.typeGroupValidators.number + * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword. + * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor57 + * + * @name Schema.validationKeywords.minProperties * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `number` keyword. + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `minProperties` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - number: function number(value, schema, opts) { - // Additional validations for numerics are the same - return typeGroupValidators.numeric(value, schema, opts); + minProperties: function minProperties(value, schema, opts) { + // validate only objects + if (!utils.isObject(value)) return; + var minProperties = schema.minProperties; + var length = Object.keys(value).length; + if (length < minProperties) { + return makeError(length, 'no more than ' + minProperties + ' properties', opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer. - * The validation keywords for the type `numeric` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor13. + * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword. + * Validation succeeds if the number can be divided equally into the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor14 * - * @name Schema.typeGroupValidators.numeric + * @name Schema.validationKeywords.multipleOf * @method * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `numeric` keyword. + * @param {Object} schema Schema containing the `multipleOf` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - numeric: function numeric(value, schema, opts) { - return runOps(NUMERIC_OPS, value, schema, opts); + multipleOf: function multipleOf(value, schema, opts) { + var multipleOf = schema.multipleOf; + if (utils.isNumber(value)) { + if (value / multipleOf % 1 !== 0) { + return makeError(value, 'multipleOf ' + multipleOf, opts); + } + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an object. - * The validation keywords for the type `object` are: - *``` - * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor53. + * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword. + * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value. * - * @name Schema.typeGroupValidators.object + * see http://json-schema.org/latest/json-schema-validation.html#anchor91 + * @name Schema.validationKeywords.not * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing at least one `object` keyword. + * @param {*} value to be checked. + * @param {Object} schema Schema containing the not keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - object: function object(value, schema, opts) { - return runOps(OBJECT_OPS, value, schema, opts); + not: function not(value, schema, opts) { + if (!_validate(value, schema.not, opts)) { + // TODO: better messaging + return makeError('succeeded', 'should have failed', opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an string. - * The validation keywords for the type `string` are: - *``` - * ['maxLength', 'minLength', 'pattern'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor25. + * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword. + * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value. * - * @name Schema.typeGroupValidators.string + * see http://json-schema.org/latest/json-schema-validation.html#anchor88 + * @name Schema.validationKeywords.oneOf + * @method + * @param {*} value to be checked. + * @param {Object} schema Schema containing the `oneOf` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + oneOf: function oneOf(value, schema, opts) { + var validated = false; + var allErrors = []; + schema.oneOf.forEach(function (_schema) { + var errors = _validate(value, _schema, opts); + if (errors) { + allErrors = allErrors.concat(errors); + } else if (validated) { + allErrors = [makeError('valid against more than one', 'valid against only one', opts)]; + validated = false; + return false; + } else { + validated = true; + } + }); + return validated ? undefined : allErrors; + }, + + + /** + * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword. + * Validation succeeds if the string is a match of the regex value of this keyword. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor33 + * @name Schema.validationKeywords.pattern * @method * @param {*} value String to be validated. - * @param {Object} schema Schema containing at least one `string` keyword. + * @param {Object} schema Schema containing the `pattern` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - string: function string(value, schema, opts) { - return runOps(STRING_OPS, value, schema, opts); - } -}; + pattern: function pattern(value, schema, opts) { + var pattern = schema.pattern; + if (utils.isString(value) && !value.match(pattern)) { + return makeError(value, pattern, opts); + } + }, -/** - * js-data's Schema class. - * - * @example Schema#constructor - * // Normally you would do: import {Schema} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Schema} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const PostSchema = new Schema({ - * type: 'object', - * properties: { - * title: { type: 'string' } - * } - * }) - * PostSchema.validate({ title: 1234 }) - * - * @class Schema - * @extends Component - * @param {Object} definition Schema definition according to json-schema.org - */ -function Schema(definition) { - var _this2 = this; - definition || (definition = {}); - // TODO: schema validation - utils.fillIn(this, definition); + /** + * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword. + * Validation succeeds if the object's property are valid with each of the schema's in the provided map. + * Validation also depends on the additionalProperties and or patternProperties. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info. + * + * @name Schema.validationKeywords.properties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `properties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + properties: function properties(value, schema, opts) { + opts || (opts = {}); + // Can be a boolean or an object + // Technically the default is an "empty schema", but here "true" is + // functionally the same + var additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties; + // "s": The property set of the instance to validate. + var toValidate = {}; + // "p": The property set from "properties". + // Default is an object + var properties = schema.properties || {}; + // "pp": The property set from "patternProperties". + // Default is an object + var patternProperties = schema.patternProperties || {}; + var errors = []; - if (this.type === 'object' && this.properties) { - utils.forOwn(this.properties, function (_definition, prop) { - if (!(_definition instanceof Schema)) { - _this2.properties[prop] = new Schema(_definition); - } + // Collect set "s" + utils.forOwn(value, function (_value, prop) { + toValidate[prop] = undefined; + }); + // Remove from "s" all elements of "p", if any. + utils.forOwn(properties || {}, function (_schema, prop) { + // if (value[prop] === undefined && _schema['default'] !== undefined) { + // value[prop] = utils.copy(_schema['default']) + // } + opts.prop = prop; + errors = errors.concat(_validate(value[prop], _schema, opts) || []); + delete toValidate[prop]; }); - } - if (this.type === 'array' && this.items && !(this.items instanceof Schema)) { - this.items = new Schema(this.items); - } - ['allOf', 'anyOf', 'oneOf'].forEach(function (validationKeyword) { - if (_this2[validationKeyword]) { - _this2[validationKeyword].forEach(function (_definition, i) { - if (!(_definition instanceof Schema)) { - _this2[validationKeyword][i] = new Schema(_definition); + // For each regex in "pp", remove all elements of "s" which this regex + // matches. + utils.forOwn(patternProperties, function (_schema, pattern) { + utils.forOwn(toValidate, function (undef, prop) { + if (prop.match(pattern)) { + opts.prop = prop; + errors = errors.concat(_validate(value[prop], _schema, opts) || []); + delete toValidate[prop]; } }); + }); + var keys = Object.keys(toValidate); + // If "s" is not empty, validation fails + if (additionalProperties === false) { + if (keys.length) { + addError('extra fields: ' + keys.join(', '), 'no extra fields', opts, errors); + } + } else if (utils.isObject(additionalProperties)) { + // Otherwise, validate according to provided schema + keys.forEach(function (prop) { + opts.prop = prop; + errors = errors.concat(_validate(value[prop], additionalProperties, opts) || []); + }); } - }); -} + return errors.length ? errors : undefined; + }, -var Schema$1 = Component$1.extend({ - constructor: Schema, /** - * This adds ES5 getters/setters to the target based on the "properties" in - * this Schema, which makes possible change tracking and validation on - * property assignment. + * Validates the provided object's has all properties listed in the Schema's `properties` keyword array. + * Validation succeeds if the object contains all properties provided in the array value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor61 * - * @name Schema#validate + * @name Schema.validationKeywords.required * @method - * @param {Object} target The prototype to which to apply this schema. + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `required` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - apply: function apply(target, opts) { + required: function required(value, schema, opts) { opts || (opts = {}); - opts.getter || (opts.getter = '_get'); - opts.setter || (opts.setter = '_set'); - opts.unsetter || (opts.unsetter = '_unset'); - opts.track || (opts.track = this.track); - var properties = this.properties || {}; - utils.forOwn(properties, function (schema, prop) { - Object.defineProperty(target, prop, makeDescriptor(prop, schema, opts)); - }); + var required = schema.required; + var errors = []; + if (!opts.existingOnly) { + required.forEach(function (prop) { + if (utils.get(value, prop) === undefined) { + var prevProp = opts.prop; + opts.prop = prop; + addError(undefined, 'a value', opts, errors); + opts.prop = prevProp; + } + }); + } + return errors.length ? errors : undefined; }, /** - * Apply default values to the target object for missing values. + * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor79 * - * @name Schema#applyDefaults + * @name Schema.validationKeywords.type * @method - * @param {Object} target The target to which to apply values for missing values. + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `type` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - applyDefaults: function applyDefaults(target) { - if (!target) { - return; + type: function type(value, schema, opts) { + var type = schema.type; + var validType = void 0; + // Can be one of several types + if (utils.isString(type)) { + type = [type]; } - var properties = this.properties || {}; - var hasSet = utils.isFunction(target.set) || utils.isFunction(target._set); - utils.forOwn(properties, function (schema, prop) { - if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) { - if (hasSet) { - target.set(prop, utils.plainCopy(schema['default']), { silent: true }); - } else { - utils.set(target, prop, utils.plainCopy(schema['default'])); - } - } - if (schema.type === 'object' && schema.properties) { - if (hasSet) { - var orig = target._get('noValidate'); - target._set('noValidate', true); - utils.set(target, prop, utils.get(target, prop) || {}, { silent: true }); - target._set('noValidate', orig); - } else { - utils.set(target, prop, utils.get(target, prop) || {}); - } - schema.applyDefaults(utils.get(target, prop)); + // Try to match the value against an expected type + type.forEach(function (_type) { + // TODO: throw an error if type is not defined + if (types[_type](value, schema, opts)) { + // Matched a type + validType = _type; + return false; } }); + // Value did not match any expected type + if (!validType) { + return makeError(value !== undefined && value !== null ? typeof value === 'undefined' ? 'undefined' : _typeof(value) : '' + value, 'one of (' + type.join(', ') + ')', opts); + } + // Run keyword validators for matched type + // http://json-schema.org/latest/json-schema-validation.html#anchor12 + var validator = typeGroupValidators[validType]; + if (validator) { + return validator(value, schema, opts); + } }, /** - * Validate the provided value against this schema. + * Validates the provided array values are unique. + * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true + * see http://json-schema.org/latest/json-schema-validation.html#anchor49 * - * @name Schema#validate + * @name Schema.validationKeywords.uniqueItems * @method - * @param {*} value Value to validate. + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the `uniqueItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - validate: function validate(value, opts) { - return _validate(value, this, opts); + uniqueItems: function uniqueItems(value, schema, opts) { + if (value && value.length && schema.uniqueItems) { + var length = value.length; + var item = void 0, + i = void 0, + j = void 0; + // Check n - 1 items + for (i = length - 1; i > 0; i--) { + item = value[i]; + // Only compare against unchecked items + for (j = i - 1; j >= 0; j--) { + // Found a duplicate + if (utils.deepEqual(item, value[j])) { + return makeError(item, 'no duplicates', opts); + } + } + } + } } -}, { - ANY_OPS: ANY_OPS, - ARRAY_OPS: ARRAY_OPS, - NUMERIC_OPS: NUMERIC_OPS, - OBJECT_OPS: OBJECT_OPS, - STRING_OPS: STRING_OPS, - typeGroupValidators: typeGroupValidators, - types: types, - validate: _validate, - validationKeywords: validationKeywords -}); - -// TODO: remove this when the rest of the project is cleaned -var belongsToType = 'belongsTo'; -var hasManyType = 'hasMany'; -var hasOneType = 'hasOne'; +}; -var DOMAIN$7 = 'Relation'; +/** + * @ignore + */ +var validateKeyword = function validateKeyword(op, value, schema, opts) { + return schema[op] !== undefined && validationKeywords[op](value, schema, opts); +}; -function Relation(relatedMapper) { - var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; +/** + * @ignore + */ +var runOps = function runOps(ops, value, schema, opts) { + var errors = []; + ops.forEach(function (op) { + errors = errors.concat(validateKeyword(op, value, schema, opts) || []); + }); + return errors.length ? errors : undefined; +}; - utils.classCallCheck(this, Relation); +var ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']; +var ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']; +var NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']; +var OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']; +var STRING_OPS = ['maxLength', 'minLength', 'pattern']; - options.type = this.constructor.TYPE_NAME; - this.validateOptions(relatedMapper, options); +/** + * http://json-schema.org/latest/json-schema-validation.html#anchor75 + * @ignore + */ +var validateAny = function validateAny(value, schema, opts) { + return runOps(ANY_OPS, value, schema, opts); +}; - if ((typeof relatedMapper === 'undefined' ? 'undefined' : _typeof(relatedMapper)) === 'object') { - Object.defineProperty(this, 'relatedMapper', { value: relatedMapper }); +/** + * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification. + * + * @name Schema.validate + * @method + * @param {*} value Value to be validated. + * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ +var _validate = function _validate(value, schema, opts) { + var errors = []; + opts || (opts = {}); + opts.ctx || (opts.ctx = { value: value, schema: schema }); + var shouldPop = void 0; + var prevProp = opts.prop; + if (schema === undefined) { + return; + } + if (!utils.isObject(schema)) { + throw utils.err(DOMAIN$7 + '#validate')(500, 'Invalid schema at path: "' + opts.path + '"'); + } + if (opts.path === undefined) { + opts.path = []; + } + // Track our location as we recurse + if (opts.prop !== undefined) { + shouldPop = true; + opts.path.push(opts.prop); + opts.prop = undefined; + } + // Validate against parent schema + if (schema['extends']) { + // opts.path = path + // opts.prop = prop + if (utils.isFunction(schema['extends'].validate)) { + errors = errors.concat(schema['extends'].validate(value, opts) || []); + } else { + errors = errors.concat(_validate(value, schema['extends'], opts) || []); + } + } + if (value === undefined) { + // Check if property is required + if (schema.required === true && !opts.existingOnly) { + addError(value, 'a value', opts, errors); + } + if (shouldPop) { + opts.path.pop(); + opts.prop = prevProp; + } + return errors.length ? errors : undefined; } - Object.defineProperty(this, 'inverse', { writable: true }); - utils.fillIn(this, options); -} + errors = errors.concat(validateAny(value, schema, opts) || []); + if (shouldPop) { + opts.path.pop(); + opts.prop = prevProp; + } + return errors.length ? errors : undefined; +}; -Relation.extend = utils.extend; +// These strings are cached for optimal performance of the change detection +// boolean - Whether a Record is changing in the current execution frame +var changingPath = 'changing'; +// string[] - Properties that have changed in the current execution frame +var changedPath = 'changed'; +// Object[] - History of change records +var changeHistoryPath = 'history'; +// boolean - Whether a Record is currently being instantiated +var creatingPath = 'creating'; +// number - The setTimeout change event id of a Record, if any +var eventIdPath = 'eventId'; +// boolean - Whether to skip validation for a Record's currently changing property +var noValidatePath = 'noValidate'; +// boolean - Whether to skip change notification for a Record's currently +// changing property +var silentPath = 'silent'; +var validationFailureMsg = 'validation failed'; -utils.addHiddenPropsToTarget(Relation.prototype, { - get canAutoAddLinks() { - return this.add === undefined || !!this.add; - }, +/** + * Assemble a property descriptor which will be added to the prototype of + * {@link Mapper#recordClass}. This method is called when + * {@link Mapper#applySchema} is set to `true`. + * + * @ignore + */ +var makeDescriptor = function makeDescriptor(prop, schema, opts) { + var descriptor = { + // Better to allow configurability, but at the user's own risk + configurable: true, + // These properties are enumerable by default, but regardless of their + // enumerability, they won't be "own" properties of individual records + enumerable: schema.enumerable === undefined ? true : !!schema.enumerable + }; + // Cache a few strings for optimal performance + var keyPath = 'props.' + prop; + var previousPath = 'previous.' + prop; + var getter = opts.getter; + var setter = opts.setter; + var unsetter = opts.unsetter; + var track = utils.isBoolean(opts.track) ? opts.track : schema.track; - get relatedCollection() { - return this.mapper.datastore.getCollection(this.relation); - }, + descriptor.get = function () { + return this._get(keyPath); + }; - validateOptions: function validateOptions(related, opts) { - var DOMAIN_ERR = 'new ' + DOMAIN$7; + if (utils.isFunction(schema.get)) { + (function () { + var originalGet = descriptor.get; + descriptor.get = function () { + return schema.get.call(this, originalGet); + }; + })(); + } - var localField = opts.localField; - if (!localField) { - throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField); - } + descriptor.set = function (value) { + var _this = this; - var foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey; - if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) { - throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey); - } + // These are accessed a lot + var _get = this[getter]; + var _set = this[setter]; + var _unset = this[unsetter]; - if (utils.isString(related)) { - opts.relation = related; - if (!utils.isFunction(opts.getRelation)) { - throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation); + // Optionally check that the new value passes validation + if (!_get(noValidatePath)) { + var errors = schema.validate(value, { path: [prop] }); + if (errors) { + // Immediately throw an error, preventing the record from getting into + // an invalid state + var error = new Error(validationFailureMsg); + error.errors = errors; + throw error; } - } else if (related) { - opts.relation = related.name; - } else { - throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related); - } - }, - assignTo: function assignTo(mapper) { - this.name = mapper.name; - Object.defineProperty(this, 'mapper', { value: mapper }); - - mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] }); - mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] }); - mapper.relationList.push(this); - mapper.relationFields.push(this.localField); - }, - canFindLinkFor: function canFindLinkFor() { - return !!(this.foreignKey || this.localKey); - }, - getRelation: function getRelation() { - return this.relatedMapper; - }, - getForeignKey: function getForeignKey(record) { - return utils.get(record, this.mapper.idAttribute); - }, - setForeignKey: function setForeignKey(record, relatedRecord) { - if (!record || !relatedRecord) { - return; } + // TODO: Make it so tracking can be turned on for all properties instead of + // only per-property + if (track && !_get(creatingPath)) { + (function () { + var previous = _get(previousPath); + var current = _get(keyPath); + var changing = _get(changingPath); + var changed = _get(changedPath); - this._setForeignKey(record, relatedRecord); - }, - _setForeignKey: function _setForeignKey(record, relatedRecords) { - var _this = this; - - var idAttribute = this.mapper.idAttribute; - - if (!utils.isArray(relatedRecords)) { - relatedRecords = [relatedRecords]; - } + if (!changing) { + // Track properties that are changing in the current event loop + changed = []; + } - relatedRecords.forEach(function (relatedRecord) { - utils.set(relatedRecord, _this.foreignKey, utils.get(record, idAttribute)); - }); - }, - getLocalField: function getLocalField(record) { - return utils.get(record, this.localField); - }, - setLocalField: function setLocalField(record, relatedData) { - return utils.set(record, this.localField, relatedData); - }, - getInverse: function getInverse(mapper) { - if (!this.inverse) { - this.findInverseRelation(mapper); + // Add changing properties to this array once at most + var index = changed.indexOf(prop); + if (current !== value && index === -1) { + changed.push(prop); + } + if (previous === value) { + if (index >= 0) { + changed.splice(index, 1); + } + } + // No changes in current event loop + if (!changed.length) { + changing = false; + _unset(changingPath); + _unset(changedPath); + // Cancel pending change event + if (_get(eventIdPath)) { + clearTimeout(_get(eventIdPath)); + _unset(eventIdPath); + } + } + // Changes detected in current event loop + if (!changing && changed.length) { + _set(changedPath, changed); + _set(changingPath, true); + // Saving the timeout id allows us to batch all changes in the same + // event loop into a single "change" + // TODO: Optimize + _set(eventIdPath, setTimeout(function () { + // Previous event loop where changes were gathered has ended, so + // notify any listeners of those changes and prepare for any new + // changes + _unset(changedPath); + _unset(eventIdPath); + _unset(changingPath); + // TODO: Optimize + if (!_get(silentPath)) { + var i = void 0; + for (i = 0; i < changed.length; i++) { + _this.emit('change:' + changed[i], _this, utils.get(_this, changed[i])); + } + var changes = _this.changes(); + var changeRecord = utils.plainCopy(changes); + changeRecord.timestamp = new Date().getTime(); + var changeHistory = _get(changeHistoryPath) || []; + _set(changeHistoryPath, changeHistory); + changeHistory.push(changeRecord); + _this.emit('change', _this, changes); + } + _unset(silentPath); + }, 0)); + } + })(); } + _set(keyPath, value); + return value; + }; - return this.inverse; - }, - findInverseRelation: function findInverseRelation(mapper) { - var _this2 = this; - - this.getRelation().relationList.forEach(function (def) { - if (def.getRelation() === mapper && _this2.isInversedTo(def)) { - _this2.inverse = def; - return true; - } - }); - }, - isInversedTo: function isInversedTo(def) { - return !def.foreignKey || def.foreignKey === this.foreignKey; - }, - addLinkedRecords: function addLinkedRecords(records) { - var _this3 = this; - - var datastore = this.mapper.datastore; - - records.forEach(function (record) { - var relatedData = _this3.getLocalField(record); - - if (utils.isFunction(_this3.add)) { - relatedData = _this3.add(datastore, _this3, record); - } else if (relatedData) { - relatedData = _this3.linkRecord(record, relatedData); - } - - var isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length; + if (utils.isFunction(schema.set)) { + (function () { + var originalSet = descriptor.set; + descriptor.set = function (value) { + return schema.set.call(this, value, originalSet); + }; + })(); + } - if (isEmptyLinks && _this3.canFindLinkFor(record)) { - relatedData = _this3.findExistingLinksFor(record); - } + return descriptor; +}; - if (relatedData) { - _this3.setLocalField(record, relatedData); - } - }); +/** + * A map of validation functions grouped by type. + * + * @name Schema.typeGroupValidators + * @type {Object} + */ +var typeGroupValidators = { + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an array. + * The validation keywords for the type `array` are: + *``` + * ['items', 'maxItems', 'minItems', 'uniqueItems'] + *``` + * see http://json-schema.org/latest/json-schema-validation.html#anchor25 + * + * @name Schema.typeGroupValidators.array + * @method + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing at least one array keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + array: function array(value, schema, opts) { + return runOps(ARRAY_OPS, value, schema, opts); }, - removeLinkedRecords: function removeLinkedRecords(relatedMapper, records) { - var _this4 = this; - var localField = this.localField; - records.forEach(function (record) { - var relatedData = utils.get(record, localField); - _this4.unlinkInverseRecords(relatedData); - utils.set(record, localField, undefined); - }); - }, - unlinkInverseRecords: function unlinkInverseRecords(record) { - if (!record) { - return; - } - utils.set(record, this.getInverse(this.mapper).localField, undefined); + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer. + * The validation keywords for the type `integer` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * @name Schema.typeGroupValidators.integer + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `integer` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + integer: function integer(value, schema, opts) { + // Additional validations for numerics are the same + return typeGroupValidators.numeric(value, schema, opts); }, - linkRecord: function linkRecord(record, relatedRecord) { - var relatedId = utils.get(relatedRecord, this.mapper.idAttribute); - if (relatedId === undefined) { - var unsaved = this.relatedCollection.unsaved(); - if (unsaved.indexOf(relatedRecord) === -1) { - if (this.canAutoAddLinks) { - relatedRecord = this.relatedCollection.add(relatedRecord); - } - } - } else { - if (relatedRecord !== this.relatedCollection.get(relatedId)) { - this.setForeignKey(record, relatedRecord); - - if (this.canAutoAddLinks) { - relatedRecord = this.relatedCollection.add(relatedRecord); - } - } - } + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an number. + * The validation keywords for the type `number` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * @name Schema.typeGroupValidators.number + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `number` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + number: function number(value, schema, opts) { + // Additional validations for numerics are the same + return typeGroupValidators.numeric(value, schema, opts); + }, - return relatedRecord; + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer. + * The validation keywords for the type `numeric` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor13. + * + * @name Schema.typeGroupValidators.numeric + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `numeric` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + numeric: function numeric(value, schema, opts) { + return runOps(NUMERIC_OPS, value, schema, opts); }, + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an object. + * The validation keywords for the type `object` are: + *``` + * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor53. + * + * @name Schema.typeGroupValidators.object + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing at least one `object` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + object: function object(value, schema, opts) { + return runOps(OBJECT_OPS, value, schema, opts); + }, - // e.g. user hasMany post via "foreignKey", so find all posts of user - findExistingLinksByForeignKey: function findExistingLinksByForeignKey(id) { - return this.relatedCollection.filter(defineProperty({}, this.foreignKey, id)); + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an string. + * The validation keywords for the type `string` are: + *``` + * ['maxLength', 'minLength', 'pattern'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor25. + * + * @name Schema.typeGroupValidators.string + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing at least one `string` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + string: function string(value, schema, opts) { + return runOps(STRING_OPS, value, schema, opts); } -}); +}; -var BelongsToRelation = Relation.extend({ - getForeignKey: function getForeignKey(record) { - return utils.get(record, this.foreignKey); - }, - _setForeignKey: function _setForeignKey(record, relatedRecord) { - utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute)); - }, - findExistingLinksFor: function findExistingLinksFor(record) { - // console.log('\tBelongsTo#findExistingLinksFor', record) - if (!record) { - return; - } - var relatedId = utils.get(record, this.foreignKey); - if (relatedId !== undefined && relatedId !== null) { - return this.relatedCollection.get(relatedId); - } - } -}, { - TYPE_NAME: 'belongsTo' -}); +/** + * js-data's Schema class. + * + * @example Schema#constructor + * // Normally you would do: import {Schema} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Schema} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const PostSchema = new Schema({ + * type: 'object', + * properties: { + * title: { type: 'string' } + * } + * }) + * PostSchema.validate({ title: 1234 }) + * + * @class Schema + * @extends Component + * @param {Object} definition Schema definition according to json-schema.org + */ +function Schema(definition) { + var _this2 = this; -var HasManyRelation = Relation.extend({ - validateOptions: function validateOptions(related, opts) { - Relation.prototype.validateOptions.call(this, related, opts); + definition || (definition = {}); + // TODO: schema validation + utils.fillIn(this, definition); - var localKeys = opts.localKeys; - var foreignKeys = opts.foreignKeys; - var foreignKey = opts.foreignKey; + if (this.type === 'object' && this.properties) { + utils.forOwn(this.properties, function (_definition, prop) { + if (!(_definition instanceof Schema)) { + _this2.properties[prop] = new Schema(_definition); + } + }); + } + if (this.type === 'array' && this.items && !(this.items instanceof Schema)) { + this.items = new Schema(this.items); + } + ['allOf', 'anyOf', 'oneOf'].forEach(function (validationKeyword) { + if (_this2[validationKeyword]) { + _this2[validationKeyword].forEach(function (_definition, i) { + if (!(_definition instanceof Schema)) { + _this2[validationKeyword][i] = new Schema(_definition); + } + }); + } + }); +} +var Schema$1 = Component$1.extend({ + constructor: Schema, - if (!foreignKey && !localKeys && !foreignKeys) { - throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey); - } - }, - canFindLinkFor: function canFindLinkFor(record) { - var hasForeignKeys = this.foreignKey || this.foreignKeys; - return !!(hasForeignKeys || this.localKeys && utils.get(record, this.localKeys)); - }, - unlinkInverseRecords: function unlinkInverseRecords(records) { - if (!records) { - return; - } - var localField = this.getInverse(this.mapper).localField; - records.forEach(function (record) { - utils.set(record, localField, undefined); + /** + * This adds ES5 getters/setters to the target based on the "properties" in + * this Schema, which makes possible change tracking and validation on + * property assignment. + * + * @name Schema#validate + * @method + * @param {Object} target The prototype to which to apply this schema. + */ + apply: function apply(target, opts) { + opts || (opts = {}); + opts.getter || (opts.getter = '_get'); + opts.setter || (opts.setter = '_set'); + opts.unsetter || (opts.unsetter = '_unset'); + opts.track || (opts.track = this.track); + var properties = this.properties || {}; + utils.forOwn(properties, function (schema, prop) { + Object.defineProperty(target, prop, makeDescriptor(prop, schema, opts)); }); }, - linkRecord: function linkRecord(record, relatedRecords) { - var _this = this; - - var relatedCollection = this.relatedCollection; - var canAutoAddLinks = this.canAutoAddLinks; - var foreignKey = this.foreignKey; - var unsaved = this.relatedCollection.unsaved(); - return relatedRecords.map(function (relatedRecord) { - var relatedId = relatedCollection.recordId(relatedRecord); - if (relatedId === undefined && unsaved.indexOf(relatedRecord) === -1 || relatedRecord !== relatedCollection.get(relatedId)) { - if (foreignKey) { - // TODO: slow, could be optimized? But user loses hook - _this.setForeignKey(record, relatedRecord); + /** + * Apply default values to the target object for missing values. + * + * @name Schema#applyDefaults + * @method + * @param {Object} target The target to which to apply values for missing values. + */ + applyDefaults: function applyDefaults(target) { + if (!target) { + return; + } + var properties = this.properties || {}; + var hasSet = utils.isFunction(target.set) || utils.isFunction(target._set); + utils.forOwn(properties, function (schema, prop) { + if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) { + if (hasSet) { + target.set(prop, utils.plainCopy(schema['default']), { silent: true }); + } else { + utils.set(target, prop, utils.plainCopy(schema['default'])); } - if (canAutoAddLinks) { - relatedRecord = relatedCollection.add(relatedRecord); + } + if (schema.type === 'object' && schema.properties) { + if (hasSet) { + var orig = target._get('noValidate'); + target._set('noValidate', true); + utils.set(target, prop, utils.get(target, prop) || {}, { silent: true }); + target._set('noValidate', orig); + } else { + utils.set(target, prop, utils.get(target, prop) || {}); } + schema.applyDefaults(utils.get(target, prop)); } - - return relatedRecord; - }); - }, - findExistingLinksFor: function findExistingLinksFor(record) { - var id = utils.get(record, this.mapper.idAttribute); - var ids = this.localKeys ? utils.get(record, this.localKeys) : null; - var records = void 0; - - if (id !== undefined && this.foreignKey) { - records = this.findExistingLinksByForeignKey(id); - } else if (this.localKeys && ids) { - records = this.findExistingLinksByLocalKeys(ids); - } else if (id !== undefined && this.foreignKeys) { - records = this.findExistingLinksByForeignKeys(id); - } - - if (records && records.length) { - return records; - } - }, - - - // e.g. user hasMany group via "foreignKeys", so find all users of a group - findExistingLinksByLocalKeys: function findExistingLinksByLocalKeys(ids) { - return this.relatedCollection.filter({ - where: defineProperty({}, this.mapper.idAttribute, { - 'in': ids - }) }); }, - // e.g. group hasMany user via "localKeys", so find all groups that own a user - findExistingLinksByForeignKeys: function findExistingLinksByForeignKeys(id) { - return this.relatedCollection.filter({ - where: defineProperty({}, this.foreignKeys, { - 'contains': id - }) - }); - } -}, { - TYPE_NAME: 'hasMany' -}); - -var HasOneRelation = Relation.extend({ - findExistingLinksFor: function findExistingLinksFor(relatedMapper, record) { - var recordId = utils.get(record, relatedMapper.idAttribute); - var records = this.findExistingLinksByForeignKey(recordId); - - if (records.length) { - return records[0]; - } + /** + * Validate the provided value against this schema. + * + * @name Schema#validate + * @method + * @param {*} value Value to validate. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + validate: function validate(value, opts) { + return _validate(value, this, opts); } }, { - TYPE_NAME: 'hasOne' -}); - -[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) { - Relation[RelationType.TYPE_NAME] = function (related, options) { - return new RelationType(related, options); - }; + ANY_OPS: ANY_OPS, + ARRAY_OPS: ARRAY_OPS, + NUMERIC_OPS: NUMERIC_OPS, + OBJECT_OPS: OBJECT_OPS, + STRING_OPS: STRING_OPS, + typeGroupValidators: typeGroupValidators, + types: types, + validate: _validate, + validationKeywords: validationKeywords }); -/** - * BelongsTo relation decorator. You probably won't use this directly. - * - * @name module:js-data.belongsTo - * @method - * @param {Mapper} related The relation the target belongs to. - * @param {Object} opts Configuration options. - * @param {string} opts.foreignKey The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ -var belongsTo = function belongsTo(related, opts) { - return function (mapper) { - Relation.belongsTo(related, opts).assignTo(mapper); - }; -}; - -/** - * HasMany relation decorator. You probably won't use this directly. - * - * @name module:js-data.hasMany - * @method - * @param {Mapper} related The relation of which the target has many. - * @param {Object} opts Configuration options. - * @param {string} [opts.foreignKey] The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ -var hasMany = function hasMany(related, opts) { - return function (mapper) { - Relation.hasMany(related, opts).assignTo(mapper); - }; -}; - -/** - * HasOne relation decorator. You probably won't use this directly. - * - * @name module:js-data.hasOne - * @method - * @param {Mapper} related The relation of which the target has one. - * @param {Object} opts Configuration options. - * @param {string} [opts.foreignKey] The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ -var hasOne = function hasOne(related, opts) { - return function (mapper) { - Relation.hasOne(related, opts).assignTo(mapper); - }; -}; - var DOMAIN$4 = 'Mapper'; var applyDefaultsHooks = ['beforeCreate', 'beforeCreateMany']; var validatingHooks = ['beforeCreate', 'beforeCreateMany', 'beforeUpdate', 'beforeUpdateAll', 'beforeUpdateMany']; @@ -10887,8 +10926,6 @@ var LinkedCollection$1 = Collection$1.extend({ } if (mapper.relationList.length && record) { - // Check the currently visited record for relations that need to be - // inserted into their respective collections. mapper.relationList.forEach(function (def) { def.removeLinkedRecords(mapper, [record]); }); @@ -10902,8 +10939,6 @@ var LinkedCollection$1 = Collection$1.extend({ records.forEach(this._clearMeta, this); if (mapper.relationList.length && records.length) { - // Check the currently visited record for relations that need to be - // inserted into their respective collections. mapper.relationList.forEach(function (def) { def.removeLinkedRecords(mapper, records); }); @@ -11213,22 +11248,6 @@ var proxiedCollectionMethods = [ 'unsaved']; var ownMethodsForScoping = ['addToCache', 'cachedFind', 'cachedFindAll', 'cacheFind', 'cacheFindAll', 'hashQuery']; -var safeSetProp = function safeSetProp(record, field, value) { - if (record && record._set) { - record._set('props.' + field, value); - } else { - utils.set(record, field, value); - } -}; - -var safeSetLink = function safeSetLink(record, field, value) { - if (record && record._set) { - record._set('links.' + field, value); - } else { - utils.set(record, field, value); - } -}; - var cachedFn = function cachedFn(name, hashOrId, opts) { var cached = this._completedQueries[name][hashOrId]; if (utils.isFunction(cached)) { @@ -11346,15 +11365,6 @@ function DataStore(opts) { var props$1 = { constructor: DataStore, - _callSuper: function _callSuper(method) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - return this.constructor.__super__.prototype[method].apply(this, args); - }, - - /** * Internal method used to handle Mapper responses. * @@ -11426,8 +11436,8 @@ var props$1 = { * @param {...*} [args] Args passed to {@link Collection#emit}. */ _onCollectionEvent: function _onCollectionEvent(name) { - for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key3 = 1; _key3 < _len2; _key3++) { - args[_key3 - 1] = arguments[_key3]; + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) { + args[_key2 - 1] = arguments[_key2]; } var type = args.shift(); @@ -11516,8 +11526,8 @@ var props$1 = { props[method] = { writable: true, value: function value() { - for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { - args[_key4] = arguments[_key4]; + for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) { + args[_key3] = arguments[_key3]; } return original[method].apply(original, [name].concat(args)); @@ -11854,7 +11864,7 @@ var props$1 = { var _this4 = this; opts || (opts = {}); - return this._callSuper('create', name, record, opts).then(function (result) { + return Container.prototype.create.call(this, name, record, opts).then(function (result) { return _this4._end(name, result, opts); }); }, @@ -11955,7 +11965,7 @@ var props$1 = { var _this5 = this; opts || (opts = {}); - return this._callSuper('createMany', name, records, opts).then(function (result) { + return Container.prototype.createMany.call(this, name, records, opts).then(function (result) { return _this5._end(name, result, opts); }); }, @@ -11995,8 +12005,8 @@ var props$1 = { }); collection.on('all', function () { - for (var _len4 = arguments.length, args = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) { - args[_key5] = arguments[_key5]; + for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { + args[_key4] = arguments[_key4]; } self._onCollectionEvent.apply(self, [name].concat(args)); @@ -12028,8 +12038,6 @@ var props$1 = { // e.g. profile.user = someUser // or comment.post = somePost set: function set(record) { - var _this6 = this; - // e.g. const otherUser = profile.user var currentParent = this._get(path); // e.g. profile.user === someUser @@ -12041,23 +12049,8 @@ var props$1 = { // e.g. profile.user !== someUser // or comment.post !== somePost - if (currentParent) { - // e.g. otherUser.profile = undefined - if (inverseDef.type === hasOneType) { - safeSetLink(currentParent, inverseDef.localField, undefined); - } else if (inverseDef.type === hasManyType) { - // e.g. remove comment from otherPost.comments - var children = utils.get(currentParent, inverseDef.localField); - if (id === undefined) { - utils.remove(children, function (child) { - return child === _this6; - }); - } else { - utils.remove(children, function (child) { - return child === _this6 || id === utils.get(child, idAttribute); - }); - } - } + if (currentParent && inverseDef) { + this.removeInverseRelation(currentParent, id, inverseDef, idAttribute); } if (record) { // e.g. profile.user = someUser @@ -12076,22 +12069,8 @@ var props$1 = { safeSetProp(this, foreignKey, relatedId); collection.updateIndex(this, updateOpts); - // Update (set) inverse relation - if (inverseDef.type === hasOneType) { - // e.g. someUser.profile = profile - safeSetLink(record, inverseDef.localField, this); - } else if (inverseDef.type === hasManyType) { - // e.g. add comment to somePost.comments - var _children = utils.get(record, inverseDef.localField); - if (id === undefined) { - utils.noDupeAdd(_children, this, function (child) { - return child === _this6; - }); - } else { - utils.noDupeAdd(_children, this, function (child) { - return child === _this6 || id === utils.get(child, idAttribute); - }); - } + if (inverseDef) { + this.setupInverseRelation(record, id, inverseDef, idAttribute); } } else { // Unset in-memory link only @@ -12118,7 +12097,7 @@ var props$1 = { }; var originalSet = foreignKeyDescriptor.set; foreignKeyDescriptor.set = function (value) { - var _this7 = this; + var _this6 = this; if (originalSet) { originalSet.call(this, value); @@ -12135,11 +12114,11 @@ var props$1 = { var children = utils.get(currentParent, inverseDef.localField); if (id === undefined) { utils.remove(children, function (child) { - return child === _this7; + return child === _this6; }); } else { utils.remove(children, function (child) { - return child === _this7 || id === utils.get(child, idAttribute); + return child === _this6 || id === utils.get(child, idAttribute); }); } } @@ -12185,7 +12164,7 @@ var props$1 = { // or user.groups = someGroups // or group.users = someUsers set: function set(records) { - var _this8 = this; + var _this7 = this; if (records && !utils.isArray(records)) { records = [records]; @@ -12203,7 +12182,7 @@ var props$1 = { // e.g. comment.id var relatedId = utils.get(record, relatedIdAttribute); var currentParent = utils.get(record, inverseLocalField); - if (currentParent && currentParent !== _this8) { + if (currentParent && currentParent !== _this7) { var currentChildrenOfParent = utils.get(currentParent, localField); // e.g. somePost.comments.remove(comment) if (relatedId === undefined) { @@ -12217,7 +12196,7 @@ var props$1 = { } } if (relatedId !== undefined) { - if (_this8._get('$')) { + if (_this7._get('$')) { // Prefer store record record = self.get(relation, relatedId) || record; } @@ -12252,7 +12231,7 @@ var props$1 = { // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' }) self.getCollection(relation).updateIndex(record, updateOpts); // e.g. comment.post = post - safeSetLink(record, inverseLocalField, _this8); + safeSetLink(record, inverseLocalField, _this7); }); } else if (localKeys) { // Update locals @@ -12276,11 +12255,11 @@ var props$1 = { // e.g. someUser.groups.remove(group) if (id === undefined) { utils.remove(parents, function (parent) { - return parent === _this8; + return parent === _this7; }); } else { utils.remove(parents, function (parent) { - return parent === _this8 || id === utils.get(parent, idAttribute); + return parent === _this7 || id === utils.get(parent, idAttribute); }); } } @@ -12290,12 +12269,12 @@ var props$1 = { var parents = utils.get(child, inverseLocalField); // e.g. someUser.groups.push(group) if (id === undefined) { - utils.noDupeAdd(parents, _this8, function (parent) { - return parent === _this8; + utils.noDupeAdd(parents, _this7, function (parent) { + return parent === _this7; }); } else { - utils.noDupeAdd(parents, _this8, function (parent) { - return parent === _this8 || id === utils.get(parent, idAttribute); + utils.noDupeAdd(parents, _this7, function (parent) { + return parent === _this7 || id === utils.get(parent, idAttribute); }); } }); @@ -12313,11 +12292,11 @@ var props$1 = { // e.g. someGroup.users.remove(user) if (id === undefined) { utils.remove(children, function (child) { - return child === _this8; + return child === _this7; }); } else { utils.remove(children, function (child) { - return child === _this8 || id === utils.get(child, idAttribute); + return child === _this7 || id === utils.get(child, idAttribute); }); } }); @@ -12329,12 +12308,12 @@ var props$1 = { }); var children = utils.get(parent, inverseLocalField); if (id === undefined) { - utils.noDupeAdd(children, _this8, function (child) { - return child === _this8; + utils.noDupeAdd(children, _this7, function (child) { + return child === _this7; }); } else { - utils.noDupeAdd(children, _this8, function (child) { - return child === _this8 || id === utils.get(child, idAttribute); + utils.noDupeAdd(children, _this7, function (child) { + return child === _this7 || id === utils.get(child, idAttribute); }); } }); @@ -12359,13 +12338,13 @@ var props$1 = { return current; } var inverseLocalField = def.getInverse(mapper).localField; + // Update (unset) inverse relation + if (current) { + safeSetProp(current, foreignKey, undefined); + self.getCollection(relation).updateIndex(current, updateOpts); + safeSetLink(current, inverseLocalField, undefined); + } if (record) { - // Update (unset) inverse relation - if (current) { - safeSetProp(current, foreignKey, undefined); - self.getCollection(relation).updateIndex(current, updateOpts); - safeSetLink(current, inverseLocalField, undefined); - } var relatedId = utils.get(record, def.getRelation().idAttribute); // Prefer store record if (relatedId !== undefined) { @@ -12394,14 +12373,14 @@ var props$1 = { (function () { var origGet = descriptor.get; descriptor.get = function () { - var _this9 = this; + var _this8 = this; return def.get(def, this, function () { - for (var _len5 = arguments.length, args = Array(_len5), _key6 = 0; _key6 < _len5; _key6++) { - args[_key6] = arguments[_key6]; + for (var _len4 = arguments.length, args = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) { + args[_key5] = arguments[_key5]; } - return origGet.apply(_this9, args); + return origGet.apply(_this8, args); }); }; })(); @@ -12410,10 +12389,10 @@ var props$1 = { (function () { var origSet = descriptor.set; descriptor.set = function (related) { - var _this10 = this; + var _this9 = this; return def.set(def, this, related, function (value) { - return origSet.call(_this10, value === undefined ? related : value); + return origSet.call(_this9, value === undefined ? related : value); }); }; })(); @@ -12518,16 +12497,16 @@ var props$1 = { * @since 3.0.0 */ destroy: function destroy(name, id, opts) { - var _this11 = this; + var _this10 = this; opts || (opts = {}); - return this._callSuper('destroy', name, id, opts).then(function (result) { - var record = _this11.getCollection(name).remove(id, opts); + return Container.prototype.destroy.call(this, name, id, opts).then(function (result) { + var record = _this10.getCollection(name).remove(id, opts); - if (record && _this11.unlinkOnDestroy) { + if (record && _this10.unlinkOnDestroy) { var _opts = utils.plainCopy(opts); _opts.withAll = true; - utils.forEachRelation(_this11.getMapper(name), _opts, function (def) { + utils.forEachRelation(_this10.getMapper(name), _opts, function (def) { utils.set(record, def.localField, undefined); }); } @@ -12537,8 +12516,8 @@ var props$1 = { } else { result = record; } - delete _this11._pendingQueries[name][id]; - delete _this11._completedQueries[name][id]; + delete _this10._pendingQueries[name][id]; + delete _this10._completedQueries[name][id]; return result; }); }, @@ -12634,16 +12613,16 @@ var props$1 = { * @since 3.0.0 */ destroyAll: function destroyAll(name, query, opts) { - var _this12 = this; + var _this11 = this; opts || (opts = {}); - return this._callSuper('destroyAll', name, query, opts).then(function (result) { - var records = _this12.getCollection(name).removeAll(query, opts); + return Container.prototype.destroyAll.call(this, name, query, opts).then(function (result) { + var records = _this11.getCollection(name).removeAll(query, opts); - if (records && records.length && _this12.unlinkOnDestroy) { + if (records && records.length && _this11.unlinkOnDestroy) { var _opts = utils.plainCopy(opts); _opts.withAll = true; - utils.forEachRelation(_this12.getMapper(name), _opts, function (def) { + utils.forEachRelation(_this11.getMapper(name), _opts, function (def) { records.forEach(function (record) { utils.set(record, def.localField, undefined); }); @@ -12655,9 +12634,9 @@ var props$1 = { } else { result = records; } - var hash = _this12.hashQuery(name, query, opts); - delete _this12._pendingQueries[name][hash]; - delete _this12._completedQueries[name][hash]; + var hash = _this11.hashQuery(name, query, opts); + delete _this11._pendingQueries[name][hash]; + delete _this11._completedQueries[name][hash]; return result; }); }, @@ -12754,7 +12733,7 @@ var props$1 = { * @since 3.0.0 */ find: function find(name, id, opts) { - var _this13 = this; + var _this12 = this; opts || (opts = {}); var mapper = this.getMapper(name); @@ -12769,13 +12748,13 @@ var props$1 = { var promise = void 0; if (opts.force || !item) { - promise = this._pendingQueries[name][id] = this._callSuper('find', name, id, opts).then(function (result) { - delete _this13._pendingQueries[name][id]; - result = _this13._end(name, result, opts); - _this13.cacheFind(name, result, id, opts); + promise = this._pendingQueries[name][id] = Container.prototype.find.call(this, name, id, opts).then(function (result) { + delete _this12._pendingQueries[name][id]; + result = _this12._end(name, result, opts); + _this12.cacheFind(name, result, id, opts); return result; }, function (err) { - delete _this13._pendingQueries[name][id]; + delete _this12._pendingQueries[name][id]; return utils.reject(err); }); } else { @@ -12868,7 +12847,7 @@ var props$1 = { * @since 3.0.0 */ findAll: function findAll(name, query, opts) { - var _this14 = this; + var _this13 = this; opts || (opts = {}); var mapper = this.getMapper(name); @@ -12885,13 +12864,13 @@ var props$1 = { var promise = void 0; if (opts.force || !items) { - promise = this._pendingQueries[name][hash] = this._callSuper('findAll', name, query, opts).then(function (result) { - delete _this14._pendingQueries[name][hash]; - result = _this14._end(name, result, opts); - _this14.cacheFindAll(name, result, hash, opts); + promise = this._pendingQueries[name][hash] = Container.prototype.findAll.call(this, name, query, opts).then(function (result) { + delete _this13._pendingQueries[name][hash]; + result = _this13._end(name, result, opts); + _this13.cacheFindAll(name, result, hash, opts); return result; }, function (err) { - delete _this14._pendingQueries[name][hash]; + delete _this13._pendingQueries[name][hash]; return utils.reject(err); }); } else { @@ -13042,7 +13021,7 @@ var props$1 = { * @since 3.0.0 */ removeRelated: function removeRelated(name, records, opts) { - var _this15 = this; + var _this14 = this; if (!utils.isArray(records)) { records = [records]; @@ -13066,10 +13045,10 @@ var props$1 = { }) }; } else if (def.type === belongsToType) { - relatedData = _this15.remove(def.relation, def.getForeignKey(record), optsCopy); + relatedData = _this14.remove(def.relation, def.getForeignKey(record), optsCopy); } if (query) { - relatedData = _this15.removeAll(def.relation, query, optsCopy); + relatedData = _this14.removeAll(def.relation, query, optsCopy); } if (relatedData) { if (utils.isArray(relatedData) && !relatedData.length) { @@ -13172,11 +13151,11 @@ var props$1 = { * @since 3.0.0 */ update: function update(name, id, record, opts) { - var _this16 = this; + var _this15 = this; opts || (opts = {}); - return this._callSuper('update', name, id, record, opts).then(function (result) { - return _this16._end(name, result, opts); + return Container.prototype.update.call(this, name, id, record, opts).then(function (result) { + return _this15._end(name, result, opts); }); }, @@ -13268,11 +13247,11 @@ var props$1 = { * @since 3.0.0 */ updateAll: function updateAll(name, props, query, opts) { - var _this17 = this; + var _this16 = this; opts || (opts = {}); - return this._callSuper('updateAll', name, query, props, opts).then(function (result) { - return _this17._end(name, result, opts); + return Container.prototype.updateAll.call(this, name, query, props, opts).then(function (result) { + return _this16._end(name, result, opts); }); }, @@ -13364,11 +13343,11 @@ var props$1 = { * @since 3.0.0 */ updateMany: function updateMany(name, records, opts) { - var _this18 = this; + var _this17 = this; opts || (opts = {}); - return this._callSuper('updateMany', name, records, opts).then(function (result) { - return _this18._end(name, result, opts); + return Container.prototype.updateMany.call(this, name, records, opts).then(function (result) { + return _this17._end(name, result, opts); }); } }; @@ -13377,8 +13356,8 @@ proxiedCollectionMethods.forEach(function (method) { props$1[method] = function (name) { var _getCollection; - for (var _len6 = arguments.length, args = Array(_len6 > 1 ? _len6 - 1 : 0), _key7 = 1; _key7 < _len6; _key7++) { - args[_key7 - 1] = arguments[_key7]; + for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key6 = 1; _key6 < _len5; _key6++) { + args[_key6 - 1] = arguments[_key6]; } return (_getCollection = this.getCollection(name))[method].apply(_getCollection, args); @@ -13435,7 +13414,7 @@ var DataStore$1 = Container.extend(props$1); * @type {Object} */ var version = { - full: '3.0.0-rc.3', + full: '3.0.0-rc.4', major: 3, minor: 0, patch: 0 diff --git a/dist/js-data.es2015.js.map b/dist/js-data.es2015.js.map index 8bd32fc1..daf5bdf2 100644 --- a/dist/js-data.es2015.js.map +++ b/dist/js-data.es2015.js.map @@ -1 +1 @@ -{"version":3,"file":null,"sources":["../src/utils.js","../src/Settable.js","../src/Component.js","../src/Query.js","../lib/mindex/_utils.js","../lib/mindex/index.js","../src/Collection.js","../src/Record.js","../src/Schema.js","../src/Relation.js","../src/Relation/BelongsTo.js","../src/Relation/HasMany.js","../src/Relation/HasOne.js","../src/relations.js","../src/decorators.js","../src/Mapper.js","../src/Container.js","../src/LinkedCollection.js","../src/DataStore.js","../src/index.js"],"sourcesContent":["/**\n * Utility methods used by JSData.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @namespace utils\n * @type {Object}\n */\n\nconst DOMAIN = 'utils'\n\nconst INFINITY = 1 / 0\nconst MAX_INTEGER = 1.7976931348623157e+308\nconst BOOL_TAG = '[object Boolean]'\nconst DATE_TAG = '[object Date]'\nconst FUNC_TAG = '[object Function]'\nconst NUMBER_TAG = '[object Number]'\nconst OBJECT_TAG = '[object Object]'\nconst REGEXP_TAG = '[object RegExp]'\nconst STRING_TAG = '[object String]'\nconst objToString = Object.prototype.toString\nconst PATH = /^(.+)\\.(.+)$/\n\nconst ERRORS = {\n '400' () { return `expected: ${arguments[0]}, found: ${arguments[2] ? arguments[1] : typeof arguments[1]}` },\n '404' () { return `${arguments[0]} not found` }\n}\n\nconst toInteger = function (value) {\n if (!value) {\n return 0\n }\n // Coerce to number\n value = +value\n if (value === INFINITY || value === -INFINITY) {\n const sign = (value < 0 ? -1 : 1)\n return sign * MAX_INTEGER\n }\n const remainder = value % 1\n return value === value ? (remainder ? value - remainder : value) : 0 // eslint-disable-line\n}\n\nconst toStr = function (value) {\n return objToString.call(value)\n}\n\nconst isPlainObject = function (value) {\n return (!!value && typeof value === 'object' && value.constructor === Object)\n}\n\nconst mkdirP = function (object, path) {\n if (!path) {\n return object\n }\n const parts = path.split('.')\n parts.forEach(function (key) {\n if (!object[key]) {\n object[key] = {}\n }\n object = object[key]\n })\n return object\n}\n\nconst utils = {\n /**\n * Reference to the Promise constructor used by JSData. Defaults to\n * `window.Promise` or `global.Promise`.\n *\n * @example Make JSData use a different `Promise` constructor\n * import Promise from 'bluebird'\n * import {utils} from 'js-data'\n * utils.Promise = Promise\n *\n * @name utils.Promise\n * @since 3.0.0\n * @type {Function}\n */\n Promise: Promise,\n\n /**\n * Shallow copy properties that meet the following criteria from `src` to\n * `dest`:\n *\n * - own enumerable\n * - not a function\n * - does not start with \"_\"\n *\n * @method utils._\n * @param {Object} dest Destination object.\n * @param {Object} src Source object.\n * @private\n * @since 3.0.0\n */\n _ (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (key && dest[key] === undefined && !utils.isFunction(value) && key.indexOf('_') !== 0) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Recursively iterates over relations found in `opts.with`.\n *\n * @method utils._forRelation\n * @param {Object} opts Configuration options.\n * @param {Relation} def Relation definition.\n * @param {Function} fn Callback function.\n * @param {*} [thisArg] Execution context for the callback function.\n * @private\n * @since 3.0.0\n */\n _forRelation (opts, def, fn, thisArg) {\n const relationName = def.relation\n let containedName = null\n let index\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n if ((index = utils._getIndex(opts.with, relationName)) >= 0) {\n containedName = relationName\n } else if ((index = utils._getIndex(opts.with, def.localField)) >= 0) {\n containedName = def.localField\n }\n\n if (opts.withAll) {\n fn.call(thisArg, def, {})\n return\n } else if (!containedName) {\n return\n }\n let optsCopy = {}\n utils.fillIn(optsCopy, def.getRelation())\n utils.fillIn(optsCopy, opts)\n optsCopy.with = opts.with.slice()\n optsCopy._activeWith = optsCopy.with.splice(index, 1)[0]\n optsCopy.with.forEach(function (relation, i) {\n if (relation && relation.indexOf(containedName) === 0 && relation.length >= containedName.length && relation[containedName.length] === '.') {\n optsCopy.with[i] = relation.substr(containedName.length + 1)\n } else {\n optsCopy.with[i] = ''\n }\n })\n fn.call(thisArg, def, optsCopy)\n },\n\n /**\n * Find the index of a relation in the given list\n *\n * @method utils._getIndex\n * @param {string[]} list List to search.\n * @param {string} relation Relation to find.\n * @private\n * @returns {number}\n */\n _getIndex (list, relation) {\n let index = -1\n list.forEach(function (_relation, i) {\n if (_relation === relation) {\n index = i\n return false\n } else if (utils.isObject(_relation)) {\n if (_relation.relation === relation) {\n index = i\n return false\n }\n }\n })\n return index\n },\n\n /**\n * Define hidden (non-enumerable), writable properties on `target` from the\n * provided `props`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {}\n * utils.addHiddenPropsToTarget(Cat.prototype, {\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat.say() // \"meow\"\n *\n * @method utils.addHiddenPropsToTarget\n * @param {Object} target That to which `props` should be added.\n * @param {Object} props Properties to be added to `target`.\n * @since 3.0.0\n */\n addHiddenPropsToTarget (target, props) {\n const map = {}\n Object.keys(props).forEach(function (propName) {\n const descriptor = Object.getOwnPropertyDescriptor(props, propName)\n\n descriptor.enumerable = false\n map[propName] = descriptor\n })\n Object.defineProperties(target, map)\n },\n\n /**\n * Return whether the two objects are deeply different.\n *\n * @example\n * import {utils} from 'js-data'\n * utils.areDifferent({}, {}) // false\n * utils.areDifferent({ a: 1 }, { a: 1 }) // false\n * utils.areDifferent({ foo: 'bar' }, {}) // true\n *\n * @method utils.areDifferent\n * @param {Object} a Base object.\n * @param {Object} b Comparison object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Whether the two objects are deeply different.\n * @see utils.diffObjects\n * @since 3.0.0\n */\n areDifferent (newObject, oldObject, opts) {\n opts || (opts = {})\n const diff = utils.diffObjects(newObject, oldObject, opts)\n const diffCount = Object.keys(diff.added).length +\n Object.keys(diff.removed).length +\n Object.keys(diff.changed).length\n return diffCount > 0\n },\n\n /**\n * Verified that the given constructor is being invoked via `new`, as opposed\n * to just being called like a normal function.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {\n * utils.classCallCheck(this, Cat)\n * }\n * const cat = new Cat() // this is ok\n * Cat() // this throws an error\n *\n * @method utils.classCallCheck\n * @param {*} instance Instance that is being constructed.\n * @param {Constructor} ctor Constructor function used to construct the\n * instance.\n * @since 3.0.0\n * @throws {Error} Throws an error if the constructor is being improperly\n * invoked.\n */\n classCallCheck (instance, ctor) {\n if (!(instance instanceof ctor)) {\n throw utils.err(`${ctor.name}`)(500, 'Cannot call a class as a function')\n }\n },\n\n /**\n * Deep copy a value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' } }\n * const b = utils.copy(a)\n * a === b // false\n * utils.areDifferent(a, b) // false\n *\n * @param {*} from Value to deep copy.\n * @param {*} [to] Destination object for the copy operation.\n * @param {*} [stackFrom] For internal use.\n * @param {*} [stackTo] For internal use.\n * @param {string[]|RegExp[]} [blacklist] List of strings or RegExp of\n * properties to skip.\n * @param {boolean} [plain] Whether to make a plain copy (don't try to use\n * original prototype).\n * @returns {*} Deep copy of `from`.\n * @since 3.0.0\n */\n copy (from, to, stackFrom, stackTo, blacklist, plain) {\n if (!to) {\n to = from\n if (from) {\n if (utils.isArray(from)) {\n to = utils.copy(from, [], stackFrom, stackTo, blacklist, plain)\n } else if (utils.isDate(from)) {\n to = new Date(from.getTime())\n } else if (utils.isRegExp(from)) {\n to = new RegExp(from.source, from.toString().match(/[^\\/]*$/)[0])\n to.lastIndex = from.lastIndex\n } else if (utils.isObject(from)) {\n if (plain) {\n to = utils.copy(from, {}, stackFrom, stackTo, blacklist, plain)\n } else {\n to = utils.copy(from, Object.create(Object.getPrototypeOf(from)), stackFrom, stackTo, blacklist, plain)\n }\n }\n }\n } else {\n if (from === to) {\n throw utils.err(`${DOMAIN}.copy`)(500, 'Cannot copy! Source and destination are identical.')\n }\n\n stackFrom = stackFrom || []\n stackTo = stackTo || []\n\n if (utils.isObject(from)) {\n let index = stackFrom.indexOf(from)\n if (index !== -1) {\n return stackTo[index]\n }\n\n stackFrom.push(from)\n stackTo.push(to)\n }\n\n let result\n if (utils.isArray(from)) {\n let i\n to.length = 0\n for (i = 0; i < from.length; i++) {\n result = utils.copy(from[i], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[i])) {\n stackFrom.push(from[i])\n stackTo.push(result)\n }\n to.push(result)\n }\n } else {\n if (utils.isArray(to)) {\n to.length = 0\n } else {\n utils.forOwn(to, function (value, key) {\n delete to[key]\n })\n }\n for (var key in from) {\n if (from.hasOwnProperty(key)) {\n if (utils.isBlacklisted(key, blacklist)) {\n continue\n }\n result = utils.copy(from[key], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[key])) {\n stackFrom.push(from[key])\n stackTo.push(result)\n }\n to[key] = result\n }\n }\n }\n }\n return to\n },\n\n /**\n * Recursively shallow fill in own enumerable properties from `source` to\n * `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"bip\"}\n *\n * @method utils.deepFillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n deepFillIn (dest, source) {\n if (source) {\n utils.forOwn(source, function (value, key) {\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepFillIn(existing, value)\n } else if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n }\n return dest\n },\n\n /**\n * Recursively shallow copy enumerable properties from `source` to `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"boop\"}\n *\n * @method utils.deepMixIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepFillIn\n * @since 3.0.0\n */\n deepMixIn (dest, source) {\n if (source) {\n for (var key in source) {\n const value = source[key]\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepMixIn(existing, value)\n } else {\n dest[key] = value\n }\n }\n }\n return dest\n },\n\n /**\n * Return a diff of the base object to the comparison object.\n *\n * @example\n * import {utils} from 'js-data'\n * const oldObject = { foo: 'bar', a: 1234 }\n * const newObject = { beep: 'boop', a: 5678 }\n * const diff = utils.diffObjects(oldObject, newObject)\n * console.log(diff.added) // {\"beep\":\"boop\"}\n * console.log(diff.changed) // {\"a\":5678}\n * console.log(diff.removed) // {\"foo\":undefined}\n *\n * @method utils.diffObjects\n * @param {Object} newObject Comparison object.\n * @param {Object} oldObject Base object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} The diff from the base object to the comparison object.\n * @see utils.areDifferent\n * @since 3.0.0\n */\n diffObjects (newObject, oldObject, opts) {\n opts || (opts = {})\n let equalsFn = opts.equalsFn\n let blacklist = opts.ignore\n const diff = {\n added: {},\n changed: {},\n removed: {}\n }\n if (!utils.isFunction(equalsFn)) {\n equalsFn = utils.deepEqual\n }\n\n const newKeys = Object.keys(newObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n const oldKeys = Object.keys(oldObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n\n // Check for properties that were added or changed\n newKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (equalsFn(oldValue, newValue)) {\n return\n }\n if (oldValue === undefined) {\n diff.added[key] = newValue\n } else {\n diff.changed[key] = newValue\n }\n })\n\n // Check for properties that were removed\n oldKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (newValue === undefined && oldValue !== undefined) {\n diff.removed[key] = undefined\n }\n })\n\n return diff\n },\n\n /**\n * Return whether the two values are equal according to the `==` operator.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.equal(1,1)) // true\n * console.log(utils.equal(1,'1')) // true\n * console.log(utils.equal(93, 66)) // false\n *\n * @method utils.equal\n * @param {*} a First value in the comparison.\n * @param {*} b Second value in the comparison.\n * @returns {boolean} Whether the two values are equal according to `==`.\n * @since 3.0.0\n */\n equal (a, b) {\n return a == b // eslint-disable-line\n },\n\n /**\n * Produce a factory function for making Error objects with the provided\n * metadata. Used throughout the various js-data components.\n *\n * @example\n * import {utils} from 'js-data'\n * const errorFactory = utils.err('domain', 'target')\n * const error400 = errorFactory(400, 'expected type', 'actual type')\n * console.log(error400) // [Error: [domain:target] expected: expected type, found: string\nhttp://www.js-data.io/v3.0/docs/errors#400]\n * @method utils.err\n * @param {string} domain Namespace.\n * @param {string} target Target.\n * @returns {Function} Factory function.\n * @since 3.0.0\n */\n err (domain, target) {\n return function (code) {\n const prefix = `[${domain}:${target}] `\n let message = ERRORS[code].apply(null, Array.prototype.slice.call(arguments, 1))\n message = `${prefix}${message}\nhttp://www.js-data.io/v3.0/docs/errors#${code}`\n return new Error(message)\n }\n },\n\n /**\n * Add eventing capabilities into the target object.\n *\n * @example\n * import {utils} from 'js-data'\n * const user = { name: 'John' }\n * utils.eventify(user)\n * user.on('foo', () => console.log(arguments))\n * user.emit('foo', 1, 'bar') // should log to console values (1, \"bar\")\n *\n * @method utils.eventify\n * @param {Object} target Target object.\n * @param {Function} [getter] Custom getter for retrieving the object's event\n * listeners.\n * @param {Function} [setter] Custom setter for setting the object's event\n * listeners.\n * @since 3.0.0\n */\n eventify (target, getter, setter) {\n target = target || this\n let _events = {}\n if (!getter && !setter) {\n getter = function () { return _events }\n setter = function (value) { _events = value }\n }\n Object.defineProperties(target, {\n emit: {\n value (...args) {\n const events = getter.call(this) || {}\n const type = args.shift()\n let listeners = events[type] || []\n let i\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n listeners = events.all || []\n args.unshift(type)\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n }\n },\n off: {\n value (type, func) {\n const events = getter.call(this)\n const listeners = events[type]\n if (!listeners) {\n setter.call(this, {})\n } else if (func) {\n for (let i = 0; i < listeners.length; i++) {\n if (listeners[i].f === func) {\n listeners.splice(i, 1)\n break\n }\n }\n } else {\n listeners.splice(0, listeners.length)\n }\n }\n },\n on: {\n value (type, func, thisArg) {\n if (!getter.call(this)) {\n setter.call(this, {})\n }\n const events = getter.call(this)\n events[type] = events[type] || []\n events[type].push({\n c: thisArg,\n f: func\n })\n }\n }\n })\n },\n\n /**\n * Used for sublcassing. Invoke this method in the context of a superclass to\n * to produce a subclass based on `props` and `classProps`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Animal () {}\n * Animal.extend = utils.extend\n * const Cat = Animal.extend({\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat instanceof Animal // true\n * cat instanceof Cat // true\n * cat.say() // \"meow\"\n *\n * @method utils.extend\n * @param {Object} props Instance properties for the subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to use as the subclass.\n * @param {Object} props Static properties for the subclass.\n * @returns {Constructor} A new subclass.\n * @since 3.0.0\n */\n extend (props, classProps) {\n const superClass = this\n let subClass\n\n props || (props = {})\n classProps || (classProps = {})\n\n if (props.hasOwnProperty('constructor')) {\n subClass = props.constructor\n delete props.constructor\n } else {\n subClass = function (...args) {\n utils.classCallCheck(this, subClass)\n superClass.apply(this, args)\n }\n }\n\n // Setup inheritance of instance members\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n configurable: true,\n enumerable: false,\n value: subClass,\n writable: true\n }\n })\n\n const obj = Object\n // Setup inheritance of static members\n if (obj.setPrototypeOf) {\n obj.setPrototypeOf(subClass, superClass)\n } else if (classProps.strictEs6Class) {\n subClass.__proto__ = superClass // eslint-disable-line\n } else {\n utils.forOwn(superClass, function (value, key) {\n subClass[key] = value\n })\n }\n if (!subClass.hasOwnProperty('__super__')) {\n Object.defineProperty(subClass, '__super__', {\n configurable: true,\n value: superClass\n })\n }\n\n utils.addHiddenPropsToTarget(subClass.prototype, props)\n utils.fillIn(subClass, classProps)\n\n return subClass\n },\n\n /**\n * Shallow copy own enumerable properties from `src` to `dest` that are on\n * `src` but are missing from `dest.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: 'bar', beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.fillIn(b, a)\n * console.log(b) // {\"foo\":\"bar\",\"beep\":\"bip\"}\n *\n * @method utils.fillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.deepFillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n fillIn (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Find the last index of an item in an array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = { name: 'John', age: 20 }\n * const sara = { name: 'Sara', age: 25 }\n * const dan = { name: 'Dan', age: 20 }\n * const users = [john, sara, dan]\n *\n * console.log(utils.findIndex(users, (user) => user.age === 25)) // 1\n * console.log(utils.findIndex(users, (user) => user.age > 19)) // 2\n * console.log(utils.findIndex(users, (user) => user.name === 'John')) // 0\n * console.log(utils.findIndex(users, (user) => user.name === 'Jimmy')) // -1\n *\n * @method utils.findIndex\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n * @returns {number} Index if found or -1 if not found.\n * @since 3.0.0\n */\n findIndex (array, fn) {\n let index = -1\n if (!array) {\n return index\n }\n array.forEach(function (record, i) {\n if (fn(record)) {\n index = i\n return false\n }\n })\n return index\n },\n\n /**\n * Recursively iterate over a {@link Mapper}'s relations according to\n * `opts.with`.\n *\n * @method utils.forEachRelation\n * @param {Mapper} mapper Mapper.\n * @param {Object} opts Configuration options.\n * @param {Function} fn Callback function.\n * @param {*} thisArg Execution context for the callback function.\n * @since 3.0.0\n */\n forEachRelation (mapper, opts, fn, thisArg) {\n const relationList = mapper.relationList || []\n if (!relationList.length) {\n return\n }\n relationList.forEach(function (def) {\n utils._forRelation(opts, def, fn, thisArg)\n })\n },\n\n /**\n * Iterate over an object's own enumerable properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { b: 1, c: 4 }\n * let sum = 0\n * utils.forOwn(a, function (value, key) {\n * sum += value\n * })\n * console.log(sum) // 5\n *\n * @method utils.forOwn\n * @param {Object} object The object whose properties are to be enumerated.\n * @param {Function} fn Iteration function.\n * @param {Object} [thisArg] Content to which to bind `fn`.\n * @since 3.0.0\n */\n forOwn (obj, fn, thisArg) {\n const keys = Object.keys(obj)\n const len = keys.length\n let i\n for (i = 0; i < len; i++) {\n fn.call(thisArg, obj[keys[i]], keys[i], obj)\n }\n },\n\n /**\n * Proxy for `JSON.parse`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = utils.fromJson('{\"name\" : \"John\"}')\n * console.log(a) // { name: 'John' }\n *\n * @method utils.fromJson\n * @param {string} json JSON to parse.\n * @returns {Object} Parsed object.\n * @see utils.toJson\n * @since 3.0.0\n */\n fromJson (json) {\n return utils.isString(json) ? JSON.parse(json) : json\n },\n\n /**\n * Retrieve the specified property from the given object. Supports retrieving\n * nested properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * console.log(utils.get(a, 'beep')) // \"boop\"\n * console.log(utils.get(a, 'foo.bar')) // \"baz\"\n *\n * @method utils.get\n * @param {Object} object Object from which to retrieve a property's value.\n * @param {string} prop Property to retrieve.\n * @returns {*} Value of the specified property.\n * @see utils.set\n * @since 3.0.0\n */\n 'get': function (object, prop) {\n if (!prop) {\n return\n }\n const parts = prop.split('.')\n const last = parts.pop()\n\n while (prop = parts.shift()) { // eslint-disable-line\n object = object[prop]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n return object[last]\n },\n\n /**\n * Return the superclass for the given instance or subclass. If an instance is\n * provided, then finds the parent class of the instance's constructor.\n *\n * @example\n * import {utils} from 'js-data'\n * // using ES2015 classes\n * class Foo {}\n * class Bar extends Foo {}\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * // using Function constructor with utils.extend\n * function Foo () {}\n * Foo.extend = utils.extend\n * const Bar = Foo.extend()\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * @method utils.getSuper\n * @param {Object|Function} instance Instance or constructor.\n * @param {boolean} [isCtor=false] Whether `instance` is a constructor.\n * @returns {Constructor} The superclass (grandparent constructor).\n * @since 3.0.0\n */\n getSuper (instance, isCtor) {\n const ctor = isCtor ? instance : instance.constructor\n if (ctor.hasOwnProperty('__super__')) {\n return ctor.__super__\n }\n return Object.getPrototypeOf(ctor) || ctor.__proto__ // eslint-disable-line\n },\n\n /**\n * Return the intersection of two arrays.\n *\n * @example\n * import {utils} from 'js-data'\n * const arrA = ['green', 'red', 'blue', 'red']\n * const arrB = ['green', 'yellow', 'red']\n * const intersected = utils.intersection(arrA, arrB)\n *\n * console.log(intersected) // ['green', 'red'])\n *\n * @method utils.intersection\n * @param {Array} array1 First array.\n * @param {Array} array2 Second array.\n * @returns {Array} Array of elements common to both arrays.\n * @since 3.0.0\n */\n intersection (array1, array2) {\n if (!array1 || !array2) {\n return []\n }\n const result = []\n let item\n let i\n const len = array1.length\n for (i = 0; i < len; i++) {\n item = array1[i]\n if (result.indexOf(item) !== -1) {\n continue\n }\n if (array2.indexOf(item) !== -1) {\n result.push(item)\n }\n }\n return result\n },\n\n /**\n * Proxy for `Array.isArray`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = [1,2,3,4,5]\n * const b = { foo: \"bar\" }\n * console.log(utils.isArray(a)) // true\n * console.log(utils.isArray(b)) // false\n *\n * @method utils.isArray\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an array.\n * @since 3.0.0\n */\n isArray: Array.isArray,\n\n /**\n * Return whether `prop` is matched by any string or regular expression in\n * `blacklist`.\n *\n * @example\n * import {utils} from 'js-data'\n * const blacklist = [/^\\$hashKey/g, /^_/g, 'id']\n * console.log(utils.isBlacklisted(\"$hashKey\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"id\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"_myProp\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"my_id\", blacklist)) // false\n *\n * @method utils.isBlacklisted\n * @param {string} prop The name of a property to check.\n * @param {Array} blacklist Array of strings and regular expressions.\n * @returns {boolean} Whether `prop` was matched.\n * @since 3.0.0\n */\n isBlacklisted (prop, blacklist) {\n if (!blacklist || !blacklist.length) {\n return false\n }\n let matches\n for (var i = 0; i < blacklist.length; i++) {\n if ((toStr(blacklist[i]) === REGEXP_TAG && blacklist[i].test(prop)) || blacklist[i] === prop) {\n matches = prop\n return !!matches\n }\n }\n return !!matches\n },\n\n /**\n * Return whether the provided value is a boolean.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = true\n * const b = { foo: \"bar\" }\n * console.log(utils.isBoolean(a)) // true\n * console.log(utils.isBoolean(b)) // false\n *\n * @method utils.isBoolean\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a boolean.\n * @since 3.0.0\n */\n isBoolean (value) {\n return toStr(value) === BOOL_TAG\n },\n\n /**\n * Return whether the provided value is a date.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = new Date()\n * const b = { foo: \"bar\" }\n * console.log(utils.isDate(a)) // true\n * console.log(utils.isDate(b)) // false\n *\n * @method utils.isDate\n * @param {*} value The value to test.\n * @returns {Date} Whether the provided value is a date.\n * @since 3.0.0\n */\n isDate (value) {\n return (value && typeof value === 'object' && toStr(value) === DATE_TAG)\n },\n\n /**\n * Return whether the provided value is a function.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = function (){ console.log('foo bar')}\n * const b = { foo: \"bar\" }\n * console.log(utils.isFunction(a)) // true\n * console.log(utils.isFunction(b)) // false\n *\n * @method utils.isFunction\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a function.\n * @since 3.0.0\n */\n isFunction (value) {\n return typeof value === 'function' || (value && toStr(value) === FUNC_TAG)\n },\n\n /**\n * Return whether the provided value is an integer.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = 1.25\n * const c = '1'\n * console.log(utils.isInteger(a)) // true\n * console.log(utils.isInteger(b)) // false\n * console.log(utils.isInteger(c)) // false\n *\n * @method utils.isInteger\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an integer.\n * @since 3.0.0\n */\n isInteger (value) {\n return toStr(value) === NUMBER_TAG && value == toInteger(value) // eslint-disable-line\n },\n\n /**\n * Return whether the provided value is `null`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = null\n * const b = { foo: \"bar\" }\n * console.log(utils.isNull(a)) // true\n * console.log(utils.isNull(b)) // false\n *\n * @method utils.isNull\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is `null`.\n * @since 3.0.0\n */\n isNull (value) {\n return value === null\n },\n\n /**\n * Return whether the provided value is a number.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = -1.25\n * const c = '1'\n * console.log(utils.isNumber(a)) // true\n * console.log(utils.isNumber(b)) // true\n * console.log(utils.isNumber(c)) // false\n *\n * @method utils.isNumber\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a number.\n * @since 3.0.0\n */\n isNumber (value) {\n const type = typeof value\n return type === 'number' || (value && type === 'object' && toStr(value) === NUMBER_TAG)\n },\n\n /**\n * Return whether the provided value is an object.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\" }\n * const b = 'foo bar'\n * console.log(utils.isObject(a)) // true\n * console.log(utils.isObject(b)) // false\n *\n * @method utils.isObject\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an object.\n * @since 3.0.0\n */\n isObject (value) {\n return toStr(value) === OBJECT_TAG\n },\n\n /**\n * Return whether the provided value is a regular expression.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = /^\\$.+$/ig\n * const b = new RegExp('^\\$.+$', 'ig')\n * const c = { foo: \"bar\" }\n * console.log(utils.isRegExp(a)) // true\n * console.log(utils.isRegExp(b)) // true\n * console.log(utils.isRegExp(c)) // false\n *\n * @method utils.isRegExp\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a regular expression.\n * @since 3.0.0\n */\n isRegExp (value) {\n return toStr(value) === REGEXP_TAG\n },\n\n /**\n * Return whether the provided value is a string or a number.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isSorN('')) // true\n * console.log(utils.isSorN(-1.65)) // true\n * console.log(utils.isSorN('my string')) // true\n * console.log(utils.isSorN({})) // false\n * console.log(utils.isSorN([1,2,4])) // false\n *\n * @method utils.isSorN\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string or a number.\n * @since 3.0.0\n */\n isSorN (value) {\n return utils.isString(value) || utils.isNumber(value)\n },\n\n /**\n * Return whether the provided value is a string.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('')) // true\n * console.log(utils.isString('my string')) // true\n * console.log(utils.isString(100)) // false\n * console.log(utils.isString([1,2,4])) // false\n *\n * @method utils.isString\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string.\n * @since 3.0.0\n */\n isString (value) {\n return typeof value === 'string' || (value && typeof value === 'object' && toStr(value) === STRING_TAG)\n },\n\n /**\n * Return whether the provided value is a `undefined`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = undefined\n * const b = { foo: \"bar\"}\n * console.log(utils.isUndefined(a)) // true\n * console.log(utils.isUndefined(b.baz)) // true\n * console.log(utils.isUndefined(b)) // false\n * console.log(utils.isUndefined(b.foo)) // false\n *\n * @method utils.isUndefined\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a `undefined`.\n * @since 3.0.0\n */\n isUndefined (value) {\n return value === undefined\n },\n\n /**\n * Mix in logging capabilities to the target.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\"}\n *\n * // Add standard logging to an object\n * utils.logify(a)\n * a.log('info', 'test log info') // output 'test log info' to console.\n *\n * // Toggle debug output of an object\n * a.dbg('test debug output') // does not output because debug is off.\n * a.debug = true\n * a.dbg('test debug output') // output 'test debug output' to console.\n *\n * @method utils.logify\n * @param {*} target The target.\n * @since 3.0.0\n */\n logify (target) {\n utils.addHiddenPropsToTarget(target, {\n dbg (...args) {\n if (utils.isFunction(this.log)) {\n this.log('debug', ...args)\n }\n },\n log (level, ...args) {\n if (level && !args.length) {\n args.push(level)\n level = 'debug'\n }\n if (level === 'debug' && !this.debug) {\n return\n }\n const prefix = `${level.toUpperCase()}: (${this.name || this.constructor.name})`\n if (utils.isFunction(console[level])) {\n console[level](prefix, ...args)\n } else {\n console.log(prefix, ...args)\n }\n }\n })\n },\n\n /**\n * Adds the given record to the provided array only if it's not already in the\n * array.\n *\n * @example\n * import {utils} from 'js-data'\n * const colors = ['red', 'green', 'yellow']\n *\n * console.log(colors.length) // 3\n * utils.noDupeAdd(colors, 'red')\n * console.log(colors.length) // 3, red already exists\n *\n * utils.noDupeAdd(colors, 'blue')\n * console.log(colors.length) // 4, blue was added\n *\n * @method utils.noDupeAdd\n * @param {Array} array The array.\n * @param {*} record The value to add.\n * @param {Function} fn Callback function passed to {@link utils.findIndex}.\n * @since 3.0.0\n */\n noDupeAdd (array, record, fn) {\n if (!array) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index < 0) {\n array.push(record)\n }\n },\n\n /**\n * Return a shallow copy of the provided object, minus the properties\n * specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.omit(a, ['$hashKey'])\n * console.log(b) // { name: 'John' }\n *\n * @method utils.omit\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to skip.\n * @returns {Object} Shallow copy of `props`, minus `keys`.\n * @since 3.0.0\n */\n omit (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) === -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a shallow copy of the provided object, but only include the\n * properties specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.pick(a, ['$hashKey'])\n * console.log(b) // { $hashKey: 1214910 }\n *\n * @method utils.pick\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to keep.\n * @returns {Object} Shallow copy of `props`, but only including `keys`.\n * @since 3.0.0\n */\n pick (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) !== -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a plain copy of the given value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John' }\n * let b = utils.plainCopy(a)\n * console.log(a === b) // false\n *\n * @method utils.plainCopy\n * @param {*} value The value to copy.\n * @returns {*} Plain copy of `value`.\n * @see utils.copy\n * @since 3.0.0\n */\n plainCopy (value) {\n return utils.copy(value, undefined, undefined, undefined, undefined, true)\n },\n\n /**\n * Shortcut for `utils.Promise.reject(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.reject(\"Testing static reject\").then(function(data) {\n * // not called\n * }).catch(function(reason) {\n * console.log(reason); // \"Testing static reject\"\n * })\n *\n * @method utils.reject\n * @param {*} [value] Value with which to reject the Promise.\n * @returns {Promise} Promise reject with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n reject (value) {\n return utils.Promise.reject(value)\n },\n\n /**\n * Remove the last item found in array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const colors = ['red', 'green', 'yellow', 'red']\n * utils.remove(colors, (color) => color === 'red')\n * console.log(colors) // ['red', 'green', 'yellow']\n *\n * @method utils.remove\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n */\n remove (array, fn) {\n if (!array || !array.length) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index >= 0) {\n array.splice(index, 1) // todo should this be recursive?\n }\n },\n\n /**\n * Shortcut for `utils.Promise.resolve(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.resolve(\"Testing static resolve\").then(function(data) {\n * console.log(data); // \"Testing static resolve\"\n * }).catch(function(reason) {\n * // not called\n * })\n *\n * @param {*} [value] Value with which to resolve the Promise.\n * @returns {Promise} Promise resolved with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n resolve (value) {\n return utils.Promise.resolve(value)\n },\n\n /**\n * Set the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n * // set value by key\n * utils.set(john, 'id', 98)\n * console.log(john.id) // 98\n *\n * // set value by path\n * utils.set(john, 'parent.id', 20)\n * console.log(john.parent.id) // 20\n *\n * // set value by path/value map\n * utils.set(john, {\n * 'id': 1098,\n * 'parent': { id: 1020 },\n * 'parent.age': '55'\n * })\n * console.log(john.id) // 1098\n * console.log(john.parent.id) // 1020\n * console.log(john.parent.age) // 55\n *\n * @method utils.set\n * @param {Object} object The object on which to set a property.\n * @param {(string|Object)} path The key or path to the property. Can also\n * pass in an object of path/value pairs, which will all be set on the target\n * object.\n * @param {*} [value] The value to set.\n */\n set: function (object, path, value) {\n if (utils.isObject(path)) {\n utils.forOwn(path, function (value, _path) {\n utils.set(object, _path, value)\n })\n } else {\n const parts = PATH.exec(path)\n if (parts) {\n mkdirP(object, parts[1])[parts[2]] = value\n } else {\n object[path] = value\n }\n }\n },\n\n /**\n * Check whether the two provided objects are deeply equal.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const objA = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * const objB = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * console.log(utils.deepEqual(a,b)) // true\n * objB.nested.colors.add('yellow') // make a change to a nested object's array\n * console.log(utils.deepEqual(a,b)) // false\n *\n * @method utils.deepEqual\n * @param {Object} a First object in the comparison.\n * @param {Object} b Second object in the comparison.\n * @returns {boolean} Whether the two provided objects are deeply equal.\n * @see utils.equal\n * @since 3.0.0\n */\n deepEqual (a, b) {\n if (a === b) {\n return true\n }\n let _equal = true\n if (utils.isObject(a) && utils.isObject(b)) {\n utils.forOwn(a, function (value, key) {\n _equal = _equal && utils.deepEqual(value, b[key])\n })\n if (!_equal) {\n return _equal\n }\n utils.forOwn(b, function (value, key) {\n _equal = _equal && utils.deepEqual(value, a[key])\n })\n } else if (utils.isArray(a) && utils.isArray(b)) {\n a.forEach(function (value, i) {\n _equal = _equal && utils.deepEqual(value, b[i])\n if (!_equal) {\n return false\n }\n })\n } else {\n return false\n }\n return _equal\n },\n\n /**\n * Proxy for `JSON.stringify`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = { name: 'John' }\n * let jsonVal = utils.toJson(a)\n * console.log(jsonVal) // '{\"name\" : \"John\"}'\n *\n * @method utils.toJson\n * @param {*} value Value to serialize to JSON.\n * @returns {string} JSON string.\n * @see utils.fromJson\n * @since 3.0.0\n */\n toJson: JSON.stringify,\n\n /**\n * Unset the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n *\n * utils.unset(john, age)\n * utils.unset(john, parent.age)\n *\n * console.log(john.age) // null\n * console.log(john.parent.age) // null\n *\n * @method utils.unset\n * @param {Object} object The object from which to delete the property.\n * @param {string} path The key or path to the property.\n * @see utils.set\n * @since 3.0.0\n */\n unset (object, path) {\n const parts = path.split('.')\n const last = parts.pop()\n\n while (path = parts.shift()) { // eslint-disable-line\n object = object[path]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n object[last] = undefined\n }\n}\n\nexport default utils\n","import utils from './utils'\n\n/**\n * A base class which gives instances private properties.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Settable.extend} for an example of using {@link Settable} as a\n * base class.\n *\n *```javascript\n * import {Settable} from 'js-data'\n * ```\n *\n * @class Settable\n * @returns {Settable} A new {@link Settable} instance.\n * @since 3.0.0\n */\nexport default function Settable () {\n const _props = {}\n Object.defineProperties(this, {\n /**\n * Get a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method Settable#_get\n * @param {string} key The property to retrieve.\n * @returns {*} The value of the property.\n * @since 3.0.0\n */\n _get: { value (key) { return utils.get(_props, key) } },\n\n /**\n * Set a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_set\n * @param {(string|Object)} key The key or path to the property. Can also\n * pass in an object of key/value pairs, which will all be set on the instance.\n * @param {*} [value] The value to set.\n * @since 3.0.0\n */\n _set: { value (key, value) { return utils.set(_props, key, value) } },\n\n /**\n * Unset a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_unset\n * @param {string} key The property to unset.\n * @since 3.0.0\n */\n _unset: { value (key) { return utils.unset(_props, key) } }\n })\n}\n\n/**\n * Create a subclass of this Settable:\n *\n * @example Settable.extend\n * // Normally you would do: import {Settable} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Settable} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSettableClass extends Settable {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSettable = new CustomSettableClass()\n * console.log(customSettable.foo())\n * console.log(CustomSettableClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSettableClass = Settable.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSettable = new OtherSettableClass()\n * console.log(otherSettable.foo())\n * console.log(OtherSettableClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSettableClass () {\n * Settable.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Settable.extend({\n * constructor: AnotherSettableClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSettable = new AnotherSettableClass()\n * console.log(anotherSettable.created_at)\n * console.log(anotherSettable.foo())\n * console.log(AnotherSettableClass.beep())\n *\n * @method Settable.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Settable class.\n * @since 3.0.0\n */\nSettable.extend = utils.extend\n","import utils from './utils'\nimport Settable from './Settable'\n\n/**\n * The base class from which all JSData components inherit some basic\n * functionality.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Component.extend} for an example of using {@link Component} as a\n * base class.\n *\n *```javascript\n * import {Component} from 'js-data'\n * ```\n *\n * @class Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @returns {Component} A new {@link Component} instance.\n * @since 3.0.0\n */\nfunction Component (opts) {\n Settable.call(this)\n opts || (opts = {})\n\n /**\n * Whether to enable debug-level logs for this component. Anything that\n * extends `Component` inherits this option and the corresponding logging\n * functionality.\n *\n * @example Component#debug\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const component = new Component()\n * component.log('debug', 'some message') // nothing gets logged\n * // Display debug logs:\n * component.debug = true\n * component.log('debug', 'other message') // this DOES get logged\n *\n * @default false\n * @name Component#debug\n * @since 3.0.0\n * @type {boolean}\n */\n this.debug = opts.hasOwnProperty('debug') ? !!opts.debug : false\n\n /**\n * Event listeners attached to this Component. __Do not modify.__ Use\n * {@link Component#on} and {@link Component#off} instead.\n *\n * @name Component#_listeners\n * @instance\n * @since 3.0.0\n * @type {Object}\n */\n Object.defineProperty(this, '_listeners', { value: {}, writable: true })\n}\n\nexport default Settable.extend({\n constructor: Component\n})\n\n/**\n * Create a subclass of this Component:\n *\n * @example Component.extend\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomComponentClass extends Component {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customComponent = new CustomComponentClass()\n * console.log(customComponent.foo())\n * console.log(CustomComponentClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherComponentClass = Component.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherComponent = new OtherComponentClass()\n * console.log(otherComponent.foo())\n * console.log(OtherComponentClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherComponentClass () {\n * Component.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Component.extend({\n * constructor: AnotherComponentClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherComponent = new AnotherComponentClass()\n * console.log(anotherComponent.created_at)\n * console.log(anotherComponent.foo())\n * console.log(AnotherComponentClass.beep())\n *\n * @method Component.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Component class.\n * @since 3.0.0\n */\nComponent.extend = utils.extend\n\n/**\n * Log the provided values at the \"debug\" level. Debug-level logs are only\n * logged if {@link Component#debug} is `true`.\n *\n * `.dbg(...)` is shorthand for `.log('debug', ...)`.\n *\n * @method Component#dbg\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\n/**\n * Log the provided values. By default sends values to `console[level]`.\n * Debug-level logs are only logged if {@link Component#debug} is `true`.\n *\n * Will attempt to use appropriate `console` methods if they are available.\n *\n * @method Component#log\n * @param {string} level Log level.\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\nutils.logify(Component.prototype)\n\n/**\n * Register a new event listener on this Component.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * collection.on('add', (records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * post.on('change', (record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method Component#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n/**\n * Remove an event listener from this Component. If no listener is provided,\n * then all listeners for the specified event will be removed. If no event is\n * specified then all listeners for all events will be removed.\n *\n * @example\n * // Remove a particular listener for a particular event\n * collection.off('add', handler)\n *\n * @example\n * // Remove all listeners for a particular event\n * record.off('change')\n *\n * @example\n * // Remove all listeners to all events\n * store.off()\n *\n * @method Component#off\n * @param {string} [event] Name of event to unsubsribe to.\n * @param {Function} [listener] Listener to remove.\n * @since 3.0.0\n */\n/**\n * Trigger an event on this Component.\n *\n * @example Component#emit\n * // import {Collection, DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, DataStore} = JSData\n *\n * const collection = new Collection()\n * collection.on('foo', function (msg) {\n * console.log(msg)\n * })\n * collection.emit('foo', 'bar')\n *\n * const store = new DataStore()\n * store.on('beep', function (msg) {\n * console.log(msg)\n * })\n * store.emit('beep', 'boop')\n *\n * @method Component#emit\n * @param {string} event Name of event to emit.\n * @param {...*} [args] Arguments to pass to any listeners.\n * @since 3.0.0\n */\nutils.eventify(\n Component.prototype,\n function () {\n return this._listeners\n },\n function (value) {\n this._listeners = value\n }\n)\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Query'\nconst INDEX_ERR = 'Index inaccessible after first operation'\n\n// Reserved words used by JSData's Query Syntax\nconst reserved = {\n limit: '',\n offset: '',\n orderBy: '',\n skip: '',\n sort: '',\n where: ''\n}\n\n// Used by our JavaScript implementation of the LIKE operator\nconst escapeRegExp = /([.*+?^=!:${}()|[\\]\\/\\\\])/g\nconst percentRegExp = /%/g\nconst underscoreRegExp = /_/g\nconst escape = function (pattern) {\n return pattern.replace(escapeRegExp, '\\\\$1')\n}\n\n/**\n * A class used by the {@link Collection} class to build queries to be executed\n * against the collection's data. An instance of `Query` is returned by\n * {@link Collection#query}. Query instances are typically short-lived, and you\n * shouldn't have to create them yourself. Just use {@link Collection#query}.\n *\n * ```javascript\n * import {Query} from 'js-data'\n * ```\n *\n * @example\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const drafts = store.query('post').filter({ status: 'draft' }).limit(2).run()\n * console.log(drafts)\n *\n * @class Query\n * @extends Component\n * @param {Collection} collection The collection on which this query operates.\n * @since 3.0.0\n */\nfunction Query (collection) {\n utils.classCallCheck(this, Query)\n\n /**\n * The {@link Collection} on which this query operates.\n *\n * @name Query#collection\n * @since 3.0.0\n * @type {Collection}\n */\n this.collection = collection\n\n /**\n * The current data result of this query.\n *\n * @name Query#data\n * @since 3.0.0\n * @type {Array}\n */\n this.data = null\n}\n\nexport default Component.extend({\n constructor: Query,\n\n _applyWhereFromObject (where) {\n const fields = []\n const ops = []\n const predicates = []\n utils.forOwn(where, (clause, field) => {\n if (!utils.isObject(clause)) {\n clause = {\n '==': clause\n }\n }\n utils.forOwn(clause, (expr, op) => {\n fields.push(field)\n ops.push(op)\n predicates.push(expr)\n })\n })\n return {\n fields,\n ops,\n predicates\n }\n },\n\n _applyWhereFromArray (where) {\n const groups = []\n where.forEach((_where, i) => {\n if (utils.isString(_where)) {\n return\n }\n const prev = where[i - 1]\n const parser = utils.isArray(_where) ? this._applyWhereFromArray : this._applyWhereFromObject\n const group = parser.call(this, _where)\n if (prev === 'or') {\n group.isOr = true\n }\n groups.push(group)\n })\n groups.isArray = true\n return groups\n },\n\n _testObjectGroup (keep, first, group, item) {\n let i\n const fields = group.fields\n const ops = group.ops\n const predicates = group.predicates\n const len = ops.length\n for (i = 0; i < len; i++) {\n let op = ops[i]\n const isOr = op.charAt(0) === '|'\n op = isOr ? op.substr(1) : op\n const expr = this.evaluate(utils.get(item, fields[i]), op, predicates[i])\n if (expr !== undefined) {\n keep = first ? expr : (isOr ? keep || expr : keep && expr)\n }\n first = false\n }\n return { keep, first }\n },\n\n _testArrayGroup (keep, first, groups, item) {\n let i\n const len = groups.length\n for (i = 0; i < len; i++) {\n const group = groups[i]\n const parser = group.isArray ? this._testArrayGroup : this._testObjectGroup\n const result = parser.call(this, true, true, group, item)\n if (groups[i - 1]) {\n if (group.isOr) {\n keep = keep || result.keep\n } else {\n keep = keep && result.keep\n }\n } else {\n keep = result.keep\n }\n first = result.first\n }\n return { keep, first }\n },\n\n /**\n * Find all entities between two boundaries.\n *\n * @example Get the users ages 18 to 30.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between(18, 30, { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @example Same as above.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between([18], [30], { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @method Query#between\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#between`)(500, 'Cannot access index')\n }\n this.data = this.collection.getIndex(opts.index).between(leftKeys, rightKeys, opts)\n return this\n },\n\n /**\n * The comparison function used by the {@link Query} class.\n *\n * @method Query#compare\n * @param {Array} orderBy An orderBy clause used for sorting and sub-sorting.\n * @param {number} index The index of the current orderBy clause being used.\n * @param {*} a The first item in the comparison.\n * @param {*} b The second item in the comparison.\n * @returns {number} -1 if `b` should preceed `a`. 0 if `a` and `b` are equal.\n * 1 if `a` should preceed `b`.\n * @since 3.0.0\n */\n compare (orderBy, index, a, b) {\n const def = orderBy[index]\n let cA = utils.get(a, def[0])\n let cB = utils.get(b, def[0])\n if (cA && utils.isString(cA)) {\n cA = cA.toUpperCase()\n }\n if (cB && utils.isString(cB)) {\n cB = cB.toUpperCase()\n }\n if (a === undefined) {\n a = null\n }\n if (b === undefined) {\n b = null\n }\n if (def[1].toUpperCase() === 'DESC') {\n const temp = cB\n cB = cA\n cA = temp\n }\n if (cA < cB) {\n return -1\n } else if (cA > cB) {\n return 1\n } else {\n if (index < orderBy.length - 1) {\n return this.compare(orderBy, index + 1, a, b)\n } else {\n return 0\n }\n }\n },\n\n /**\n * Predicate evaluation function used by the {@link Query} class.\n *\n * @method Query#evaluate\n * @param {*} value The value to evaluate.\n * @param {string} op The operator to use in this evaluation.\n * @param {*} predicate The predicate to use in this evaluation.\n * @returns {boolean} Whether the value passed the evaluation or not.\n * @since 3.0.0\n */\n evaluate (value, op, predicate) {\n const ops = this.constructor.ops\n if (ops[op]) {\n return ops[op](value, predicate)\n }\n if (op.indexOf('like') === 0) {\n return this.like(predicate, op.substr(4)).exec(value) !== null\n } else if (op.indexOf('notLike') === 0) {\n return this.like(predicate, op.substr(7)).exec(value) === null\n }\n },\n\n /**\n * Find the record or records that match the provided query or are accepted by\n * the provided filter function.\n *\n * @example Get the draft posts by authors younger than 30\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * let results = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * age: {\n * '<': 30\n * }\n * }\n * }).run()\n * console.log(results)\n *\n * @example Use a custom filter function\n * const posts = query.filter(function (post) {\n * return post.isReady()\n * }).run()\n *\n * @method Query#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Function} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n filter (query, thisArg) {\n /**\n * Selection query as defined by JSData's [Query Syntax][querysyntax].\n *\n * [querysyntax]: http://www.js-data.io/v3.0/docs/query-syntax\n *\n * @example Empty \"findAll\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * store.findAll('post').then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @example Empty \"filter\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = store.filter('post')\n * console.log(posts) // [...]\n *\n * @example Complex \"filter\" query\n * const PAGE_SIZE = 2\n * let currentPage = 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * // Retrieve a filtered page of blog posts\n * // Would typically replace filter with findAll\n * store.filter('post', {\n * where: {\n * status: {\n * // WHERE status = 'published'\n * '==': 'published'\n * },\n * author: {\n * // AND author IN ('bob', 'alice')\n * 'in': ['bob', 'alice'],\n * // OR author IN ('karen')\n * '|in': ['karen']\n * }\n * },\n * orderBy: [\n * // ORDER BY date_published DESC,\n * ['date_published', 'DESC'],\n * // ORDER BY title ASC\n * ['title', 'ASC']\n * ],\n * // LIMIT 2\n * limit: PAGE_SIZE,\n * // SKIP 4\n * offset: PAGE_SIZE * (currentPage - 1)\n * })\n *\n * @namespace query\n * @property {number} [limit] See {@link query.limit}.\n * @property {number} [offset] See {@link query.offset}.\n * @property {string|Array[]} [orderBy] See {@link query.orderBy}.\n * @property {number} [skip] Alias for {@link query.offset}.\n * @property {string|Array[]} [sort] Alias for {@link query.orderBy}.\n * @property {Object} [where] See {@link query.where}.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/query-syntax\",\"JSData's Query Syntax\"]\n */\n query || (query = {})\n this.getData()\n if (utils.isObject(query)) {\n let where = {}\n\n /**\n * Filtering criteria. Records that do not meet this criteria will be exluded\n * from the result.\n *\n * @example Return posts where author is at least 32 years old\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * where: {\n * age: {\n * '>=': 30\n * }\n * }\n * })\n * console.log(results)\n *\n * @name query.where\n * @type {Object}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isObject(query.where) || utils.isArray(query.where)) {\n where = query.where\n }\n utils.forOwn(query, function (value, key) {\n if (!(key in reserved) && !(key in where)) {\n where[key] = {\n '==': value\n }\n }\n })\n let groups\n\n // Apply filter for each field\n if (utils.isObject(where) && Object.keys(where).length !== 0) {\n groups = this._applyWhereFromArray([where])\n } else if (utils.isArray(where)) {\n groups = this._applyWhereFromArray(where)\n }\n\n if (groups) {\n this.data = this.data.filter((item, i) => this._testArrayGroup(true, true, groups, item).keep)\n }\n\n // Sort\n let orderBy = query.orderBy || query.sort\n\n if (utils.isString(orderBy)) {\n orderBy = [\n [orderBy, 'ASC']\n ]\n }\n if (!utils.isArray(orderBy)) {\n orderBy = null\n }\n\n /**\n * Determines how records should be ordered in the result.\n *\n * @example Order posts by `author` then by `id` descending \n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * orderBy:[['author','ASC'],['id','DESC']]\n * })\n * console.log(results)\n *\n * @name query.orderBy\n * @type {string|Array[]}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (orderBy) {\n let index = 0\n orderBy.forEach(function (def, i) {\n if (utils.isString(def)) {\n orderBy[i] = [def, 'ASC']\n }\n })\n this.data.sort((a, b) => this.compare(orderBy, index, a, b))\n }\n\n /**\n * Number of records to skip.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n *\n * @name query.offset\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.skip)) {\n this.skip(query.skip)\n } else if (utils.isNumber(query.offset)) {\n this.skip(query.offset)\n }\n\n /**\n * Maximum number of records to retrieve.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n * @name query.limit\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.limit)) {\n this.limit(query.limit)\n }\n } else if (utils.isFunction(query)) {\n this.data = this.data.filter(query, thisArg)\n }\n return this\n },\n\n /**\n * Iterate over all entities.\n *\n * @method Query#forEach\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n forEach (forEachFn, thisArg) {\n this.getData().forEach(forEachFn, thisArg)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided key.\n *\n * @example Get the entity whose primary key is 25.\n * const entities = query.get(25).run()\n *\n * @example Same as above.\n * const entities = query.get([25]).run()\n *\n * @example Get all users who are active and have the \"admin\" role.\n * const activeAdmins = query.get(['active', 'admin'], {\n * index: 'activityAndRoles'\n * }).run()\n *\n * @example Get all entities that match a certain weather condition.\n * const niceDays = query.get(['sunny', 'humid', 'calm'], {\n * index: 'weatherConditions'\n * }).run()\n *\n * @method Query#get\n * @param {Array} keyList Key(s) defining the entity to retrieve. If\n * `keyList` is not an array (i.e. for a single-value key), it will be\n * wrapped in an array.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.string] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n get (keyList, opts) {\n keyList || (keyList = [])\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#get`)(500, INDEX_ERR)\n }\n if (keyList && !utils.isArray(keyList)) {\n keyList = [keyList]\n }\n if (!keyList.length) {\n this.getData()\n return this\n }\n this.data = this.collection.getIndex(opts.index).get(keyList)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided keyLists.\n *\n * @example Get the posts where \"status\" is \"draft\" or \"inReview\".\n * const posts = query.getAll('draft', 'inReview', { index: 'status' }).run()\n *\n * @example Same as above.\n * const posts = query.getAll(['draft'], ['inReview'], { index: 'status' }).run()\n *\n * @method Query#getAll\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * entities matching each keyList will be retrieved. If no keyLists are\n * provided, all entities will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n getAll (...args) {\n let opts = {}\n if (this.data) {\n throw utils.err(`${DOMAIN}#getAll`)(500, INDEX_ERR)\n }\n if (!args.length || args.length === 1 && utils.isObject(args[0])) {\n this.getData()\n return this\n } else if (args.length && utils.isObject(args[args.length - 1])) {\n opts = args[args.length - 1]\n args.pop()\n }\n const collection = this.collection\n const index = collection.getIndex(opts.index)\n this.data = []\n args.forEach((keyList) => {\n this.data = this.data.concat(index.get(keyList))\n })\n return this\n },\n\n /**\n * Return the current data result of this query.\n *\n * @method Query#getData\n * @returns {Array} The data in this query.\n * @since 3.0.0\n */\n getData () {\n if (!this.data) {\n this.data = this.collection.index.getAll()\n }\n return this.data\n },\n\n /**\n * Implementation used by the `like` operator. Takes a pattern and flags and\n * returns a `RegExp` instance that can test strings.\n *\n * @method Query#like\n * @param {string} pattern Testing pattern.\n * @param {string} flags Flags for the regular expression.\n * @returns {RegExp} Regular expression for testing strings.\n * @since 3.0.0\n */\n like (pattern, flags) {\n return new RegExp(`^${(escape(pattern).replace(percentRegExp, '.*').replace(underscoreRegExp, '.'))}$`, flags)\n },\n\n /**\n * Limit the result.\n *\n * @example Get only the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').limit(2).run()\n * console.log(results)\n *\n * @method Query#limit\n * @param {number} num The maximum number of entities to keep in the result.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n limit (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#limit`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n this.data = data.slice(0, Math.min(data.length, num))\n return this\n },\n\n /**\n * Apply a mapping function to the result data.\n *\n * @example\n * // Return the age of all users\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const ages = store.query('user').map((user) => {\n * return user.age\n * }).run()\n * console.log(ages)\n *\n * @method Query#map\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n map (mapFn, thisArg) {\n this.data = this.getData().map(mapFn, thisArg)\n return this\n },\n\n /**\n * Return the result of calling the specified function on each item in this\n * collection's main index.\n *\n * @example\n * const stringAges = UserCollection.query().mapCall('toString').run()\n *\n * @method Query#mapCall\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n mapCall (funcName, ...args) {\n this.data = this.getData().map(function (item) {\n return item[funcName](...args)\n })\n return this\n },\n\n /**\n * Complete the execution of the query and return the resulting data.\n *\n * @method Query#run\n * @returns {Array} The result of executing this query.\n * @since 3.0.0\n */\n run () {\n const data = this.data\n this.data = null\n return data\n },\n\n /**\n * Skip a number of results.\n *\n * @example Get all but the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').skip(2).run()\n * console.log(results)\n *\n * @method Query#skip\n * @param {number} num The number of entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n skip (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#skip`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n if (num < data.length) {\n this.data = data.slice(num)\n } else {\n this.data = []\n }\n return this\n }\n}, {\n /**\n * The filtering operators supported by {@link Query#filter}, and which are\n * implemented by adapters (for the most part).\n *\n * @example Variant 1\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * status: 'published',\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n *\n * @example Variant 2\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * }\n * },\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n * @example Variant 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * status: 'published'\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Variant 4\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'published'\n * }\n * }\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Multiple operators\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const myPublishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * },\n * user_id: {\n * '==': currentUser.id\n * }\n * }\n * })\n *\n * console.log(myPublishedPosts)\n *\n * @name Query.ops\n * @property {Function} == Equality operator.\n * @property {Function} != Inequality operator.\n * @property {Function} > Greater than operator.\n * @property {Function} >= Greater than (inclusive) operator.\n * @property {Function} < Less than operator.\n * @property {Function} <= Less than (inclusive) operator.\n * @property {Function} isectEmpty Operator that asserts that the intersection\n * between two arrays is empty.\n * @property {Function} isectNotEmpty Operator that asserts that the\n * intersection between two arrays is __not__ empty.\n * @property {Function} in Operator that asserts whether a value is in an\n * array.\n * @property {Function} notIn Operator that asserts whether a value is __not__\n * in an array.\n * @property {Function} contains Operator that asserts whether an array\n * contains a value.\n * @property {Function} notContains Operator that asserts whether an array\n * does __not__ contain a value.\n * @since 3.0.0\n * @type {Object}\n */\n ops: {\n '=': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '==': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '===': function (value, predicate) {\n return value === predicate\n },\n '!=': function (value, predicate) {\n return value != predicate // eslint-disable-line\n },\n '!==': function (value, predicate) {\n return value !== predicate\n },\n '>': function (value, predicate) {\n return value > predicate\n },\n '>=': function (value, predicate) {\n return value >= predicate\n },\n '<': function (value, predicate) {\n return value < predicate\n },\n '<=': function (value, predicate) {\n return value <= predicate\n },\n 'isectEmpty': function (value, predicate) {\n return !utils.intersection((value || []), (predicate || [])).length\n },\n 'isectNotEmpty': function (value, predicate) {\n return utils.intersection((value || []), (predicate || [])).length\n },\n 'in': function (value, predicate) {\n return predicate.indexOf(value) !== -1\n },\n 'notIn': function (value, predicate) {\n return predicate.indexOf(value) === -1\n },\n 'contains': function (value, predicate) {\n return (value || []).indexOf(predicate) !== -1\n },\n 'notContains': function (value, predicate) {\n return (value || []).indexOf(predicate) === -1\n }\n }\n})\n\n/**\n * Create a subclass of this Query:\n * @example Query.extend\n * // Normally you would do: import {Query} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Query} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomQueryClass extends Query {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customQuery = new CustomQueryClass()\n * console.log(customQuery.foo())\n * console.log(CustomQueryClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherQueryClass = Query.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherQuery = new OtherQueryClass()\n * console.log(otherQuery.foo())\n * console.log(OtherQueryClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherQueryClass (collection) {\n * Query.call(this, collection)\n * this.created_at = new Date().getTime()\n * }\n * Query.extend({\n * constructor: AnotherQueryClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherQuery = new AnotherQueryClass()\n * console.log(anotherQuery.created_at)\n * console.log(anotherQuery.foo())\n * console.log(AnotherQueryClass.beep())\n *\n * @method Query.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Query class.\n * @since 3.0.0\n */\n","export function sort (a, b, hashCode) {\n // Short-circuit comparison if a and b are strictly equal\n // This is absolutely necessary for indexed objects that\n // don't have the idAttribute field\n if (a === b) {\n return 0\n }\n if (hashCode) {\n a = hashCode(a)\n b = hashCode(b)\n }\n if ((a === null && b === null) || (a === undefined && b === undefined)) {\n return -1\n }\n\n if (a === null || a === undefined) {\n return -1\n }\n\n if (b === null || b === undefined) {\n return 1\n }\n\n if (a < b) {\n return -1\n }\n\n if (a > b) {\n return 1\n }\n\n return 0\n}\n\nexport function insertAt (array, index, value) {\n array.splice(index, 0, value)\n return array\n}\n\nexport function removeAt (array, index) {\n array.splice(index, 1)\n return array\n}\n\nexport function binarySearch (array, value, field) {\n let lo = 0\n let hi = array.length\n let compared\n let mid\n\n while (lo < hi) {\n mid = ((lo + hi) / 2) | 0\n compared = sort(value, array[mid], field)\n if (compared === 0) {\n return {\n found: true,\n index: mid\n }\n } else if (compared < 0) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n\n return {\n found: false,\n index: hi\n }\n}\n","// Copyright (c) 2015, InternalFX.\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose with or\n// without fee is hereby granted, provided that the above copyright notice and this permission\n// notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO\n// THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT\n// SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR\n// ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE\n// USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// Modifications\n// Copyright 2015-2016 Jason Dobry\n//\n// Summary of modifications:\n// Reworked dependencies so as to re-use code already in js-data\n// Removed unused code\nimport utils from '../../src/utils'\nimport {binarySearch, insertAt, removeAt} from './_utils'\n\nexport default function Index (fieldList, opts) {\n utils.classCallCheck(this, Index)\n fieldList || (fieldList = [])\n\n if (!utils.isArray(fieldList)) {\n throw new Error('fieldList must be an array.')\n }\n\n opts || (opts = {})\n this.fieldList = fieldList\n this.fieldGetter = opts.fieldGetter\n this.hashCode = opts.hashCode\n this.isIndex = true\n this.keys = []\n this.values = []\n}\n\nutils.addHiddenPropsToTarget(Index.prototype, {\n 'set' (keyList, value) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n let dataLocation = binarySearch(this.values[pos.index], value, this.hashCode)\n if (!dataLocation.found) {\n insertAt(this.values[pos.index], dataLocation.index, value)\n }\n } else {\n insertAt(this.keys, pos.index, key)\n insertAt(this.values, pos.index, [value])\n }\n } else {\n if (pos.found) {\n this.values[pos.index].set(keyList, value)\n } else {\n insertAt(this.keys, pos.index, key)\n let newIndex = new Index([], { hashCode: this.hashCode })\n newIndex.set(keyList, value)\n insertAt(this.values, pos.index, newIndex)\n }\n }\n },\n\n 'get' (keyList) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n if (this.values[pos.index].isIndex) {\n return this.values[pos.index].getAll()\n } else {\n return this.values[pos.index].slice()\n }\n } else {\n return []\n }\n } else {\n if (pos.found) {\n return this.values[pos.index].get(keyList)\n } else {\n return []\n }\n }\n },\n\n getAll (opts) {\n opts || (opts = {})\n let results = []\n const values = this.values\n if (opts.order === 'desc') {\n for (let i = values.length - 1; i >= 0; i--) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n } else {\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n }\n return results\n },\n\n visitAll (cb, thisArg) {\n this.values.forEach(function (value) {\n if (value.isIndex) {\n value.visitAll(cb, thisArg)\n } else {\n value.forEach(cb, thisArg)\n }\n })\n },\n\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (!utils.isArray(leftKeys)) {\n leftKeys = [leftKeys]\n }\n if (!utils.isArray(rightKeys)) {\n rightKeys = [rightKeys]\n }\n utils.fillIn(opts, {\n leftInclusive: true,\n rightInclusive: false,\n limit: undefined,\n offset: 0\n })\n\n let results = this._between(leftKeys, rightKeys, opts)\n\n if (opts.limit) {\n return results.slice(opts.offset, opts.limit + opts.offset)\n } else {\n return results.slice(opts.offset)\n }\n },\n\n _between (leftKeys, rightKeys, opts) {\n let results = []\n\n let leftKey = leftKeys.shift()\n let rightKey = rightKeys.shift()\n\n let pos\n\n if (leftKey !== undefined) {\n pos = binarySearch(this.keys, leftKey)\n } else {\n pos = {\n found: false,\n index: 0\n }\n }\n\n if (leftKeys.length === 0) {\n if (pos.found && opts.leftInclusive === false) {\n pos.index += 1\n }\n\n for (let i = pos.index; i < this.keys.length; i += 1) {\n if (rightKey !== undefined) {\n if (opts.rightInclusive) {\n if (this.keys[i] > rightKey) { break }\n } else {\n if (this.keys[i] >= rightKey) { break }\n }\n }\n\n if (this.values[i].isIndex) {\n results = results.concat(this.values[i].getAll())\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n } else {\n for (let i = pos.index; i < this.keys.length; i += 1) {\n let currKey = this.keys[i]\n if (currKey > rightKey) { break }\n\n if (this.values[i].isIndex) {\n if (currKey === leftKey) {\n results = results.concat(this.values[i]._between(utils.copy(leftKeys), rightKeys.map(function () { return undefined }), opts))\n } else if (currKey === rightKey) {\n results = results.concat(this.values[i]._between(leftKeys.map(function () { return undefined }), utils.copy(rightKeys), opts))\n } else {\n results = results.concat(this.values[i].getAll())\n }\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n }\n\n if (opts.limit) {\n return results.slice(0, opts.limit + opts.offset)\n } else {\n return results\n }\n },\n\n peek () {\n if (this.values.length) {\n if (this.values[0].isIndex) {\n return this.values[0].peek()\n } else {\n return this.values[0]\n }\n }\n return []\n },\n\n clear () {\n this.keys = []\n this.values = []\n },\n\n insertRecord (data) {\n let keyList = this.fieldList.map(function (field) {\n if (utils.isFunction(field)) {\n return field(data) || undefined\n } else {\n return data[field] || undefined\n }\n })\n this.set(keyList, data)\n },\n\n removeRecord (data) {\n let removed\n const isUnique = this.hashCode(data) !== undefined\n this.values.forEach((value, i) => {\n if (value.isIndex) {\n if (value.removeRecord(data)) {\n if (value.keys.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n } else {\n let dataLocation = {}\n if (this.keys[i] === undefined || !isUnique) {\n for (let j = value.length - 1; j >= 0; j--) {\n if (value[j] === data) {\n dataLocation = {\n found: true,\n index: j\n }\n break\n }\n }\n } else if (isUnique) {\n dataLocation = binarySearch(value, data, this.hashCode)\n }\n if (dataLocation.found) {\n removeAt(value, dataLocation.index)\n if (value.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n }\n })\n return removed ? data : undefined\n },\n\n updateRecord (data) {\n const removed = this.removeRecord(data)\n if (removed !== undefined) {\n this.insertRecord(data)\n }\n }\n})\n","import utils from './utils'\nimport Component from './Component'\nimport Query from './Query'\nimport Index from '../lib/mindex/index'\n\nconst DOMAIN = 'Collection'\n\nconst COLLECTION_DEFAULTS = {\n /**\n * Whether to call {@link Record#commit} on records that are added to the\n * collection and already exist in the collection.\n *\n * @name Collection#commitOnMerge\n * @type {boolean}\n * @default true\n */\n commitOnMerge: true,\n\n /**\n * Field to be used as the unique identifier for records in this collection.\n * Defaults to `\"id\"` unless {@link Collection#mapper} is set, in which case\n * this will default to {@link Mapper#idAttribute}.\n *\n * @name Collection#idAttribute\n * @type {string}\n * @default \"id\"\n */\n idAttribute: 'id',\n\n /**\n * What to do when inserting a record into this Collection that shares a\n * primary key with a record already in this Collection.\n *\n * Possible values:\n * merge\n * replace\n *\n * Merge:\n *\n * Recursively shallow copy properties from the new record onto the existing\n * record.\n *\n * Replace:\n *\n * Shallow copy top-level properties from the new record onto the existing\n * record. Any top-level own properties of the existing record that are _not_\n * on the new record will be removed.\n *\n * @name Collection#onConflict\n * @type {string}\n * @default \"merge\"\n */\n onConflict: 'merge'\n}\n\n/**\n * An ordered set of {@link Record} instances.\n *\n * @example Collection#constructor\n * // import {Collection, Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const user1 = new Record({ id: 1 })\n * const user2 = new Record({ id: 2 })\n * const UserCollection = new Collection([user1, user2])\n * console.log(UserCollection.get(1) === user1)\n *\n * @class Collection\n * @extends Component\n * @param {Array} [records] Initial set of records to insert into the\n * collection.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.commitOnMerge] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.idAttribute] See {@link Collection#idAttribute}.\n * @param {string} [opts.onConflict=\"merge\"] See {@link Collection#onConflict}.\n * @param {string} [opts.mapper] See {@link Collection#mapper}.\n * @since 3.0.0\n */\nfunction Collection (records, opts) {\n utils.classCallCheck(this, Collection)\n Component.call(this, opts)\n\n if (records && !utils.isArray(records)) {\n opts = records\n records = []\n }\n if (utils.isString(opts)) {\n opts = { idAttribute: opts }\n }\n\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * Default Mapper for this collection. Optional. If a Mapper is provided, then\n * the collection will use the {@link Mapper#idAttribute} setting, and will\n * wrap records in {@link Mapper#recordClass}.\n *\n * @example Collection#mapper\n * // Normally you would do: import {Collection, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const myMapper = new MyMapperClass({ name: 'myMapper' })\n * const collection = new Collection(null, { mapper: myMapper })\n *\n * @name Collection#mapper\n * @type {Mapper}\n * @default null\n * @since 3.0.0\n */\n mapper: {\n value: undefined,\n writable: true\n },\n // Query class used by this collection\n queryClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(COLLECTION_DEFAULTS))\n\n if (!this.queryClass) {\n this.queryClass = Query\n }\n\n const idAttribute = this.recordId()\n\n Object.defineProperties(this, {\n /**\n * The main index, which uses @{link Collection#recordId} as the key.\n *\n * @name Collection#index\n * @type {Index}\n */\n index: {\n value: new Index([idAttribute], {\n hashCode (obj) {\n return utils.get(obj, idAttribute)\n }\n })\n },\n\n /**\n * Object that holds the secondary indexes of this collection.\n *\n * @name Collection#indexes\n * @type {Object.}\n */\n indexes: {\n value: {}\n }\n })\n\n // Insert initial data into the collection\n if (utils.isObject(records) || (utils.isArray(records) && records.length)) {\n this.add(records)\n }\n}\n\nexport default Component.extend({\n constructor: Collection,\n\n /**\n * Used to bind to events emitted by records in this Collection.\n *\n * @method Collection#_onRecordEvent\n * @since 3.0.0\n * @private\n * @param {...*} [arg] Args passed to {@link Collection#emit}.\n */\n _onRecordEvent (...args) {\n this.emit(...args)\n },\n\n /**\n * Insert the provided record or records.\n *\n * If a record is already in the collection then the provided record will\n * either merge with or replace the existing record based on the value of the\n * `onConflict` option.\n *\n * The collection's secondary indexes will be updated as each record is\n * visited.\n *\n * @method Collection#add\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} data The record or records to insert.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.onConflict] See {@link Collection#onConflict}.\n * @returns {(Object|Object[]|Record|Record[])} The added record or records.\n */\n add (records, opts) {\n // Default values for arguments\n opts || (opts = {})\n\n // Fill in \"opts\" with the Collection's configuration\n utils._(opts, this)\n records = this.beforeAdd(records, opts) || records\n\n // Track whether just one record or an array of records is being inserted\n let singular = false\n const idAttribute = this.recordId()\n if (!utils.isArray(records)) {\n if (utils.isObject(records)) {\n records = [records]\n singular = true\n } else {\n throw utils.err(`${DOMAIN}#add`, 'records')(400, 'object or array', records)\n }\n }\n\n // Map the provided records to existing records.\n // New records will be inserted. If any records map to existing records,\n // they will be merged into the existing records according to the onConflict\n // option.\n records = records.map((record) => {\n let id = this.recordId(record)\n // Grab existing record if there is one\n const existing = id === undefined ? id : this.get(id)\n // If the currently visited record is just a reference to an existing\n // record, then there is nothing to be done. Exit early.\n if (record === existing) {\n return existing\n }\n\n if (existing) {\n // Here, the currently visited record corresponds to a record already\n // in the collection, so we need to merge them\n const onConflict = opts.onConflict || this.onConflict\n if (onConflict === 'merge') {\n utils.deepMixIn(existing, record)\n } else if (onConflict === 'replace') {\n utils.forOwn(existing, (value, key) => {\n if (key !== idAttribute && record[key] === undefined) {\n existing[key] = undefined\n }\n })\n existing.set(record)\n } else {\n throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)\n }\n record = existing\n if (opts.commitOnMerge && utils.isFunction(record.commit)) {\n record.commit()\n }\n // Update all indexes in the collection\n this.updateIndexes(record)\n } else {\n // Here, the currently visted record does not correspond to any record\n // in the collection, so (optionally) instantiate this record and insert\n // it into the collection\n record = this.mapper ? this.mapper.createRecord(record, opts) : record\n this.index.insertRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.insertRecord(record)\n })\n if (record && utils.isFunction(record.on)) {\n record.on('all', this._onRecordEvent, this)\n }\n }\n return record\n })\n // Finally, return the inserted data\n const result = singular ? records[0] : records\n this.emit('add', result)\n return this.afterAdd(records, opts, result) || result\n },\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then {@link Collection#add} will return that same value.\n *\n * @method Collection#method\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} result The record or records\n * that were added to this Collection by {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n afterAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}. If this method returns\n * a value then {@link Collection#remove} will return that same value.\n *\n * @method Collection#afterRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n * @param {Object} record The result that will be returned by {@link Collection#remove}.\n */\n afterRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}. If this method\n * returns a value then {@link Collection#removeAll} will return that same\n * value.\n *\n * @method Collection#afterRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n * @param {Object} records The result that will be returned by {@link Collection#removeAll}.\n */\n afterRemoveAll () {},\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then the `records` argument in {@link Collection#add} will be\n * re-assigned to the returned value.\n *\n * @method Collection#beforeAdd\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} records The `records` argument passed to {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n beforeAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}.\n *\n * @method Collection#beforeRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n */\n beforeRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}.\n *\n * @method Collection#beforeRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n */\n beforeRemoveAll () {},\n\n /**\n * Find all records between two boundaries.\n *\n * Shortcut for `collection.query().between(18, 30, { index: 'age' }).run()`\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = collection.between(18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = collection.between([18], [30], { index: 'age' })\n *\n * @method Collection#between\n * @since 3.0.0\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting records to skip.\n * @returns {Object[]|Record[]} The result.\n */\n between (leftKeys, rightKeys, opts) {\n return this.query().between(leftKeys, rightKeys, opts).run()\n },\n\n /**\n * Create a new secondary index on the contents of the collection.\n *\n * @example\n * // Index users by age\n * collection.createIndex('age')\n *\n * @example\n * // Index users by status and role\n * collection.createIndex('statusAndRole', ['status', 'role'])\n *\n * @method Collection#createIndex\n * @since 3.0.0\n * @param {string} name The name of the new secondary index.\n * @param {string[]} [fieldList] Array of field names to use as the key or\n * compound key of the new secondary index. If no fieldList is provided, then\n * the name will also be the field that is used to index the collection.\n */\n createIndex (name, fieldList, opts) {\n if (utils.isString(name) && fieldList === undefined) {\n fieldList = [name]\n }\n opts || (opts = {})\n opts.hashCode || (opts.hashCode = (obj) => this.recordId(obj))\n const index = this.indexes[name] = new Index(fieldList, opts)\n this.index.visitAll(index.insertRecord, index)\n },\n\n /**\n * Find the record or records that match the provided query or pass the\n * provided filter function.\n *\n * Shortcut for `collection.query().filter(queryOrFn[, thisArg]).run()`\n *\n * @example Collection#filter\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const collection = new Collection([\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = collection.filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = collection.filter(function (post) {\n * return post.id % 2 === 0\n * })\n *\n * @method Collection#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Object} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Array} The result.\n * @see query\n * @since 3.0.0\n */\n filter (query, thisArg) {\n return this.query().filter(query, thisArg).run()\n },\n\n /**\n * Iterate over all records.\n *\n * @example\n * collection.forEach(function (record) {\n * // do something\n * })\n *\n * @method Collection#forEach\n * @since 3.0.0\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Array} The result.\n */\n forEach (cb, thisArg) {\n this.index.visitAll(cb, thisArg)\n },\n\n /**\n * Get the record with the given id.\n *\n * @method Collection#get\n * @since 3.0.0\n * @param {(string|number)} id The primary key of the record to get.\n * @returns {(Object|Record)} The record with the given id.\n */\n get (id) {\n const instances = this.query().get(id).run()\n return instances.length ? instances[0] : undefined\n },\n\n /**\n * Find the record or records that match the provided keyLists.\n *\n * Shortcut for `collection.query().getAll(keyList1, keyList2, ...).run()`\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = collection.getAll('draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = collection.getAll(['draft'], ['inReview'], { index: 'status' })\n *\n * @method Collection#getAll\n * @since 3.0.0\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * records matching each keyList will be retrieved. If no keyLists are\n * provided, all records will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Array} The result.\n */\n getAll (...args) {\n return this.query().getAll(...args).run()\n },\n\n /**\n * Return the index with the given name. If no name is provided, return the\n * main index. Throws an error if the specified index does not exist.\n *\n * @method Collection#getIndex\n * @since 3.0.0\n * @param {string} [name] The name of the index to retrieve.\n */\n getIndex (name) {\n const index = name ? this.indexes[name] : this.index\n if (!index) {\n throw utils.err(`${DOMAIN}#getIndex`, name)(404, 'index')\n }\n return index\n },\n\n /**\n * Limit the result.\n *\n * Shortcut for `collection.query().limit(maximumNumber).run()`\n *\n * @example\n * const posts = collection.limit(10)\n *\n * @method Collection#limit\n * @since 3.0.0\n * @param {number} num The maximum number of records to keep in the result.\n * @returns {Array} The result.\n */\n limit (num) {\n return this.query().limit(num).run()\n },\n\n /**\n * Apply a mapping function to all records.\n *\n * @example\n * const names = collection.map(function (user) {\n * return user.name\n * })\n *\n * @method Collection#map\n * @since 3.0.0\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Array} The result of the mapping.\n */\n map (cb, thisArg) {\n const data = []\n this.index.visitAll(function (value) {\n data.push(cb.call(thisArg, value))\n })\n return data\n },\n\n /**\n * Return the result of calling the specified function on each record in this\n * collection's main index.\n *\n * @method Collection#mapCall\n * @since 3.0.0\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Array} The result.\n */\n mapCall (funcName, ...args) {\n const data = []\n this.index.visitAll(function (record) {\n data.push(record[funcName](...args))\n })\n return data\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#prune\n * @param {Object} [opts] Configuration options, passed to {@link Collection#removeAll}.\n * @since 3.0.0\n * @returns {Array} The removed records, if any.\n */\n prune (opts) {\n return this.removeAll(this.unsaved(), opts)\n },\n\n /**\n * Create a new query to be executed against the contents of the collection.\n * The result will be all or a subset of the contents of the collection.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * collection.query()\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method Collection#query\n * @since 3.0.0\n * @returns {Query} New query object.\n */\n query () {\n const Ctor = this.queryClass\n return new Ctor(this)\n },\n\n /**\n * Return the primary key of the given, or if no record is provided, return the\n * name of the field that holds the primary key of records in this Collection.\n *\n * @method Collection#recordId\n * @since 3.0.0\n * @param {(Object|Record)} [record] The record whose primary key is to be\n * returned.\n * @returns {(string|number)} Primary key or name of field that holds primary\n * key.\n */\n recordId (record) {\n if (record) {\n return utils.get(record, this.recordId())\n }\n return this.mapper ? this.mapper.idAttribute : this.idAttribute\n },\n\n /**\n * Reduce the data in the collection to a single value and return the result.\n *\n * @example\n * const totalVotes = collection.reduce(function (prev, record) {\n * return prev + record.upVotes + record.downVotes\n * }, 0)\n *\n * @method Collection#reduce\n * @since 3.0.0\n * @param {Function} cb Reduction callback.\n * @param {*} initialValue Initial value of the reduction.\n * @returns {*} The result.\n */\n reduce (cb, initialValue) {\n const data = this.getAll()\n return data.reduce(cb, initialValue)\n },\n\n /**\n * Remove the record with the given id from this Collection.\n *\n * @method Collection#remove\n * @since 3.0.0\n * @param {(string|number|object|Record)} idOrRecord The primary key of the\n * record to be removed, or a reference to the record that is to be removed.\n * @param {Object} [opts] Configuration options.\n * @returns {Object|Record} The removed record, if any.\n */\n remove (idOrRecord, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemove(idOrRecord, opts)\n let record = utils.isSorN(idOrRecord) ? this.get(idOrRecord) : idOrRecord\n\n // The record is in the collection, remove it\n if (utils.isObject(record)) {\n record = this.index.removeRecord(record)\n if (record) {\n utils.forOwn(this.indexes, function (index, name) {\n index.removeRecord(record)\n })\n if (utils.isFunction(record.off)) {\n record.off('all', this._onRecordEvent, this)\n if (!opts.silent) {\n this.emit('remove', record)\n }\n }\n }\n }\n return this.afterRemove(idOrRecord, opts, record) || record\n },\n\n /**\n * Remove from this collection the given records or the records selected by\n * the given \"query\".\n *\n * @method Collection#removeAll\n * @since 3.0.0\n * @param {Object|Object[]|Record[]} [queryOrRecords={}] Records to be removed or selection query. See {@link query}.\n * @param {Object} [queryOrRecords.where] See {@link query.where}.\n * @param {number} [queryOrRecords.offset] See {@link query.offset}.\n * @param {number} [queryOrRecords.limit] See {@link query.limit}.\n * @param {string|Array[]} [queryOrRecords.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object[]|Record[])} The removed records, if any.\n */\n removeAll (queryOrRecords, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemoveAll(queryOrRecords, opts)\n let records = utils.isArray(queryOrRecords) ? queryOrRecords.slice() : this.filter(queryOrRecords)\n\n // Remove each selected record from the collection\n const optsCopy = utils.plainCopy(opts)\n optsCopy.silent = true\n records = records\n .map((record) => this.remove(record, optsCopy))\n .filter((record) => record)\n if (!opts.silent) {\n this.emit('remove', records)\n }\n return this.afterRemoveAll(queryOrRecords, opts, records) || records\n },\n\n /**\n * Skip a number of results.\n *\n * Shortcut for `collection.query().skip(numberToSkip).run()`\n *\n * @example\n * const posts = collection.skip(10)\n *\n * @method Collection#skip\n * @since 3.0.0\n * @param {number} num The number of records to skip.\n * @returns {Array} The result.\n */\n skip (num) {\n return this.query().skip(num).run()\n },\n\n /**\n * Return the plain JSON representation of all items in this collection.\n * Assumes records in this collection have a toJSON method.\n *\n * @method Collection#toJSON\n * @since 3.0.0\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation.\n * @returns {Array} The records.\n */\n toJSON (opts) {\n return this.mapCall('toJSON', opts)\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#unsaved\n * @since 3.0.0\n * @returns {Array} The unsaved records, if any.\n */\n unsaved (opts) {\n return this.index.get()\n },\n\n /**\n * Update a record's position in a single index of this collection. See\n * {@link Collection#updateIndexes} to update a record's position in all\n * indexes at once.\n *\n * @method Collection#updateIndex\n * @since 3.0.0\n * @param {Object} record The record to update.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] The index in which to update the record's\n * position. If you don't specify an index then the record will be updated\n * in the main index.\n */\n updateIndex (record, opts) {\n opts || (opts = {})\n this.getIndex(opts.index).updateRecord(record)\n },\n\n /**\n * Updates all indexes in this collection for the provided record. Has no\n * effect if the record is not in the collection.\n *\n * @method Collection#updateIndexes\n * @since 3.0.0\n * @param {Object} record TODO\n */\n updateIndexes (record) {\n this.index.updateRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.updateRecord(record)\n })\n }\n})\n\n/**\n * Fired when a record changes. Only works for records that have tracked changes.\n * See {@link Collection~changeListener} on how to listen for this event.\n *\n * @event Collection#change\n * @see Collection~changeListener\n */\n\n/**\n * Callback signature for the {@link Collection#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * collection.on('change', onChange)\n *\n * @callback Collection~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Collection#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the Collection. See\n * {@link Collection~addListener} on how to listen for this event.\n *\n * @event Collection#add\n * @see Collection~addListener\n * @see Collection#event:add\n * @see Collection#add\n */\n\n/**\n * Callback signature for the {@link Collection#event:add} event.\n *\n * @example\n * function onAdd (recordOrRecords) {\n * // do something\n * }\n * collection.on('add', onAdd)\n *\n * @callback Collection~addListener\n * @param {Record|Record[]} The Record or Records that were added.\n * @see Collection#event:add\n * @see Collection#add\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the Collection. See\n * {@link Collection~removeListener} for how to listen for this event.\n *\n * @event Collection#remove\n * @see Collection~removeListener\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n */\n\n/**\n * Callback signature for the {@link Collection#event:remove} event.\n *\n * @example\n * function onRemove (recordsOrRecords) {\n * // do something\n * }\n * collection.on('remove', onRemove)\n *\n * @callback Collection~removeListener\n * @param {Record|Record[]} Record or Records that were removed.\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Collection:\n * @example Collection.extend\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomCollectionClass extends Collection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customCollection = new CustomCollectionClass()\n * console.log(customCollection.foo())\n * console.log(CustomCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherCollectionClass = Collection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherCollection = new OtherCollectionClass()\n * console.log(otherCollection.foo())\n * console.log(OtherCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherCollectionClass () {\n * Collection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Collection.extend({\n * constructor: AnotherCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherCollection = new AnotherCollectionClass()\n * console.log(anotherCollection.created_at)\n * console.log(anotherCollection.foo())\n * console.log(AnotherCollectionClass.beep())\n *\n * @method Collection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Collection class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Settable from './Settable'\n\nconst DOMAIN = 'Record'\n\nconst superMethod = function (mapper, name) {\n const store = mapper.datastore\n if (store && store[name]) {\n return function (...args) {\n return store[name](mapper.name, ...args)\n }\n }\n return mapper[name].bind(mapper)\n}\n\n/**\n * js-data's Record class. An instance of `Record` corresponds to an in-memory\n * representation of a single row or document in a database, Firebase,\n * localstorage, etc. Basically, a `Record` instance represents whatever kind of\n * entity in your persistence layer that has a primary key.\n *\n * ```javascript\n * import {Record} from 'js-data'\n * ```\n *\n * @example Record#constructor\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a plain record\n * let record = new Record()\n * console.log('record: ' + JSON.stringify(record))\n *\n * // You can supply properties on instantiation\n * record = new Record({ name: 'John' })\n * console.log('record: ' + JSON.stringify(record))\n *\n * @example Record#constructor2\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a record that's associated with a Mapper:\n * const UserMapper = new Mapper({ name: 'user' })\n * const User = UserMapper.recordClass\n * const user = UserMapper.createRecord({ name: 'John' })\n * const user2 = new User({ name: 'Sally' })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user2: ' + JSON.stringify(user2))\n *\n * @example Record#constructor3\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n *\n * // Instantiate a record that's associated with a store's Mapper\n * const user = store.createRecord('user', { name: 'John' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor4\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Validate on instantiation\n * const user = store.createRecord('user', { name: 1234 })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor5\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Skip validation on instantiation\n * const user = store.createRecord('user', { name: 1234 }, { noValidate: true })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user.isValid(): ' + user.isValid())\n *\n * @class Record\n * @extends Component\n * @param {Object} [props] The initial properties of the new Record instance.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate=false] Whether to skip validation on the\n * initial properties.\n * @since 3.0.0\n */\nfunction Record (props, opts) {\n utils.classCallCheck(this, Record)\n Settable.call(this)\n props || (props = {})\n opts || (opts = {})\n const _set = this._set\n // TODO: Optimize these strings\n _set('creating', true)\n if (opts.noValidate) {\n _set('noValidate', true)\n }\n // Set the idAttribute value first, if it exists.\n const mapper = this.constructor.mapper\n const id = mapper ? utils.get(props, mapper.idAttribute) : undefined\n if (id !== undefined) {\n utils.set(this, mapper.idAttribute, id)\n }\n utils.fillIn(this, props)\n _set('creating', false)\n _set('noValidate', false)\n _set('previous', utils.plainCopy(props))\n}\n\nexport default Component.extend({\n constructor: Record,\n\n /**\n * Returns the {@link Mapper} paired with this record's class, if any.\n *\n * @method Record#_mapper\n * @returns {Mapper} The {@link Mapper} paired with this record's class, if any.\n * @since 3.0.0\n */\n _mapper () {\n const mapper = this.constructor.mapper\n if (!mapper) {\n throw utils.err(`${DOMAIN}#_mapper`, '')(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Lifecycle hook.\n *\n * @method Record#afterLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n afterLoadRelations () {},\n\n /**\n * Lifecycle hook.\n *\n * @method Record#beforeLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n beforeLoadRelations () {},\n\n /**\n * Return the change history of this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @method Record#changeHistory\n * @since 3.0.0\n */\n changeHistory () {\n return (this._get('history') || []).slice()\n },\n\n /**\n * Return changes to this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#changes\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n * user.name = 'John'\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n *\n * @method Record#changes\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} Object describing the changes to this record since it was\n * instantiated or its {@link Record#commit} method was last called.\n * @since 3.0.0\n */\n changes (opts) {\n opts || (opts = {})\n return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Make the record's current in-memory state it's only state, with any\n * previous property values being set to current values.\n *\n * @example Record#commit\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#commit\n * @since 3.0.0\n */\n commit () {\n this._set('changed') // unset\n this._set('history', []) // clear history\n this._set('previous', utils.plainCopy(this))\n },\n\n /**\n * Call {@link Mapper#destroy} using this record's primary key.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user')\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Destroy this user from the database\n * return user.destroy()\n * })\n *\n * @method Record#destroy\n * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}.\n * @returns {Promise} The result of calling {@link Mapper#destroy} with the\n * primary key of this record.\n * @since 3.0.0\n */\n destroy (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts)\n },\n\n /**\n * Return the value at the given path for this instance.\n *\n * @example Record#get\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', { name: 'Bob' })\n * console.log('user.get(\"name\"): ' + user.get('name'))\n *\n * @method Record#get\n * @param {string} key Path of value to retrieve.\n * @returns {*} Value at path.\n * @since 3.0.0\n */\n 'get' (key) {\n return utils.get(this, key)\n },\n\n /**\n * Return whether this record has changed since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#hasChanges\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#hasChanges\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Return whether the record has changed since it was\n * instantiated or since its {@link Record#commit} method was called.\n * @since 3.0.0\n */\n hasChanges (opts) {\n const quickHasChanges = !!(this._get('changed') || []).length\n return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Return whether the record is unsaved. Records that have primary keys are\n * considered \"saved\". Records without primary keys are considered \"unsaved\".\n *\n * @example Record#isNew\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * id: 1234\n * })\n * const user2 = store.createRecord('user')\n * console.log('user isNew: ' + user.isNew()) // false\n * console.log('user2 isNew: ' + user2.isNew()) // true\n *\n * @method Record#isNew\n * @returns {boolean} Whether the record is unsaved.\n * @since 3.0.0\n */\n isNew (opts) {\n return utils.get(this, this._mapper().idAttribute) === undefined\n },\n\n /**\n * Return whether the record in its current state passes validation.\n *\n * @example Record#isValid\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user isValid: ' + user.isValid())\n * user.name = 'John'\n * console.log('user isValid: ' + user.isValid())\n *\n * @method Record#isValid\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {boolean} Whether the record in its current state passes\n * validation.\n * @since 3.0.0\n */\n isValid (opts) {\n return !this._mapper().validate(this, opts)\n },\n\n /**\n * Lazy load relations of this record, to be attached to the record once their\n * loaded.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user', {\n * relations: {\n * hasMany: {\n * post: {\n * localField: 'posts',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.defineMapper('post', {\n * relations: {\n * belongsTo: {\n * user: {\n * localField: 'user',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Load the user's post relations\n * return user.loadRelations(['post'])\n * }).then((user) => {\n * console.log(user.posts) // [{...}, {...}, ...]\n * })\n *\n * @method Record#loadRelations\n * @param {string[]} [relations] List of relations to load. Can use localField\n * names or Mapper names to pick relations.\n * @param {Object} [opts] Configuration options.\n * @returns {Promise} Resolves with the record, with the loaded relations now\n * attached.\n * @since 3.0.0\n */\n loadRelations (relations, opts) {\n let op\n const mapper = this._mapper()\n\n // Default values for arguments\n relations || (relations = [])\n if (utils.isString(relations)) {\n relations = [relations]\n }\n opts || (opts = {})\n opts.with = relations\n\n // Fill in \"opts\" with the Model's configuration\n utils._(opts, mapper)\n opts.adapter = mapper.getAdapterName(opts)\n\n // beforeLoadRelations lifecycle hook\n op = opts.op = 'beforeLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'loadRelations'\n mapper.dbg(op, this, relations, opts)\n let tasks = []\n let task\n utils.forEachRelation(mapper, opts, (def, optsCopy) => {\n const relatedMapper = def.getRelation()\n optsCopy.raw = false\n if (utils.isFunction(def.load)) {\n task = def.load(mapper, def, this, opts)\n } else if (def.type === 'hasMany' || def.type === 'hasOne') {\n if (def.foreignKey) {\n task = superMethod(relatedMapper, 'findAll')({\n [def.foreignKey]: utils.get(this, mapper.idAttribute)\n }, optsCopy).then(function (relatedData) {\n if (def.type === 'hasOne') {\n return relatedData.length ? relatedData[0] : undefined\n }\n return relatedData\n })\n } else if (def.localKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [relatedMapper.idAttribute]: {\n 'in': utils.get(this, def.localKeys)\n }\n }\n })\n } else if (def.foreignKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [def.foreignKeys]: {\n 'contains': utils.get(this, mapper.idAttribute)\n }\n }\n }, opts)\n }\n } else if (def.type === 'belongsTo') {\n const key = utils.get(this, def.foreignKey)\n if (utils.isSorN(key)) {\n task = superMethod(relatedMapper, 'find')(key, optsCopy)\n }\n }\n if (task) {\n task = task.then((relatedData) => {\n def.setLocalField(this, relatedData)\n })\n tasks.push(task)\n }\n })\n return Promise.all(tasks)\n }).then(() => {\n // afterLoadRelations lifecycle hook\n op = opts.op = 'afterLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => this)\n })\n },\n\n /**\n * Return the properties with which this record was instantiated.\n *\n * @example Record#previous\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.name = 'Bob'\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.commit()\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n *\n * @method Record#previous\n * @param {string} [key] If specified, return just the initial value of the\n * given key.\n * @returns {Object} The initial properties of this record.\n * @since 3.0.0\n */\n previous (key) {\n if (key) {\n return this._get(`previous.${key}`)\n }\n return this._get('previous')\n },\n\n /**\n * Revert changes to this record back to the properties it had when it was\n * instantiated.\n *\n * @example Record#revert\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user: ' + JSON.stringify(user))\n * user.name = 'Bob'\n * console.log('user: ' + JSON.stringify(user))\n * user.revert()\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#revert\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.preserve] Array of strings or Regular Expressions\n * denoting properties that should not be reverted.\n * @since 3.0.0\n */\n revert (opts) {\n const previous = this._get('previous')\n opts || (opts = {})\n opts.preserve || (opts.preserve = [])\n utils.forOwn(this, (value, key) => {\n if (key !== this._mapper().idAttribute && !previous.hasOwnProperty(key) && this.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) {\n delete this[key]\n }\n })\n utils.forOwn(previous, (value, key) => {\n if (opts.preserve.indexOf(key) === -1) {\n this[key] = value\n }\n })\n this.commit()\n },\n\n /**\n * Delegates to {@link Mapper#create} or {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('session')\n * const session = store.createRecord('session', { topic: 'Node.js' })\n *\n * // Create a new record in the database\n * session.save().then(() => {\n * console.log(session.id) // 1234\n *\n * session.skill_level = 'beginner'\n *\n * // Update the record in the database\n * return user.save()\n * })\n *\n * @method Record#save\n * @param {Object} [opts] Configuration options. See {@link Mapper#create} and\n * {@link Mapper#update}.\n * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`.\n * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @param {Array} [opts.ignore] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @returns {Promise} The result of calling {@link Mapper#create} or\n * {@link Mapper#update}.\n * @since 3.0.0\n */\n save (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n const id = utils.get(this, mapper.idAttribute)\n let props = this\n\n const postProcess = (result) => {\n const record = opts.raw ? result.data : result\n if (record) {\n utils.deepMixIn(this, record)\n this.commit()\n }\n return result\n }\n\n if (id === undefined) {\n return superMethod(mapper, 'create')(props, opts).then(postProcess)\n }\n if (opts.changesOnly) {\n const changes = this.changes(opts)\n props = {}\n utils.fillIn(props, changes.added)\n utils.fillIn(props, changes.changed)\n }\n return superMethod(mapper, 'update')(id, props, opts).then(postProcess)\n },\n\n /**\n * Set the value for a given key, or the values for the given keys if \"key\" is\n * an object. Triggers change events on those properties that have `track: true`\n * in {@link Mapper#schema}.\n *\n * @example Record#set\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set('name', 'Bob')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set({ age: 30, role: 'admin' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @fires Record#change\n * @method Record#set\n * @param {(string|Object)} key Key to set or hash of key-value pairs to set.\n * @param {*} [value] Value to set for the given key.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n 'set' (key, value, opts) {\n if (utils.isObject(key)) {\n opts = value\n }\n opts || (opts = {})\n if (opts.silent) {\n this._set('silent', true)\n }\n utils.set(this, key, value)\n if (!this._get('eventId')) {\n this._set('silent') // unset\n }\n },\n\n /**\n * Return a plain object representation of this record. If the class from\n * which this record was created has a Mapper, then {@link Mapper#toJSON} will\n * be called with this record instead.\n *\n * @example Record#toJSON\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * const user = store.createRecord('user', {\n * name: 'John',\n * $$hashKey: '1234'\n * })\n * console.log('user: ' + JSON.stringify(user.toJSON()))\n * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true })))\n *\n * @method Record#toJSON\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation. Only available as an option if the class\n * from which this record was created has a Mapper and this record resides in\n * an instance of {@link DataStore}.\n * @returns {Object} Plain object representation of this record.\n * @since 3.0.0\n */\n toJSON (opts) {\n const mapper = this.constructor.mapper\n if (mapper) {\n return mapper.toJSON(this, opts)\n } else {\n const json = {}\n utils.forOwn(this, function (prop, key) {\n json[key] = utils.plainCopy(prop)\n })\n return json\n }\n },\n\n /**\n * Unset the value for a given key. Triggers change events on those properties\n * that have `track: true` in {@link Mapper#schema}.\n *\n * @example Record#unset\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', {\n * name: 'John'\n * })\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.unset('name')\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#unset\n * @param {string} key Key to unset.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n unset (key, opts) {\n this.set(key, undefined, opts)\n },\n\n /**\n * Validate this record based on its current properties.\n *\n * @example Record#validate\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user validation: ' + JSON.stringify(user.validate()))\n * user.name = 'John'\n * console.log('user validation: ' + user.validate())\n *\n * @method Record#validate\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {*} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (opts) {\n return this._mapper().validate(this, opts)\n }\n})\n\n/**\n * Allow records to emit events.\n *\n * An record's registered listeners are stored in the record's private data.\n */\nutils.eventify(\n Record.prototype,\n function () {\n return this._get('events')\n },\n function (value) {\n this._set('events', value)\n }\n)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link Record~changeListener} on how to listen for this event.\n *\n * @event Record#change\n * @see Record~changeListener\n */\n\n/**\n * Callback signature for the {@link Record#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * record.on('change', onChange)\n *\n * @callback Record~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Record#event:change\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Record:\n * @example Record.extend\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomRecordClass extends Record {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customRecord = new CustomRecordClass()\n * console.log(customRecord.foo())\n * console.log(CustomRecordClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherRecordClass = Record.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherRecord = new OtherRecordClass()\n * console.log(otherRecord.foo())\n * console.log(OtherRecordClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherRecordClass () {\n * Record.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Record.extend({\n * constructor: AnotherRecordClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherRecord = new AnotherRecordClass()\n * console.log(anotherRecord.created_at)\n * console.log(anotherRecord.foo())\n * console.log(AnotherRecordClass.beep())\n *\n * @method Record.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Record class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Schema'\n\n/**\n * A function map for each of the seven primitive JSON types defined by the core specification.\n * Each function will check a given value and return true or false if the value is an instance of that type.\n * ```\n * types.integer(1) // returns true\n * types.string({}) // returns false\n * ```\n * http://json-schema.org/latest/json-schema-core.html#anchor8\n * @name Schema.types\n * @type {Object}\n */\nconst types = {\n array: utils.isArray,\n boolean: utils.isBoolean,\n integer: utils.isInteger,\n 'null': utils.isNull,\n number: utils.isNumber,\n object: utils.isObject,\n string: utils.isString\n}\n\n/**\n * @ignore\n */\nconst segmentToString = function (segment, prev) {\n let str = ''\n if (segment) {\n if (utils.isNumber(segment)) {\n str += `[${segment}]`\n } else if (prev) {\n str += `.${segment}`\n } else {\n str += `${segment}`\n }\n }\n return str\n}\n\n/**\n * @ignore\n */\nconst makePath = function (opts) {\n opts || (opts = {})\n let path = ''\n const segments = opts.path || []\n segments.forEach(function (segment) {\n path += segmentToString(segment, path)\n })\n path += segmentToString(opts.prop, path)\n return path\n}\n\n/**\n * @ignore\n */\nconst makeError = function (actual, expected, opts) {\n return {\n expected,\n actual: '' + actual,\n path: makePath(opts)\n }\n}\n\n/**\n * @ignore\n */\nconst addError = function (actual, expected, opts, errors) {\n errors.push(makeError(actual, expected, opts))\n}\n\n/**\n * @ignore\n */\nconst maxLengthCommon = function (keyword, value, schema, opts) {\n const max = schema[keyword]\n if (value.length > max) {\n return makeError(value.length, `length no more than ${max}`, opts)\n }\n}\n\n/**\n * @ignore\n */\nconst minLengthCommon = function (keyword, value, schema, opts) {\n const min = schema[keyword]\n if (value.length < min) {\n return makeError(value.length, `length no less than ${min}`, opts)\n }\n}\n\n/**\n * A map of all object member validation functions for each keyword defined in the JSON Schema.\n * @name Schema.validationKeywords\n * @type {Object}\n */\nconst validationKeywords = {\n /**\n * Validates the provided value against all schemas defined in the Schemas `allOf` keyword.\n * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be a valid JSON Schema.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor82\n *\n * @name Schema.validationKeywords.allOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `allOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n allOf (value, schema, opts) {\n let allErrors = []\n schema.allOf.forEach(function (_schema) {\n allErrors = allErrors.concat(validate(value, _schema, opts) || [])\n })\n return allErrors.length ? undefined : allErrors\n },\n\n /**\n * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword.\n * The instance is valid against this keyword if and only if it is valid against\n * at least one of the schemas in this keyword's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor85\n *\n * @name Schema.validationKeywords.anyOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `anyOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n anyOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.anyOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * http://json-schema.org/latest/json-schema-validation.html#anchor70\n *\n * @name Schema.validationKeywords.dependencies\n * @method\n * @param {*} value TODO\n * @param {Object} schema TODO\n * @param {Object} opts TODO\n */\n dependencies (value, schema, opts) {\n // TODO\n },\n\n /**\n * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword\n * Validation succeeds if the value is deeply equal to one of the values in the array.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor76\n *\n * @name Schema.validationKeywords.enum\n * @method\n * @param {*} value Value to validate\n * @param {Object} schema Schema containing the `enum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n enum (value, schema, opts) {\n const possibleValues = schema['enum']\n if (utils.findIndex(possibleValues, (item) => utils.deepEqual(item, value)) === -1) {\n return makeError(value, `one of (${possibleValues.join(', ')})`, opts)\n }\n },\n\n /**\n * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword\n * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules.\n *\n * @name Schema.validationKeywords.items\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the items keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n items (value, schema, opts) {\n opts || (opts = {})\n // TODO: additionalItems\n let items = schema.items\n let errors = []\n const checkingTuple = utils.isArray(items)\n const length = value.length\n for (var prop = 0; prop < length; prop++) {\n if (checkingTuple) {\n // Validating a tuple, instead of just checking each item against the\n // same schema\n items = schema.items[prop]\n }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], items, opts) || [])\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword\n * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor17\n *\n * @name Schema.validationKeywords.maximum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `maximum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maximum (value, schema, opts) {\n // Must be a number\n const maximum = schema.maximum\n // Must be a boolean\n // Depends on maximum\n // default: false\n const exclusiveMaximum = schema.exclusiveMaximum\n if (typeof value === typeof maximum && !(exclusiveMaximum ? maximum > value : maximum >= value)) {\n return exclusiveMaximum\n ? makeError(value, `no more than nor equal to ${maximum}`, opts)\n : makeError(value, `no more than ${maximum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword.\n * Validation succeeds if the length of the array is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor42\n *\n * @name Schema.validationKeywords.maxItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `maxItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return maxLengthCommon('maxItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword.\n * Validation succeeds if the length of the string is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor26\n *\n * @name Schema.validationKeywords.maxLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `maxLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxLength (value, schema, opts) {\n return maxLengthCommon('maxLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword.\n * Validation succeeds if the object's property count is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor54\n *\n * @name Schema.validationKeywords.maxProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `maxProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const maxProperties = schema.maxProperties\n const length = Object.keys(value).length\n if (length > maxProperties) {\n return makeError(length, `no more than ${maxProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword\n * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor21\n *\n * @name Schema.validationKeywords.minimum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `minimum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minimum (value, schema, opts) {\n // Must be a number\n const minimum = schema.minimum\n // Must be a boolean\n // Depends on minimum\n // default: false\n const exclusiveMinimum = schema.exclusiveMinimum\n if (typeof value === typeof minimum && !(exclusiveMinimum ? value > minimum : value >= minimum)) {\n return exclusiveMinimum\n ? makeError(value, `no less than nor equal to ${minimum}`, opts)\n : makeError(value, `no less than ${minimum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword.\n * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor45\n *\n * @name Schema.validationKeywords.minItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `minItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return minLengthCommon('minItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword.\n * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor29\n *\n * @name Schema.validationKeywords.minLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `minLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minLength (value, schema, opts) {\n return minLengthCommon('minLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword.\n * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor57\n *\n * @name Schema.validationKeywords.minProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `minProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const minProperties = schema.minProperties\n const length = Object.keys(value).length\n if (length < minProperties) {\n return makeError(length, `no more than ${minProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword.\n * Validation succeeds if the number can be divided equally into the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor14\n *\n * @name Schema.validationKeywords.multipleOf\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing the `multipleOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n multipleOf (value, schema, opts) {\n const multipleOf = schema.multipleOf\n if (utils.isNumber(value)) {\n if ((value / multipleOf) % 1 !== 0) {\n return makeError(value, `multipleOf ${multipleOf}`, opts)\n }\n }\n },\n\n /**\n * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword.\n * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor91\n * @name Schema.validationKeywords.not\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the not keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n not (value, schema, opts) {\n if (!validate(value, schema.not, opts)) {\n // TODO: better messaging\n return makeError('succeeded', 'should have failed', opts)\n }\n },\n\n /**\n * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword.\n * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor88\n * @name Schema.validationKeywords.oneOf\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the `oneOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n oneOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.oneOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else if (validated) {\n allErrors = [makeError('valid against more than one', 'valid against only one', opts)]\n validated = false\n return false\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword.\n * Validation succeeds if the string is a match of the regex value of this keyword.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor33\n * @name Schema.validationKeywords.pattern\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `pattern` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n pattern (value, schema, opts) {\n const pattern = schema.pattern\n if (utils.isString(value) && !value.match(pattern)) {\n return makeError(value, pattern, opts)\n }\n },\n\n /**\n * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword.\n * Validation succeeds if the object's property are valid with each of the schema's in the provided map.\n * Validation also depends on the additionalProperties and or patternProperties.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info.\n *\n * @name Schema.validationKeywords.properties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `properties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n properties (value, schema, opts) {\n opts || (opts = {})\n // Can be a boolean or an object\n // Technically the default is an \"empty schema\", but here \"true\" is\n // functionally the same\n const additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties\n // \"s\": The property set of the instance to validate.\n const toValidate = {}\n // \"p\": The property set from \"properties\".\n // Default is an object\n const properties = schema.properties || {}\n // \"pp\": The property set from \"patternProperties\".\n // Default is an object\n const patternProperties = schema.patternProperties || {}\n let errors = []\n\n // Collect set \"s\"\n utils.forOwn(value, function (_value, prop) {\n toValidate[prop] = undefined\n })\n // Remove from \"s\" all elements of \"p\", if any.\n utils.forOwn(properties || {}, function (_schema, prop) {\n // if (value[prop] === undefined && _schema['default'] !== undefined) {\n // value[prop] = utils.copy(_schema['default'])\n // }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n })\n // For each regex in \"pp\", remove all elements of \"s\" which this regex\n // matches.\n utils.forOwn(patternProperties, function (_schema, pattern) {\n utils.forOwn(toValidate, function (undef, prop) {\n if (prop.match(pattern)) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n }\n })\n })\n const keys = Object.keys(toValidate)\n // If \"s\" is not empty, validation fails\n if (additionalProperties === false) {\n if (keys.length) {\n addError(`extra fields: ${keys.join(', ')}`, 'no extra fields', opts, errors)\n }\n } else if (utils.isObject(additionalProperties)) {\n // Otherwise, validate according to provided schema\n keys.forEach(function (prop) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], additionalProperties, opts) || [])\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided object's has all properties listed in the Schema's `properties` keyword array.\n * Validation succeeds if the object contains all properties provided in the array value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor61\n *\n * @name Schema.validationKeywords.required\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `required` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n required (value, schema, opts) {\n opts || (opts = {})\n const required = schema.required\n let errors = []\n if (!opts.existingOnly) {\n required.forEach(function (prop) {\n if (utils.get(value, prop) === undefined) {\n const prevProp = opts.prop\n opts.prop = prop\n addError(undefined, 'a value', opts, errors)\n opts.prop = prevProp\n }\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor79\n *\n * @name Schema.validationKeywords.type\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `type` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n type (value, schema, opts) {\n let type = schema.type\n let validType\n // Can be one of several types\n if (utils.isString(type)) {\n type = [type]\n }\n // Try to match the value against an expected type\n type.forEach(function (_type) {\n // TODO: throw an error if type is not defined\n if (types[_type](value, schema, opts)) {\n // Matched a type\n validType = _type\n return false\n }\n })\n // Value did not match any expected type\n if (!validType) {\n return makeError(value !== undefined && value !== null ? typeof value : '' + value, `one of (${type.join(', ')})`, opts)\n }\n // Run keyword validators for matched type\n // http://json-schema.org/latest/json-schema-validation.html#anchor12\n const validator = typeGroupValidators[validType]\n if (validator) {\n return validator(value, schema, opts)\n }\n },\n\n /**\n * Validates the provided array values are unique.\n * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true\n * see http://json-schema.org/latest/json-schema-validation.html#anchor49\n *\n * @name Schema.validationKeywords.uniqueItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `uniqueItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n uniqueItems (value, schema, opts) {\n if (value && value.length && schema.uniqueItems) {\n const length = value.length\n let item, i, j\n // Check n - 1 items\n for (i = length - 1; i > 0; i--) {\n item = value[i]\n // Only compare against unchecked items\n for (j = i - 1; j >= 0; j--) {\n // Found a duplicate\n if (utils.deepEqual(item, value[j])) {\n return makeError(item, 'no duplicates', opts)\n }\n }\n }\n }\n }\n}\n\n/**\n * @ignore\n */\nconst validateKeyword = function (op, value, schema, opts) {\n return schema[op] !== undefined && validationKeywords[op](value, schema, opts)\n}\n\n/**\n * @ignore\n */\nconst runOps = function (ops, value, schema, opts) {\n let errors = []\n ops.forEach(function (op) {\n errors = errors.concat(validateKeyword(op, value, schema, opts) || [])\n })\n return errors.length ? errors : undefined\n}\n\nconst ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']\nconst ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']\nconst NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']\nconst OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\nconst STRING_OPS = ['maxLength', 'minLength', 'pattern']\n\n/**\n * http://json-schema.org/latest/json-schema-validation.html#anchor75\n * @ignore\n */\nconst validateAny = function (value, schema, opts) {\n return runOps(ANY_OPS, value, schema, opts)\n}\n\n/**\n * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification.\n *\n * @name Schema.validate\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\nconst validate = function (value, schema, opts) {\n let errors = []\n opts || (opts = {})\n opts.ctx || (opts.ctx = { value, schema })\n let shouldPop\n let prevProp = opts.prop\n if (schema === undefined) {\n return\n }\n if (!utils.isObject(schema)) {\n throw utils.err(`${DOMAIN}#validate`)(500, `Invalid schema at path: \"${opts.path}\"`)\n }\n if (opts.path === undefined) {\n opts.path = []\n }\n // Track our location as we recurse\n if (opts.prop !== undefined) {\n shouldPop = true\n opts.path.push(opts.prop)\n opts.prop = undefined\n }\n // Validate against parent schema\n if (schema['extends']) {\n // opts.path = path\n // opts.prop = prop\n if (utils.isFunction(schema['extends'].validate)) {\n errors = errors.concat(schema['extends'].validate(value, opts) || [])\n } else {\n errors = errors.concat(validate(value, schema['extends'], opts) || [])\n }\n }\n if (value === undefined) {\n // Check if property is required\n if (schema.required === true && !opts.existingOnly) {\n addError(value, 'a value', opts, errors)\n }\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n }\n\n errors = errors.concat(validateAny(value, schema, opts) || [])\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n}\n\n// These strings are cached for optimal performance of the change detection\n// boolean - Whether a Record is changing in the current execution frame\nconst changingPath = 'changing'\n// string[] - Properties that have changed in the current execution frame\nconst changedPath = 'changed'\n// Object[] - History of change records\nconst changeHistoryPath = 'history'\n// boolean - Whether a Record is currently being instantiated\nconst creatingPath = 'creating'\n// number - The setTimeout change event id of a Record, if any\nconst eventIdPath = 'eventId'\n// boolean - Whether to skip validation for a Record's currently changing property\nconst noValidatePath = 'noValidate'\n// boolean - Whether to skip change notification for a Record's currently\n// changing property\nconst silentPath = 'silent'\nconst validationFailureMsg = 'validation failed'\n\n/**\n * Assemble a property descriptor which will be added to the prototype of\n * {@link Mapper#recordClass}. This method is called when\n * {@link Mapper#applySchema} is set to `true`.\n *\n * @ignore\n */\nconst makeDescriptor = function (prop, schema, opts) {\n const descriptor = {\n // Better to allow configurability, but at the user's own risk\n configurable: true,\n // These properties are enumerable by default, but regardless of their\n // enumerability, they won't be \"own\" properties of individual records\n enumerable: schema.enumerable === undefined ? true : !!schema.enumerable\n }\n // Cache a few strings for optimal performance\n const keyPath = `props.${prop}`\n const previousPath = `previous.${prop}`\n const getter = opts.getter\n const setter = opts.setter\n const unsetter = opts.unsetter\n const track = utils.isBoolean(opts.track) ? opts.track : schema.track\n\n descriptor.get = function () {\n return this._get(keyPath)\n }\n\n if (utils.isFunction(schema.get)) {\n const originalGet = descriptor.get\n descriptor.get = function () {\n return schema.get.call(this, originalGet)\n }\n }\n\n descriptor.set = function (value) {\n // These are accessed a lot\n const _get = this[getter]\n const _set = this[setter]\n const _unset = this[unsetter]\n\n // Optionally check that the new value passes validation\n if (!_get(noValidatePath)) {\n const errors = schema.validate(value, { path: [prop] })\n if (errors) {\n // Immediately throw an error, preventing the record from getting into\n // an invalid state\n const error = new Error(validationFailureMsg)\n error.errors = errors\n throw error\n }\n }\n // TODO: Make it so tracking can be turned on for all properties instead of\n // only per-property\n if (track && !_get(creatingPath)) {\n const previous = _get(previousPath)\n const current = _get(keyPath)\n let changing = _get(changingPath)\n let changed = _get(changedPath)\n\n if (!changing) {\n // Track properties that are changing in the current event loop\n changed = []\n }\n\n // Add changing properties to this array once at most\n const index = changed.indexOf(prop)\n if (current !== value && index === -1) {\n changed.push(prop)\n }\n if (previous === value) {\n if (index >= 0) {\n changed.splice(index, 1)\n }\n }\n // No changes in current event loop\n if (!changed.length) {\n changing = false\n _unset(changingPath)\n _unset(changedPath)\n // Cancel pending change event\n if (_get(eventIdPath)) {\n clearTimeout(_get(eventIdPath))\n _unset(eventIdPath)\n }\n }\n // Changes detected in current event loop\n if (!changing && changed.length) {\n _set(changedPath, changed)\n _set(changingPath, true)\n // Saving the timeout id allows us to batch all changes in the same\n // event loop into a single \"change\"\n // TODO: Optimize\n _set(eventIdPath, setTimeout(() => {\n // Previous event loop where changes were gathered has ended, so\n // notify any listeners of those changes and prepare for any new\n // changes\n _unset(changedPath)\n _unset(eventIdPath)\n _unset(changingPath)\n // TODO: Optimize\n if (!_get(silentPath)) {\n let i\n for (i = 0; i < changed.length; i++) {\n this.emit('change:' + changed[i], this, utils.get(this, changed[i]))\n }\n const changes = this.changes()\n const changeRecord = utils.plainCopy(changes)\n changeRecord.timestamp = new Date().getTime()\n const changeHistory = _get(changeHistoryPath) || []\n _set(changeHistoryPath, changeHistory)\n changeHistory.push(changeRecord)\n this.emit('change', this, changes)\n }\n _unset(silentPath)\n }, 0))\n }\n }\n _set(keyPath, value)\n return value\n }\n\n if (utils.isFunction(schema.set)) {\n const originalSet = descriptor.set\n descriptor.set = function (value) {\n return schema.set.call(this, value, originalSet)\n }\n }\n\n return descriptor\n}\n\n/**\n * A map of validation functions grouped by type.\n *\n * @name Schema.typeGroupValidators\n * @type {Object}\n */\nconst typeGroupValidators = {\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an array.\n * The validation keywords for the type `array` are:\n *```\n * ['items', 'maxItems', 'minItems', 'uniqueItems']\n *```\n * see http://json-schema.org/latest/json-schema-validation.html#anchor25\n *\n * @name Schema.typeGroupValidators.array\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing at least one array keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n array: function (value, schema, opts) {\n return runOps(ARRAY_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer.\n * The validation keywords for the type `integer` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.integer\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `integer` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n integer: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an number.\n * The validation keywords for the type `number` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.number\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `number` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n number: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer.\n * The validation keywords for the type `numeric` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor13.\n *\n * @name Schema.typeGroupValidators.numeric\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `numeric` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n numeric: function (value, schema, opts) {\n return runOps(NUMERIC_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an object.\n * The validation keywords for the type `object` are:\n *```\n * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor53.\n *\n * @name Schema.typeGroupValidators.object\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing at least one `object` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n object: function (value, schema, opts) {\n return runOps(OBJECT_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an string.\n * The validation keywords for the type `string` are:\n *```\n * ['maxLength', 'minLength', 'pattern']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor25.\n *\n * @name Schema.typeGroupValidators.string\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing at least one `string` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n string: function (value, schema, opts) {\n return runOps(STRING_OPS, value, schema, opts)\n }\n}\n\n/**\n * js-data's Schema class.\n *\n * @example Schema#constructor\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const PostSchema = new Schema({\n * type: 'object',\n * properties: {\n * title: { type: 'string' }\n * }\n * })\n * PostSchema.validate({ title: 1234 })\n *\n * @class Schema\n * @extends Component\n * @param {Object} definition Schema definition according to json-schema.org\n */\nfunction Schema (definition) {\n definition || (definition = {})\n // TODO: schema validation\n utils.fillIn(this, definition)\n\n if (this.type === 'object' && this.properties) {\n utils.forOwn(this.properties, (_definition, prop) => {\n if (!(_definition instanceof Schema)) {\n this.properties[prop] = new Schema(_definition)\n }\n })\n }\n if (this.type === 'array' && this.items && !(this.items instanceof Schema)) {\n this.items = new Schema(this.items)\n }\n ['allOf', 'anyOf', 'oneOf'].forEach((validationKeyword) => {\n if (this[validationKeyword]) {\n this[validationKeyword].forEach((_definition, i) => {\n if (!(_definition instanceof Schema)) {\n this[validationKeyword][i] = new Schema(_definition)\n }\n })\n }\n })\n}\n\nexport default Component.extend({\n constructor: Schema,\n\n /**\n * This adds ES5 getters/setters to the target based on the \"properties\" in\n * this Schema, which makes possible change tracking and validation on\n * property assignment.\n *\n * @name Schema#validate\n * @method\n * @param {Object} target The prototype to which to apply this schema.\n */\n apply (target, opts) {\n opts || (opts = {})\n opts.getter || (opts.getter = '_get')\n opts.setter || (opts.setter = '_set')\n opts.unsetter || (opts.unsetter = '_unset')\n opts.track || (opts.track = this.track)\n const properties = this.properties || {}\n utils.forOwn(properties, function (schema, prop) {\n Object.defineProperty(\n target,\n prop,\n makeDescriptor(prop, schema, opts)\n )\n })\n },\n\n /**\n * Apply default values to the target object for missing values.\n *\n * @name Schema#applyDefaults\n * @method\n * @param {Object} target The target to which to apply values for missing values.\n */\n applyDefaults (target) {\n if (!target) {\n return\n }\n const properties = this.properties || {}\n const hasSet = utils.isFunction(target.set) || utils.isFunction(target._set)\n utils.forOwn(properties, function (schema, prop) {\n if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) {\n if (hasSet) {\n target.set(prop, utils.plainCopy(schema['default']), { silent: true })\n } else {\n utils.set(target, prop, utils.plainCopy(schema['default']))\n }\n }\n if (schema.type === 'object' && schema.properties) {\n if (hasSet) {\n const orig = target._get('noValidate')\n target._set('noValidate', true)\n utils.set(target, prop, utils.get(target, prop) || {}, { silent: true })\n target._set('noValidate', orig)\n } else {\n utils.set(target, prop, utils.get(target, prop) || {})\n }\n schema.applyDefaults(utils.get(target, prop))\n }\n })\n },\n\n /**\n * Validate the provided value against this schema.\n *\n * @name Schema#validate\n * @method\n * @param {*} value Value to validate.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n validate (value, opts) {\n return validate(value, this, opts)\n }\n}, {\n ANY_OPS,\n ARRAY_OPS,\n NUMERIC_OPS,\n OBJECT_OPS,\n STRING_OPS,\n typeGroupValidators,\n types,\n validate,\n validationKeywords\n})\n\n/**\n * Create a subclass of this Schema:\n * @example Schema.extend\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSchemaClass extends Schema {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSchema = new CustomSchemaClass()\n * console.log(customSchema.foo())\n * console.log(CustomSchemaClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSchemaClass = Schema.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSchema = new OtherSchemaClass()\n * console.log(otherSchema.foo())\n * console.log(OtherSchemaClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSchemaClass () {\n * Schema.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Schema.extend({\n * constructor: AnotherSchemaClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSchema = new AnotherSchemaClass()\n * console.log(anotherSchema.created_at)\n * console.log(anotherSchema.foo())\n * console.log(AnotherSchemaClass.beep())\n *\n * @method Schema.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Schema class.\n * @since 3.0.0\n */\n\n","import utils from './utils'\n\n// TODO: remove this when the rest of the project is cleaned\nexport const belongsToType = 'belongsTo'\nexport const hasManyType = 'hasMany'\nexport const hasOneType = 'hasOne'\n\nconst DOMAIN = 'Relation'\n\nexport function Relation (relatedMapper, options = {}) {\n utils.classCallCheck(this, Relation)\n\n options.type = this.constructor.TYPE_NAME\n this.validateOptions(relatedMapper, options)\n\n if (typeof relatedMapper === 'object') {\n Object.defineProperty(this, 'relatedMapper', { value: relatedMapper })\n }\n\n Object.defineProperty(this, 'inverse', { writable: true })\n utils.fillIn(this, options)\n}\n\nRelation.extend = utils.extend\n\nutils.addHiddenPropsToTarget(Relation.prototype, {\n get canAutoAddLinks () {\n return this.add === undefined || !!this.add\n },\n\n get relatedCollection () {\n return this.mapper.datastore.getCollection(this.relation)\n },\n\n validateOptions (related, opts) {\n const DOMAIN_ERR = `new ${DOMAIN}`\n\n const localField = opts.localField\n if (!localField) {\n throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField)\n }\n\n const foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey\n if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) {\n throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey)\n }\n\n if (utils.isString(related)) {\n opts.relation = related\n if (!utils.isFunction(opts.getRelation)) {\n throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation)\n }\n } else if (related) {\n opts.relation = related.name\n } else {\n throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related)\n }\n },\n\n assignTo (mapper) {\n this.name = mapper.name\n Object.defineProperty(this, 'mapper', { value: mapper })\n\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] })\n mapper.relationList.push(this)\n mapper.relationFields.push(this.localField)\n },\n\n canFindLinkFor () {\n return !!(this.foreignKey || this.localKey)\n },\n\n getRelation () {\n return this.relatedMapper\n },\n\n getForeignKey (record) {\n return utils.get(record, this.mapper.idAttribute)\n },\n\n setForeignKey (record, relatedRecord) {\n if (!record || !relatedRecord) {\n return\n }\n\n this._setForeignKey(record, relatedRecord)\n },\n\n _setForeignKey (record, relatedRecords) {\n const idAttribute = this.mapper.idAttribute\n\n if (!utils.isArray(relatedRecords)) {\n relatedRecords = [relatedRecords]\n }\n\n relatedRecords.forEach((relatedRecord) => {\n utils.set(relatedRecord, this.foreignKey, utils.get(record, idAttribute))\n })\n },\n\n getLocalField (record) {\n return utils.get(record, this.localField)\n },\n\n setLocalField (record, relatedData) {\n return utils.set(record, this.localField, relatedData)\n },\n\n getInverse (mapper) {\n if (!this.inverse) {\n this.findInverseRelation(mapper)\n }\n\n return this.inverse\n },\n\n findInverseRelation (mapper) {\n this.getRelation().relationList.forEach((def) => {\n if (def.getRelation() === mapper && this.isInversedTo(def)) {\n this.inverse = def\n return true\n }\n })\n },\n\n isInversedTo (def) {\n return !def.foreignKey || def.foreignKey === this.foreignKey\n },\n\n addLinkedRecords (records) {\n const datastore = this.mapper.datastore\n\n records.forEach((record) => {\n let relatedData = this.getLocalField(record)\n\n if (utils.isFunction(this.add)) {\n relatedData = this.add(datastore, this, record)\n } else if (relatedData) {\n relatedData = this.linkRecord(record, relatedData)\n }\n\n const isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length\n\n if (isEmptyLinks && this.canFindLinkFor(record)) {\n relatedData = this.findExistingLinksFor(record)\n }\n\n if (relatedData) {\n this.setLocalField(record, relatedData)\n }\n })\n },\n\n removeLinkedRecords (relatedMapper, records) {\n const localField = this.localField\n records.forEach((record) => {\n const relatedData = utils.get(record, localField)\n this.unlinkInverseRecords(relatedData)\n utils.set(record, localField, undefined)\n })\n },\n\n unlinkInverseRecords (record) {\n if (!record) {\n return\n }\n utils.set(record, this.getInverse(this.mapper).localField, undefined)\n },\n\n linkRecord (record, relatedRecord) {\n const relatedId = utils.get(relatedRecord, this.mapper.idAttribute)\n\n if (relatedId === undefined) {\n const unsaved = this.relatedCollection.unsaved()\n if (unsaved.indexOf(relatedRecord) === -1) {\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n } else {\n if (relatedRecord !== this.relatedCollection.get(relatedId)) {\n this.setForeignKey(record, relatedRecord)\n\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n }\n\n return relatedRecord\n },\n\n // e.g. user hasMany post via \"foreignKey\", so find all posts of user\n findExistingLinksByForeignKey (id) {\n return this.relatedCollection.filter({\n [this.foreignKey]: id\n })\n }\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const BelongsToRelation = Relation.extend({\n getForeignKey (record) {\n return utils.get(record, this.foreignKey)\n },\n\n _setForeignKey (record, relatedRecord) {\n utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute))\n },\n\n findExistingLinksFor (record) {\n // console.log('\\tBelongsTo#findExistingLinksFor', record)\n if (!record) {\n return\n }\n const relatedId = utils.get(record, this.foreignKey)\n if (relatedId !== undefined && relatedId !== null) {\n return this.relatedCollection.get(relatedId)\n }\n }\n}, {\n TYPE_NAME: 'belongsTo'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasManyRelation = Relation.extend({\n validateOptions (related, opts) {\n Relation.prototype.validateOptions.call(this, related, opts)\n\n const { localKeys, foreignKeys, foreignKey } = opts\n\n if (!foreignKey && !localKeys && !foreignKeys) {\n throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey)\n }\n },\n\n canFindLinkFor (record) {\n const hasForeignKeys = this.foreignKey || this.foreignKeys\n return !!(hasForeignKeys || (this.localKeys && utils.get(record, this.localKeys)))\n },\n\n unlinkInverseRecords (records) {\n if (!records) {\n return\n }\n const localField = this.getInverse(this.mapper).localField\n records.forEach(function (record) {\n utils.set(record, localField, undefined)\n })\n },\n\n linkRecord (record, relatedRecords) {\n const relatedCollection = this.relatedCollection\n const canAutoAddLinks = this.canAutoAddLinks\n const foreignKey = this.foreignKey\n const unsaved = this.relatedCollection.unsaved()\n\n return relatedRecords.map((relatedRecord) => {\n const relatedId = relatedCollection.recordId(relatedRecord)\n\n if ((relatedId === undefined && unsaved.indexOf(relatedRecord) === -1) || relatedRecord !== relatedCollection.get(relatedId)) {\n if (foreignKey) {\n // TODO: slow, could be optimized? But user loses hook\n this.setForeignKey(record, relatedRecord)\n }\n if (canAutoAddLinks) {\n relatedRecord = relatedCollection.add(relatedRecord)\n }\n }\n\n return relatedRecord\n })\n },\n\n findExistingLinksFor (record) {\n const id = utils.get(record, this.mapper.idAttribute)\n const ids = this.localKeys ? utils.get(record, this.localKeys) : null\n let records\n\n if (id !== undefined && this.foreignKey) {\n records = this.findExistingLinksByForeignKey(id)\n } else if (this.localKeys && ids) {\n records = this.findExistingLinksByLocalKeys(ids)\n } else if (id !== undefined && this.foreignKeys) {\n records = this.findExistingLinksByForeignKeys(id)\n }\n\n if (records && records.length) {\n return records\n }\n },\n\n // e.g. user hasMany group via \"foreignKeys\", so find all users of a group\n findExistingLinksByLocalKeys (ids) {\n return this.relatedCollection.filter({\n where: {\n [this.mapper.idAttribute]: {\n 'in': ids\n }\n }\n })\n },\n\n // e.g. group hasMany user via \"localKeys\", so find all groups that own a user\n findExistingLinksByForeignKeys (id) {\n return this.relatedCollection.filter({\n where: {\n [this.foreignKeys]: {\n 'contains': id\n }\n }\n })\n }\n}, {\n TYPE_NAME: 'hasMany'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasOneRelation = Relation.extend({\n findExistingLinksFor (relatedMapper, record) {\n const recordId = utils.get(record, relatedMapper.idAttribute)\n const records = this.findExistingLinksByForeignKey(recordId)\n\n if (records.length) {\n return records[0]\n }\n }\n}, {\n TYPE_NAME: 'hasOne'\n})\n","import { Relation } from './Relation'\nimport { BelongsToRelation } from './Relation/BelongsTo'\nimport { HasManyRelation } from './Relation/HasMany'\nimport { HasOneRelation } from './Relation/HasOne'\n\n[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) {\n Relation[RelationType.TYPE_NAME] = function (related, options) {\n return new RelationType(related, options)\n }\n})\n\nexport { belongsToType, hasManyType, hasOneType, Relation } from './Relation'\n","import { Relation } from './relations'\n\nexport { belongsToType, hasManyType, hasOneType } from './relations'\n/**\n * BelongsTo relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.belongsTo\n * @method\n * @param {Mapper} related The relation the target belongs to.\n * @param {Object} opts Configuration options.\n * @param {string} opts.foreignKey The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const belongsTo = function (related, opts) {\n return function (mapper) {\n Relation.belongsTo(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasMany relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasMany\n * @method\n * @param {Mapper} related The relation of which the target has many.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasMany = function (related, opts) {\n return function (mapper) {\n Relation.hasMany(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasOne relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasOne\n * @method\n * @param {Mapper} related The relation of which the target has one.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasOne = function (related, opts) {\n return function (mapper) {\n Relation.hasOne(related, opts).assignTo(mapper)\n }\n}\n","import utils from './utils'\nimport Component from './Component'\nimport Record from './Record'\nimport Schema from './Schema'\nimport { Relation } from './relations'\nimport {\n belongsTo,\n belongsToType,\n hasMany,\n hasManyType,\n hasOne,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Mapper'\nconst applyDefaultsHooks = [\n 'beforeCreate',\n 'beforeCreateMany'\n]\nconst validatingHooks = [\n 'beforeCreate',\n 'beforeCreateMany',\n 'beforeUpdate',\n 'beforeUpdateAll',\n 'beforeUpdateMany'\n]\nconst makeNotify = function (num) {\n return function (...args) {\n const opts = args[args.length - num]\n const op = opts.op\n this.dbg(op, ...args)\n\n if (applyDefaultsHooks.indexOf(op) !== -1 && opts.applyDefaults !== false) {\n const schema = this.getSchema()\n if (schema && schema.applyDefaults) {\n let toProcess = args[0]\n if (!utils.isArray(toProcess)) {\n toProcess = [toProcess]\n }\n toProcess.forEach((record) => {\n schema.applyDefaults(record)\n })\n }\n }\n\n // Automatic validation\n if (validatingHooks.indexOf(op) !== -1 && !opts.noValidate) {\n // Save current value of option\n const originalExistingOnly = opts.existingOnly\n\n // For updates, ignore required fields if they aren't present\n if (op.indexOf('beforeUpdate') === 0 && opts.existingOnly === undefined) {\n opts.existingOnly = true\n }\n const errors = this.validate(args[op === 'beforeUpdate' ? 1 : 0], utils.pick(opts, ['existingOnly']))\n\n // Restore option\n opts.existingOnly = originalExistingOnly\n\n // Abort lifecycle due to validation errors\n if (errors) {\n return utils.reject(errors)\n }\n }\n\n // Emit lifecycle event\n if (opts.notify || (opts.notify === undefined && this.notify)) {\n setTimeout(() => {\n this.emit(op, ...args)\n })\n }\n }\n}\n\n// These are the default implementations of all of the lifecycle hooks\nconst notify = makeNotify(1)\nconst notify2 = makeNotify(2)\n\n// This object provides meta information used by Mapper#crud to actually\n// execute each lifecycle method\nconst LIFECYCLE_METHODS = {\n count: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroy: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroyAll: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n find: {\n defaults: [undefined, {}],\n types: []\n },\n findAll: {\n defaults: [{}, {}],\n types: []\n },\n sum: {\n defaults: [undefined, {}, {}],\n skip: true,\n types: []\n },\n update: {\n adapterArgs (mapper, id, props, opts) {\n return [id, mapper.toJSON(props, opts), opts]\n },\n beforeAssign: 1,\n defaults: [undefined, {}, {}],\n types: []\n },\n updateAll: {\n adapterArgs (mapper, props, query, opts) {\n return [mapper.toJSON(props, opts), query, opts]\n },\n beforeAssign: 0,\n defaults: [{}, {}, {}],\n types: []\n },\n updateMany: {\n adapterArgs (mapper, records, opts) {\n return [records.map(function (record) {\n return mapper.toJSON(record, opts)\n }), opts]\n },\n beforeAssign: 0,\n defaults: [[], {}],\n types: []\n }\n}\n\nconst MAPPER_DEFAULTS = {\n /**\n * Hash of registered adapters. Don't modify directly. Use\n * {@link Mapper#registerAdapter} instead.\n *\n * @default {}\n * @name Mapper#_adapters\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n _adapters: {},\n\n /**\n * Whether {@link Mapper#beforeCreate} and {@link Mapper#beforeCreateMany}\n * should automatically receive default values according to the Mapper's schema.\n *\n * @default true\n * @name Mapper#applyDefaults\n * @since 3.0.0\n * @type {boolean}\n */\n applyDefaults: true,\n\n /**\n * Whether to augment {@link Mapper#recordClass} with ES5 getters and setters\n * according to the properties defined in {@link Mapper#schema}. This makes\n * possible validation and change tracking on individual properties\n * when using the dot (e.g. `user.name = \"Bob\"`) operator to modify a\n * property, and is `true` by default.\n *\n * @default true\n * @name Mapper#applySchema\n * @since 3.0.0\n * @type {boolean}\n */\n applySchema: true,\n\n /**\n * The name of the registered adapter that this Mapper should used by default.\n *\n * @default \"http\"\n * @name Mapper#defaultAdapter\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n * @type {string}\n */\n defaultAdapter: 'http',\n\n /**\n * The field used as the unique identifier on records handled by this Mapper.\n *\n * @default id\n * @name Mapper#idAttribute\n * @since 3.0.0\n * @type {string}\n */\n idAttribute: 'id',\n\n /**\n * Whether this Mapper should emit operational events.\n *\n * @default true\n * @name Mapper#notify\n * @since 3.0.0\n * @type {boolean}\n */\n notify: true,\n\n /**\n * Whether to skip validation when the Record instances are created.\n *\n * @default false\n * @name Mapper#noValidate\n * @since 3.0.0\n * @type {boolean}\n */\n noValidate: false,\n\n /**\n * Whether {@link Mapper#create}, {@link Mapper#createMany},\n * {@link Mapper#update}, {@link Mapper#updateAll}, {@link Mapper#updateMany},\n * {@link Mapper#find}, {@link Mapper#findAll}, {@link Mapper#destroy},\n * {@link Mapper#destroyAll}, {@link Mapper#count}, and {@link Mapper#sum}\n * should return a raw result object that contains both the instance data\n * returned by the adapter _and_ metadata about the operation.\n *\n * The default is to NOT return the result object, and instead return just the\n * instance data.\n *\n * @default false\n * @name Mapper#raw\n * @since 3.0.0\n * @type {boolean}\n */\n raw: false\n}\n\n/**\n * The core of JSData's [ORM/ODM][orm] implementation. Given a minimum amout of\n * meta information about a resource, a Mapper can perform generic CRUD\n * operations against that resource. Apart from its configuration, a Mapper is\n * stateless. The particulars of various persistence layers have been abstracted\n * into adapters, which a Mapper uses to perform its operations.\n *\n * The term \"Mapper\" comes from the [Data Mapper Pattern][pattern] described in\n * Martin Fowler's [Patterns of Enterprise Application Architecture][book]. A\n * Data Mapper moves data between [in-memory object instances][record] and a\n * relational or document-based database. JSData's Mapper can work with any\n * persistence layer you can write an adapter for.\n *\n * _(\"Model\" is a heavily overloaded term and is avoided in this documentation\n * to prevent confusion.)_\n *\n * [orm]: https://en.wikipedia.org/wiki/Object-relational_mapping\n * [pattern]: https://en.wikipedia.org/wiki/Data_mapper_pattern\n * [book]: http://martinfowler.com/books/eaa.html\n * [record]: Record.html\n *\n * @example\n * // Import and instantiate\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @example\n * // Define a Mapper using the Container component\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @class Mapper\n * @extends Component\n * @param {Object} opts Configuration options.\n * @param {boolean} [opts.applySchema=true] See {@link Mapper#applySchema}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {string} [opts.defaultAdapter=http] See {@link Mapper#defaultAdapter}.\n * @param {string} [opts.idAttribute=id] See {@link Mapper#idAttribute}.\n * @param {Object} [opts.methods] See {@link Mapper#methods}.\n * @param {string} opts.name See {@link Mapper#name}.\n * @param {boolean} [opts.notify] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw=false] See {@link Mapper#raw}.\n * @param {Function|boolean} [opts.recordClass] See {@link Mapper#recordClass}.\n * @param {Object|Schema} [opts.schema] See {@link Mapper#schema}.\n * @returns {Mapper} A new {@link Mapper} instance.\n * @see http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n */\nfunction Mapper (opts) {\n utils.classCallCheck(this, Mapper)\n Component.call(this)\n opts || (opts = {})\n\n // Prepare certain properties to be non-enumerable\n Object.defineProperties(this, {\n _adapters: {\n value: undefined,\n writable: true\n },\n\n /**\n * The {@link Container} that holds this Mapper. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n datastore: {\n value: undefined,\n writable: true\n },\n\n /**\n * The meta information describing this Mapper's available lifecycle\n * methods. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n lifecycleMethods: {\n value: LIFECYCLE_METHODS\n },\n\n /**\n * Set to `false` to force the Mapper to work with POJO objects only.\n *\n * @example\n * // Use POJOs only.\n * import {Mapper, Record} from 'js-data'\n * const UserMapper = new Mapper({ recordClass: false })\n * UserMapper.recordClass // false\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n *\n * @example\n * // Set to a custom class to have records wrapped in your custom class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User {\n * constructor (props = {}) {\n * for (var key in props) {\n * if (props.hasOwnProperty(key)) {\n * this[key] = props[key]\n * }\n * }\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n * user instanceof User // true\n *\n *\n * @example\n * // Extend the {@link Record} class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User extends Record {\n * constructor () {\n * super(props)\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // true\n * user instanceof User // true\n *\n * @name Mapper#recordClass\n * @default {@link Record}\n * @see Record\n * @since 3.0.0\n */\n recordClass: {\n value: undefined,\n writable: true\n },\n\n /**\n * This Mapper's {@link Schema}.\n *\n * @example Mapper#schema\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const UserMapper = new Mapper({\n * name: 'user',\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * first: { type: 'string', track: true },\n * last: { type: 'string', track: true },\n * role: { type: 'string', track: true, required: true },\n * age: { type: 'integer', track: true },\n * is_active: { type: 'number' }\n * }\n * }\n * })\n * const user = UserMapper.createRecord({\n * id: 1,\n * name: 'John',\n * role: 'admin'\n * })\n * user.on('change', function (user, changes) {\n * console.log(changes)\n * })\n * user.on('change:role', function (user, value) {\n * console.log('change:role - ' + value)\n * })\n * user.role = 'owner'\n *\n * @name Mapper#schema\n * @see Schema\n * @since 3.0.0\n * @type {Schema}\n */\n schema: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(MAPPER_DEFAULTS))\n\n /**\n * The name for this Mapper. This is the minimum amount of meta information\n * required for a Mapper to be able to execute CRUD operations for a\n * Resource.\n *\n * @name Mapper#name\n * @since 3.0.0\n * @type {string}\n */\n if (!this.name) {\n throw utils.err(`new ${DOMAIN}`, 'opts.name')(400, 'string', this.name)\n }\n\n // Setup schema, with an empty default schema if necessary\n if (this.schema) {\n this.schema.type || (this.schema.type = 'object')\n }\n if (!(this.schema instanceof Schema)) {\n this.schema = new Schema(this.schema || { type: 'object' })\n }\n\n // Create a subclass of Record that's tied to this Mapper\n if (this.recordClass === undefined) {\n const superClass = Record\n this.recordClass = superClass.extend({\n constructor: (function Record () {\n var subClass = function Record (props, opts) {\n utils.classCallCheck(this, subClass)\n superClass.call(this, props, opts)\n }\n return subClass\n })()\n })\n }\n\n if (this.recordClass) {\n this.recordClass.mapper = this\n\n /**\n * Functions that should be added to the prototype of {@link Mapper#recordClass}.\n *\n * @name Mapper#methods\n * @since 3.0.0\n * @type {Object}\n */\n if (utils.isObject(this.methods)) {\n utils.addHiddenPropsToTarget(this.recordClass.prototype, this.methods)\n }\n\n // We can only apply the schema to the prototype of this.recordClass if the\n // class extends Record\n if (Record.prototype.isPrototypeOf(Object.create(this.recordClass.prototype)) && this.schema && this.schema.apply && this.applySchema) {\n this.schema.apply(this.recordClass.prototype)\n }\n }\n}\n\nexport default Component.extend({\n constructor: Mapper,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCount: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroy: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroyAll\n * @param {*} data The `data` returned by the adapter.\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroyAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFind: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFindAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterSum\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterSum: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @since 3.0.0\n */\n beforeCreate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @since 3.0.0\n */\n beforeCreateMany: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @since 3.0.0\n */\n beforeCount: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @since 3.0.0\n */\n beforeDestroy: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroyAll\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @since 3.0.0\n */\n beforeDestroyAll: notify,\n\n /**\n * Mappers lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @since 3.0.0\n */\n beforeFind: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @since 3.0.0\n */\n beforeFindAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeSum\n * @param {string} field The `field` argument passed to {@link Mapper#sum}.\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @since 3.0.0\n */\n beforeSum: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @since 3.0.0\n */\n beforeUpdate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @since 3.0.0\n */\n beforeUpdateAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @since 3.0.0\n */\n beforeUpdateMany: notify,\n\n /**\n * This method is called at the end of most lifecycle methods. It does the\n * following:\n *\n * 1. If `opts.raw` is `true`, add this Mapper's configuration to the `opts`\n * argument as metadata for the operation.\n * 2. Wrap the result data appropriately using {@link Mapper#wrap}, which\n * calls {@link Mapper#createRecord}.\n *\n * @method Mapper#_end\n * @private\n * @since 3.0.0\n */\n _end (result, opts, skip) {\n if (opts.raw) {\n utils._(result, opts)\n }\n if (skip) {\n return result\n }\n let _data = opts.raw ? result.data : result\n if (_data && utils.isFunction(this.wrap)) {\n _data = this.wrap(_data, opts)\n if (opts.raw) {\n result.data = _data\n } else {\n result = _data\n }\n }\n return result\n },\n\n /**\n * Define a belongsTo relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * PostMapper.belongsTo(UserMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to post records at \"post.user\"\n * localField: 'user'\n * })\n *\n * CommentMapper.belongsTo(UserMapper, {\n * // comment.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to comment records at \"comment.user\"\n * localField: 'user'\n * })\n * CommentMapper.belongsTo(PostMapper, {\n * // comment.post_id points to post.id\n * foreignKey: 'post_id'\n * // post records will be attached to comment records at \"comment.post\"\n * localField: 'post'\n * })\n *\n * @method Mapper#belongsTo\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n belongsTo (relatedMapper, opts) {\n return belongsTo(relatedMapper, opts)(this)\n },\n\n /**\n * Select records according to the `query` argument and return the count.\n *\n * {@link Mapper#beforeCount} will be called before calling the adapter.\n * {@link Mapper#afterCount} will be called after calling the adapter.\n *\n * @example\n * // Get the number of published blog posts\n * PostMapper.count({ status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Mapper#count\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `count` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the count of the selected records.\n * @since 3.0.0\n */\n count (query, opts) {\n return this.crud('count', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~beforeCreateListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreate\n * @see Mapper~beforeCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Mapper~beforeCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeCreate}.\n * @see Mapper#event:beforeCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~afterCreateListener} for how to listen for this event.\n *\n * @event Mapper#afterCreate\n * @see Mapper~afterCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Mapper~afterCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterCreate}.\n * @see Mapper#event:afterCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Create and save a new the record using the provided `props`.\n *\n * {@link Mapper#beforeCreate} will be called before calling the adapter.\n * {@link Mapper#afterCreate} will be called after calling the adapter.\n *\n * @example\n * // Create and save a new blog post\n * PostMapper.create({\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#create\n * @param {Object} props The properties for the new record.\n * @param {Object} [opts] Configuration options. Refer to the `create` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `props` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#create}\n * or {@link Mapper#createMany} call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created record.\n * @since 3.0.0\n */\n create (props, opts) {\n let op, adapter\n // Default values for arguments\n props || (props = {})\n opts || (opts = {})\n const originalRecord = props\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreate lifecycle hook\n op = opts.op = 'beforeCreate'\n return utils.resolve(this[op](props, opts)).then((_props) => {\n // Allow for re-assignment from lifecycle hook\n props = _props === undefined ? props : _props\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n const relatedMapper = def.getRelation()\n const relatedIdAttribute = relatedMapper.idAttribute\n optsCopy.raw = false\n if (!relationData) {\n return\n }\n if (def.type === belongsToType) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(relatedMapper.create(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n def.setForeignKey(props, data)\n }))\n } else if (def.type === hasManyType && def.localKeys) {\n // Create his hasMany relation first because it uses localKeys\n tasks.push(relatedMapper.createMany(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n utils.set(props, def.localKeys, data.map((record) => utils.get(record, relatedIdAttribute)))\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter for the main create\n op = opts.op = 'create'\n this.dbg(op, props, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, this.toJSON(props, { with: opts.pass || [] }), opts))\n }).then((result) => {\n const createdRecordData = opts.raw ? result.data : result\n\n // Deep post-create hasMany and hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n if (!relationData) {\n return\n }\n optsCopy.raw = false\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType && def.foreignKey) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === hasOneType) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().create(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === belongsToType && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n } else if (def.type === hasManyType && def.localKeys && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n if (opts.raw) {\n result.data = originalRecord\n } else {\n result = originalRecord\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreate lifecycle hook\n op = opts.op = 'afterCreate'\n return utils.resolve(this[op](props, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Use {@link Mapper#createRecord} instead.\n * @deprecated\n * @method Mapper#createInstance\n * @param {Object|Array} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Object|Array} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n createInstance (props, opts) {\n return this.createRecord(props, opts)\n },\n\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreateMany\n * @see Mapper~beforeCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Mapper~beforeCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Mapper#event:beforeCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~afterCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterCreateMany\n * @see Mapper~afterCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Mapper~afterCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Mapper#event:afterCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Given an array of records, batch create them via an adapter.\n *\n * {@link Mapper#beforeCreateMany} will be called before calling the adapter.\n * {@link Mapper#afterCreateMany} will be called after calling the adapter.\n *\n * @example\n * // Create and save several new blog posts\n * PostMapper.createMany([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#createMany\n * @param {Record[]} records Array of records to be created in one batch.\n * @param {Object} [opts] Configuration options. Refer to the `createMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `records` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#createMany}\n * call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created records.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n createMany (records, opts) {\n let op, adapter\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n const originalRecords = records\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreateMany lifecycle hook\n op = opts.op = 'beforeCreateMany'\n return utils.resolve(this[op](records, opts)).then((_records) => {\n // Allow for re-assignment from lifecycle hook\n records = _records === undefined ? records : _records\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (def.type === belongsToType && relationData.length === records.length) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(def.getRelation().createMany(relationData, optsCopy).then((data) => {\n const relatedRecords = optsCopy.raw ? data.data : data\n def.setLocalField(belongsToRelationData, relatedRecords)\n records.forEach((record, i) => {\n def.setForeignKey(record, relatedRecords[i])\n })\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'createMany'\n const json = records.map((record) => this.toJSON(record, { with: opts.pass || [] }))\n this.dbg(op, records, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, json, opts))\n }).then((result) => {\n const createdRecordsData = opts.raw ? result.data : result\n\n // Deep post-create hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (relationData.length !== records.length) {\n return\n }\n const belongsToData = def.getLocalField(belongsToRelationData)\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType) {\n // Not supported\n this.log('warn', 'deep createMany of hasMany type not supported!')\n } else if (def.type === hasOneType) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setForeignKey(createdRecordData, relationData[i])\n })\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n const relatedData = opts.raw ? result.data : result\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, relatedData[i])\n })\n })\n } else if (def.type === belongsToType && belongsToData && belongsToData.length === createdRecordsData.length) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, belongsToData[i])\n })\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n createdRecordsData.forEach((createdRecordData, i) => {\n const originalRecord = originalRecords[i]\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n })\n if (opts.raw) {\n result.data = originalRecords\n } else {\n result = originalRecords\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreateMany lifecycle hook\n op = opts.op = 'afterCreateMany'\n return utils.resolve(this[op](records, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Create an unsaved, uncached instance of this Mapper's\n * {@link Mapper#recordClass}.\n *\n * Returns `props` if `props` is already an instance of\n * {@link Mapper#recordClass}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * const post = PostMapper.createRecord()\n *\n * @example\n * // Create an unsaved record instance with inital properties\n * const post = PostMapper.createRecord({\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create a record instance that corresponds to a saved record\n * const post = PostMapper.createRecord({\n * // JSData thinks this record has been saved if it has a primary key\n * id: 1234,\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create record instances from an array\n * const posts = PostMapper.createRecord([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }])\n *\n * @example\n * // Records are validated by default\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * try {\n * const post = PostMapper.createRecord({\n * title: 1234,\n * })\n * } catch (err) {\n * console.log(err.errors) // [{ expected: 'one of (string)', actual: 'number', path: 'title' }]\n * }\n *\n * @example\n * // Skip validation\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * const post = PostMapper.createRecord({\n * title: 1234,\n * }, { noValidate: true })\n * console.log(post.isValid()) // false\n *\n * @method Mapper#createRecord\n * @param {Object|Object[]} props The properties for the Record instance or an\n * array of property objects for the Record instances.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @returns {Record|Record[]} The Record instance or Record instances.\n * @since 3.0.0\n */\n createRecord (props, opts) {\n props || (props = {})\n if (utils.isArray(props)) {\n return props.map((_props) => this.createRecord(_props, opts))\n }\n if (!utils.isObject(props)) {\n throw utils.err(`${DOMAIN}#createRecord`, 'props')(400, 'array or object', props)\n }\n const RecordCtor = this.recordClass\n const relationList = this.relationList || []\n relationList.forEach(function (def) {\n const relatedMapper = def.getRelation()\n const relationData = def.getLocalField(props)\n if (relationData && !relatedMapper.is(relationData)) {\n if (utils.isArray(relationData) && (!relationData.length || relatedMapper.is(relationData[0]))) {\n return\n }\n utils.set(props, def.localField, relatedMapper.createRecord(relationData, opts))\n }\n })\n // Check to make sure \"props\" is not already an instance of this Mapper.\n if (RecordCtor && (!(props instanceof RecordCtor))) {\n return new RecordCtor(props, opts)\n }\n return props\n },\n\n /**\n * Lifecycle invocation method. You probably won't call this method directly.\n *\n * @method Mapper#crud\n * @param {string} method Name of the lifecycle method to invoke.\n * @param {...*} args Arguments to pass to the lifecycle method.\n * @returns {Promise}\n * @since 3.0.0\n */\n crud (method, ...args) {\n const config = this.lifecycleMethods[method]\n if (!config) {\n throw utils.err(`${DOMAIN}#crud`, method)(404, 'method')\n }\n\n const upper = `${method.charAt(0).toUpperCase()}${method.substr(1)}`\n const before = `before${upper}`\n const after = `after${upper}`\n\n let op, adapter\n\n // Default values for arguments\n config.defaults.forEach((value, i) => {\n if (args[i] === undefined) {\n args[i] = utils.copy(value)\n }\n })\n\n const opts = args[args.length - 1]\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // before lifecycle hook\n op = opts.op = before\n return utils.resolve(this[op](...args)).then((_value) => {\n if (args[config.beforeAssign] !== undefined) {\n // Allow for re-assignment from lifecycle hook\n args[config.beforeAssign] = _value === undefined ? args[config.beforeAssign] : _value\n }\n // Now delegate to the adapter\n op = opts.op = method\n args = config.adapterArgs ? config.adapterArgs(this, ...args) : args\n this.dbg(op, ...args)\n return utils.resolve(this.getAdapter(adapter)[op](this, ...args))\n }).then((result) => {\n result = this._end(result, opts, !!config.skip)\n args.push(result)\n // after lifecycle hook\n op = opts.op = after\n return utils.resolve(this[op](...args)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~beforeDestroyListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroy\n * @see Mapper~beforeDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Mapper~beforeDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroy}.\n * @see Mapper#event:beforeDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~afterDestroyListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroy\n * @see Mapper~afterDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Mapper~afterDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroy}.\n * @see Mapper#event:afterDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Using an adapter, destroy the record with the given primary key.\n *\n * {@link Mapper#beforeDestroy} will be called before destroying the record.\n * {@link Mapper#afterDestroy} will be called after destroying the record.\n *\n * @example\n * // Destroy a specific blog post\n * PostMapper.destroy(1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @example\n * // Get full response\n * PostMapper.destroy(1234, { raw: true }).then((result) => {\n * console.log(result.deleted) e.g. 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroy\n * @fires Mapper#afterDestroy\n * @method Mapper#destroy\n * @param {(string|number)} id The primary key of the record to destroy.\n * @param {Object} [opts] Configuration options. Refer to the `destroy` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the record has been destroyed. Resolves\n * even if no record was found to be destroyed.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroy (id, opts) {\n return this.crud('destroy', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroyAll\n * @see Mapper~beforeDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Mapper~beforeDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroyAll}.\n * @see Mapper#event:beforeDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroyAll\n * @see Mapper~afterDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Mapper~afterDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroyAll}.\n * @see Mapper#event:afterDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Destroy the records selected by `query` via an adapter. If no `query` is\n * provided then all records will be destroyed.\n *\n * {@link Mapper#beforeDestroyAll} will be called before destroying the records.\n * {@link Mapper#afterDestroyAll} will be called after destroying the records.\n *\n * @example\n * // Destroy all blog posts\n * PostMapper.destroyAll().then(() => {\n * // All blog posts have been destroyed\n * })\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * PostMapper.destroyAll({ status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @example\n * // Get full response\n * const query = null\n * const options = { raw: true }\n * PostMapper.destroyAll(query, options).then((result) => {\n * console.log(result.deleted) e.g. 14\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroyAll\n * @fires Mapper#afterDestroyAll\n * @method Mapper#destroyAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `destroyAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the records have been destroyed. Resolves\n * even if no records were found to be destroyed.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroyAll (query, opts) {\n return this.crud('destroyAll', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~beforeFindListener} for how to listen for this event.\n *\n * @event Mapper#beforeFind\n * @see Mapper~beforeFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Mapper~beforeFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFind}.\n * @see Mapper#event:beforeFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~afterFindListener} for how to listen for this event.\n *\n * @event Mapper#afterFind\n * @see Mapper~afterFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFind} event.\n *\n * @example\n * function onAfterFind (id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Mapper~afterFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFind}.\n * @see Mapper#event:afterFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Retrieve via an adapter the record with the given primary key.\n *\n * {@link Mapper#beforeFind} will be called before calling the adapter.\n * {@link Mapper#afterFind} will be called after calling the adapter.\n *\n * @example\n * PostMapper.find(1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @example\n * // Get full response\n * PostMapper.find(1, { raw: true }).then((result) => {\n * console.log(result.data) // { id: 1, ...}\n * console.log(result.found) // 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFind\n * @fires Mapper#afterFind\n * @method Mapper#find\n * @param {(string|number)} id The primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options. Refer to the `find` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found record. Resolves with\n * `undefined` if no record was found.\n * @see http://www.js-data.io/v3.0/docs/reading-data\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n find (id, opts) {\n return this.crud('find', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~beforeFindAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeFindAll\n * @see Mapper~beforeFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Mapper~beforeFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFindAll}.\n * @see Mapper#event:beforeFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~afterFindAllListener} for how to listen for this event.\n *\n * @event Mapper#afterFindAll\n * @see Mapper~afterFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Mapper~afterFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFindAll}.\n * @see Mapper#event:afterFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, select records to retrieve via an adapter.\n *\n * {@link Mapper#beforeFindAll} will be called before calling the adapter.\n * {@link Mapper#afterFindAll} will be called after calling the adapter.\n *\n * @example\n * // Find all \"published\" blog posts\n * PostMapper.findAll({ status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, status: 'published', ...}, ...]\n * })\n *\n * @example\n * // Get full response\n * PostMapper.findAll({ status: 'published' }, { raw: true }).then((result) => {\n * console.log(result.data) // [{ id: 1, status: 'published', ...}, ...]\n * console.log(result.found) // e.g. 13\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFindAll\n * @fires Mapper#afterFindAll\n * @method Mapper#findAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `findAll` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n findAll (query, opts) {\n return this.crud('findAll', query, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Mapper#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapter (name) {\n this.dbg('getAdapter', 'name:', name)\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Mapper#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || opts.defaultAdapter\n },\n\n /**\n * Get the object of registered adapters for this Mapper.\n *\n * @method Mapper#getAdapters\n * @returns {Object} {@link Mapper#_adapters}\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Returns this Mapper's {@link Schema}.\n *\n * @method Mapper#getSchema\n * @returns {Schema} This Mapper's {@link Schema}.\n * @see Mapper#schema\n * @since 3.0.0\n */\n getSchema () {\n return this.schema\n },\n\n /**\n * Defines a hasMany relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * UserMapper.hasMany(PostMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // post records will be attached to user records at \"user.posts\"\n * localField: 'posts'\n * })\n *\n * @method Mapper#hasMany\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasMany (relatedMapper, opts) {\n return hasMany(relatedMapper, opts)(this)\n },\n\n /**\n * Defines a hasOne relationship. Only useful if you're managing your Mappers\n * manually and not using a {@link Container} or {@link DataStore} component.\n *\n * @example\n * UserMapper.hasOne(ProfileMapper, {\n * // profile.user_id points to user.id\n * foreignKey: 'user_id'\n * // profile records will be attached to user records at \"user.profile\"\n * localField: 'profile'\n * })\n *\n * @method Mapper#hasOne\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasOne (relatedMapper, opts) {\n return hasOne(relatedMapper, opts)(this)\n },\n\n /**\n * Return whether `record` is an instance of this Mapper's recordClass.\n *\n * @example\n * const post = PostMapper.createRecord()\n *\n * console.log(PostMapper.is(post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof PostMapper.recordClass) // true\n *\n * @method Mapper#is\n * @param {Object|Record} record The record to check.\n * @returns {boolean} Whether `record` is an instance of this Mapper's\n * {@link Mapper#recordClass}.\n * @since 3.0.0\n */\n is (record) {\n const recordClass = this.recordClass\n return recordClass ? record instanceof recordClass : false\n },\n\n /**\n * Register an adapter on this Mapper under the given name.\n *\n * @method Mapper#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for this Mapper.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.defaultAdapter = name\n }\n },\n\n /**\n * Select records according to the `query` argument, and aggregate the sum\n * value of the property specified by `field`.\n *\n * {@link Mapper#beforeSum} will be called before calling the adapter.\n * {@link Mapper#afterSum} will be called after calling the adapter.\n *\n * @example\n * PurchaseOrderMapper.sum('amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Mapper#sum\n * @param {string} field The field to sum.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `sum` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the aggregated sum.\n * @since 3.0.0\n */\n sum (field, query, opts) {\n return this.crud('sum', field, query, opts)\n },\n\n /**\n * Return a plain object representation of the given record. Relations can\n * be optionally be included. Non-schema properties can be excluded.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })\n * console.log(PersonMapper.toJSON(person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(PersonMapper.toJSON(person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Mapper#toJSON\n * @param {Record|Record[]} records Record or records from which to create a\n * POJO representation.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the POJO representation.\n * @param {boolean} [opts.withAll] Whether to simply include all relations in\n * the representation. Overrides `opts.with`.\n * @returns {Object|Object[]} POJO representation of the record or records.\n * @since 3.0.0\n */\n toJSON (records, opts) {\n let record\n opts || (opts = {})\n if (utils.isArray(records)) {\n return records.map((record) => this.toJSON(record, opts))\n } else {\n record = records\n }\n const relationFields = (this ? this.relationFields : []) || []\n let json = {}\n let properties\n if (this && this.schema) {\n properties = this.schema.properties || {}\n // TODO: Make this work recursively\n utils.forOwn(properties, (opts, prop) => {\n json[prop] = utils.plainCopy(record[prop])\n })\n }\n properties || (properties = {})\n if (!opts.strict) {\n for (var key in record) {\n if (!properties[key] && relationFields.indexOf(key) === -1) {\n json[key] = utils.plainCopy(record[key])\n }\n }\n }\n // The user wants to include relations in the resulting plain object\n // representation\n if (this && opts.withAll) {\n opts.with = relationFields.slice()\n }\n if (this && opts.with) {\n if (utils.isString(opts.with)) {\n opts.with = [opts.with]\n }\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(record)\n if (relationData) {\n // The actual recursion\n if (utils.isArray(relationData)) {\n def.setLocalField(json, relationData.map((item) => {\n return def.getRelation().toJSON(item, optsCopy)\n }))\n } else {\n def.setLocalField(json, def.getRelation().toJSON(relationData, optsCopy))\n }\n }\n })\n }\n return json\n },\n\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~beforeUpdateListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdate\n * @see Mapper~beforeUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Mapper~beforeUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeUpdate}.\n * @see Mapper#event:beforeUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~afterUpdateListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdate\n * @see Mapper~afterUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Mapper~afterUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterUpdate}.\n * @see Mapper#event:afterUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Using an adapter, update the record with the primary key specified by the\n * `id` argument.\n *\n * {@link Mapper#beforeUpdate} will be called before updating the record.\n * {@link Mapper#afterUpdate} will be called after updating the record.\n *\n * @example\n * // Update a specific post\n * PostMapper.update(1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Mapper#beforeUpdate\n * @fires Mapper#afterUpdate\n * @method Mapper#update\n * @param {(string|number)} id The primary key of the record to update.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options. Refer to the `update` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * transaction.\n * @returns {Promise} Resolves with the updated record. Rejects if the record\n * could not be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n update (id, props, opts) {\n return this.crud('update', id, props, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateAll\n * @see Mapper~beforeUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Mapper~beforeUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Mapper#event:beforeUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateAll\n * @see Mapper~afterUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Mapper~afterUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Mapper#event:afterUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, perform the a single updated to the selected\n * records.\n *\n * {@link Mapper#beforeUpdateAll} will be called before making the update.\n * {@link Mapper#afterUpdateAll} will be called after making the update.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * PostMapper.updateAll(update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateAll\n * @fires Mapper#afterUpdateAll\n * @method Mapper#updateAll\n * @param {Object} props Update to apply to selected records.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `updateAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the update records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateAll (props, query, opts) {\n return this.crud('updateAll', props, query, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateMany\n * @see Mapper~beforeUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Mapper~beforeUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Mapper#event:beforeUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateMany\n * @see Mapper~afterUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Mapper~afterUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Mapper#event:afterUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Given an array of updates, perform each of the updates via an adapter. Each\n * \"update\" is a hash of properties with which to update an record. Each\n * update must contain the primary key of the record to be updated.\n *\n * {@link Mapper#beforeUpdateMany} will be called before making the update.\n * {@link Mapper#afterUpdateMany} will be called after making the update.\n *\n * @example\n * PostMapper.updateMany([\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateMany\n * @fires Mapper#afterUpdateMany\n * @method Mapper#updateMany\n * @param {Record[]} records Array up record updates.\n * @param {Object} [opts] Configuration options. Refer to the `updateMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the updated records. Rejects if any of the\n * records could be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateMany (records, opts) {\n return this.crud('updateMany', records, opts)\n },\n\n /**\n * Validate the given record or records according to this Mapper's\n * {@link Schema}. If there are no validation errors then the return value\n * will be `undefined`.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonSchema = new Schema({\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * })\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: PersonSchema\n * })\n * let errors = PersonMapper.validate({ name: 'John' })\n * console.log(errors) // undefined\n * errors = PersonMapper.validate({ name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Mapper#validate\n * @param {Object|Object[]} record The record or records to validate.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Schema#validate}.\n * @returns {Object[]} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (record, opts) {\n opts || (opts = {})\n const schema = this.getSchema()\n const _opts = utils.pick(opts, ['existingOnly'])\n if (utils.isArray(record)) {\n const errors = record.map((_record) => schema.validate(_record, utils.pick(_opts, ['existingOnly'])))\n let hasErrors = false\n errors.forEach(function (err) {\n if (err) {\n hasErrors = true\n }\n })\n if (hasErrors) {\n return errors\n }\n return undefined\n }\n return schema.validate(record, _opts)\n },\n\n /**\n * Method used to wrap data returned by an adapter with this Mapper's\n * {@link Mapper#recordClass}. This method is used by all of a Mapper's CRUD\n * methods. The provided implementation of this method assumes that the `data`\n * passed to it is a record or records that need to be wrapped with\n * {@link Mapper#createRecord}. Override with care.\n *\n * Provided implementation of {@link Mapper#wrap}:\n *\n * ```\n * function (data, opts) {\n * return this.createRecord(data, opts)\n * }\n * ```\n *\n * @example\n * const PostMapper = new Mapper({\n * name: 'post',\n * // Override to customize behavior\n * wrap (data, opts) {\n * const originalWrap = this.constructor.prototype.wrap\n * // Let's say \"GET /post\" doesn't return JSON quite like JSData expects,\n * // but the actual post records are nested under a \"posts\" field. So,\n * // we override Mapper#wrap to handle this special case.\n * if (opts.op === 'findAll') {\n * return originalWrap.call(this, data.posts, opts)\n * }\n * // Otherwise perform original behavior\n * return originalWrap.call(this, data, opts)\n * }\n * })\n *\n * @method Mapper#wrap\n * @param {Object|Object[]} data The record or records to be wrapped.\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#createRecord}.\n * @returns {Record|Record[]} The wrapped record or records.\n * @since 3.0.0\n */\n wrap (data, opts) {\n return this.createRecord(data, opts)\n },\n\n /**\n * @ignore\n */\n defineRelations () {\n // Setup the mapper's relations, including generating Mapper#relationList\n // and Mapper#relationFields\n utils.forOwn(this.relations, (group, type) => {\n utils.forOwn(group, (relations, _name) => {\n if (utils.isObject(relations)) {\n relations = [relations]\n }\n relations.forEach((def) => {\n const relatedMapper = this.datastore.getMapperByName(_name) || _name\n def.getRelation = () => this.datastore.getMapper(_name)\n\n if (typeof Relation[type] !== 'function') {\n throw utils.err(DOMAIN, 'defineRelations')(400, 'relation type (hasOne, hasMany, etc)', type, true)\n }\n\n this[type](relatedMapper, def)\n })\n })\n })\n }\n})\n\n/**\n * Create a subclass of this Mapper:\n *\n * @example Mapper.extend\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomMapperClass extends Mapper {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customMapper = new CustomMapperClass()\n * console.log(customMapper.foo())\n * console.log(CustomMapperClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherMapperClass = Mapper.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherMapper = new OtherMapperClass()\n * console.log(otherMapper.foo())\n * console.log(OtherMapperClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherMapperClass () {\n * Mapper.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Mapper.extend({\n * constructor: AnotherMapperClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherMapper = new AnotherMapperClass()\n * console.log(anotherMapper.created_at)\n * console.log(anotherMapper.foo())\n * console.log(AnotherMapperClass.beep())\n *\n * @method Mapper.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Mapper class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Mapper from './Mapper'\n\nconst DOMAIN = 'Container'\n\nexport const proxiedMapperMethods = [\n /**\n * Wrapper for {@link Mapper#count}.\n *\n * @example\n * // Get the number of published blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.count('post', { status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Container#count\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#count}.\n * @param {Object} [opts] See {@link Mapper#count}.\n * @returns {Promise} See {@link Mapper#count}.\n * @see Mapper#count\n * @since 3.0.0\n */\n 'count',\n\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~beforeCreateListener} for how to listen for this event.\n *\n * @event Container#beforeCreate\n * @see Container~beforeCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Container~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see Container#event:beforeCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~afterCreateListener} for how to listen for this event.\n *\n * @event Container#afterCreate\n * @see Container~afterCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Container~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see Container#event:afterCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}.\n *\n * @example\n * // Create and save a new blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.create('post', {\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreate\n * @fires Container#afterCreate\n * @method Container#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props See {@link Mapper#create}.\n * @param {Object} [opts] See {@link Mapper#create}.\n * @returns {Promise} See {@link Mapper#create}.\n * @see Mapper#create\n * @since 3.0.0\n */\n 'create',\n\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Container#beforeCreateMany\n * @see Container~beforeCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Container~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Container#event:beforeCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~afterCreateManyListener} for how to listen for this event.\n *\n * @event Container#afterCreateMany\n * @see Container~afterCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Container~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Container#event:afterCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}.\n *\n * @example\n * // Create and save several new blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.createMany('post', [{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreateMany\n * @fires Container#afterCreateMany\n * @method Container#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record[]} records See {@link Mapper#createMany}.\n * @param {Object} [opts] See {@link Mapper#createMany}.\n * @returns {Promise} See {@link Mapper#createMany}.\n * @see Mapper#createMany\n * @since 3.0.0\n */\n 'createMany',\n\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = PostMapper.createRecord()\n *\n * @method Container#createRecord\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Object[]} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Promise} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n 'createRecord',\n\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~beforeDestroyListener} for how to listen for this event.\n *\n * @event Container#beforeDestroy\n * @see Container~beforeDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Container~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see Container#event:beforeDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~afterDestroyListener} for how to listen for this event.\n *\n * @event Container#afterDestroy\n * @see Container~afterDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Container~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see Container#event:afterDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}.\n *\n * @example\n * // Destroy a specific blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroy('post', 1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @fires Container#beforeDestroy\n * @fires Container#afterDestroy\n * @method Container#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#destroy}.\n * @param {Object} [opts] See {@link Mapper#destroy}.\n * @returns {Promise} See {@link Mapper#destroy}.\n * @see Mapper#destroy\n * @since 3.0.0\n */\n 'destroy',\n\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Container#beforeDestroyAll\n * @see Container~beforeDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Container~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see Container#event:beforeDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Container#afterDestroyAll\n * @see Container~afterDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Container~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see Container#event:afterDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}.\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroyAll('post', { status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @fires Container#beforeDestroyAll\n * @fires Container#afterDestroyAll\n * @method Container#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#destroyAll}.\n * @param {Object} [opts] See {@link Mapper#destroyAll}.\n * @returns {Promise} See {@link Mapper#destroyAll}.\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n 'destroyAll',\n\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~beforeFindListener} for how to listen for this event.\n *\n * @event Container#beforeFind\n * @see Container~beforeFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Container~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see Container#event:beforeFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~afterFindListener} for how to listen for this event.\n *\n * @event Container#afterFind\n * @see Container~afterFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Container~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see Container#event:afterFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.find('post', 1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @fires Container#beforeFind\n * @fires Container#afterFind\n * @method Container#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#find}.\n * @param {Object} [opts] See {@link Mapper#find}.\n * @returns {Promise} See {@link Mapper#find}.\n * @see Mapper#find\n * @since 3.0.0\n */\n 'find',\n\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~beforeFindAllListener} for how to listen for this event.\n *\n * @event Container#beforeFindAll\n * @see Container~beforeFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Container~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see Container#event:beforeFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~afterFindAllListener} for how to listen for this event.\n *\n * @event Container#afterFindAll\n * @see Container~afterFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Container~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see Container#event:afterFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * @example\n * // Find all \"published\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.findAll('post', { status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, ...}, ...]\n * })\n *\n * @fires Container#beforeFindAll\n * @fires Container#afterFindAll\n * @method Container#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#findAll}.\n * @param {Object} [opts] See {@link Mapper#findAll}.\n * @returns {Promise} See {@link Mapper#findAll}.\n * @see Mapper#findAll\n * @since 3.0.0\n */\n 'findAll',\n\n /**\n * Wrapper for {@link Mapper#getSchema}.\n *\n * @method Container#getSchema\n * @param {string} name Name of the {@link Mapper} to target.\n * @returns {Schema} See {@link Mapper#getSchema}.\n * @see Mapper#getSchema\n * @since 3.0.0\n */\n 'getSchema',\n\n /**\n * Wrapper for {@link Mapper#is}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = store.createRecord()\n *\n * console.log(store.is('post', post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof store.getMapper('post').recordClass) // true\n *\n * @method Container#is\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Record} record See {@link Mapper#is}.\n * @returns {boolean} See {@link Mapper#is}.\n * @see Mapper#is\n * @since 3.0.0\n */\n 'is',\n\n /**\n * Wrapper for {@link Mapper#sum}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('purchase_order')\n *\n * store.sum('purchase_order', 'amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Container#sum\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {string} field See {@link Mapper#sum}.\n * @param {Object} [query] See {@link Mapper#sum}.\n * @param {Object} [opts] See {@link Mapper#sum}.\n * @returns {Promise} See {@link Mapper#sum}.\n * @see Mapper#sum\n * @since 3.0.0\n */\n 'sum',\n\n /**\n * Wrapper for {@link Mapper#toJSON}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('person', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' })\n * console.log(store.toJSON('person', person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(store.toJSON('person', person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Container#toJSON\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record|Record[]} records See {@link Mapper#toJSON}.\n * @param {Object} [opts] See {@link Mapper#toJSON}.\n * @returns {Object|Object[]} See {@link Mapper#toJSON}.\n * @see Mapper#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~beforeUpdateListener} for how to listen for this event.\n *\n * @event Container#beforeUpdate\n * @see Container~beforeUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Container~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see Container#event:beforeUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~afterUpdateListener} for how to listen for this event.\n *\n * @event Container#afterUpdate\n * @see Container~afterUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Container~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see Container#event:afterUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.update('post', 1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Container#beforeUpdate\n * @fires Container#afterUpdate\n * @method Container#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#update}.\n * @param {Object} record See {@link Mapper#update}.\n * @param {Object} [opts] See {@link Mapper#update}.\n * @returns {Promise} See {@link Mapper#update}.\n * @see Mapper#update\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n 'update',\n\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateAll\n * @see Container~beforeUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Container~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Container#event:beforeUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Container#afterUpdateAll\n * @see Container~afterUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Container~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Container#event:afterUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * store.updateAll('post', update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateAll\n * @fires Container#afterUpdateAll\n * @method Container#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} update See {@link Mapper#updateAll}.\n * @param {Object} [query] See {@link Mapper#updateAll}.\n * @param {Object} [opts] See {@link Mapper#updateAll}.\n * @returns {Promise} See {@link Mapper#updateAll}.\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n 'updateAll',\n\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateMany\n * @see Container~beforeUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Container~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Container#event:beforeUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Container#afterUpdateMany\n * @see Container~afterUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Container~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Container#event:afterUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.updateMany('post', [\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateMany\n * @fires Container#afterUpdateMany\n * @method Container#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#updateMany}.\n * @param {Object} [opts] See {@link Mapper#updateMany}.\n * @returns {Promise} See {@link Mapper#updateMany}.\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n 'updateMany',\n\n /**\n * Wrapper for {@link Mapper#validate}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * let errors = store.validate('post', { name: 'John' })\n * console.log(errors) // undefined\n * errors = store.validate('post', { name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Container#validate\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#validate}.\n * @param {Object} [opts] See {@link Mapper#validate}.\n * @returns {Promise} See {@link Mapper#validate}.\n * @see Mapper#validate\n * @since 3.0.0\n */\n 'validate'\n]\n\n/**\n * The `Container` class is a place to define and store {@link Mapper} instances.\n *\n * `Container` makes it easy to manage your Mappers. Without a container, you\n * need to manage Mappers yourself, including resolving circular dependencies\n * among relations. All Mappers in a container share the same adapters, so you\n * don't have to register adapters for every single Mapper.\n *\n * @example Container#constructor\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n *\n * @class Container\n * @extends Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {Constructor} [opts.mapperClass] See {@link Container#mapperClass}.\n * @param {Object} [opts.mapperDefaults] See {@link Container#mapperDefaults}.\n * @since 3.0.0\n */\nexport function Container (opts) {\n utils.classCallCheck(this, Container)\n Component.call(this)\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * The adapters registered with this Container, which are also shared by all\n * Mappers in this Container.\n *\n * @name Container#_adapters\n * @see Container#registerAdapter\n * @since 3.0.0\n * @type {Object}\n */\n _adapters: {\n value: {}\n },\n\n /**\n * The the mappers in this container\n *\n * @name Container#_mappers\n * @see Mapper\n * @since 3.0.0\n * @type {Object}\n */\n _mappers: {\n value: {}\n },\n\n /**\n * Constructor function to use in {@link Container#defineMapper} to create new\n * {@link Mapper} instances. {@link Container#mapperClass} should extend\n * {@link Mapper}. By default {@link Mapper} is used to instantiate Mappers.\n *\n * @example Container#mapperClass\n * // import {Container, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const store = new Container({\n * mapperClass: MyMapperClass\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').foo())\n *\n * @name Container#mapperClass\n * @see Mapper\n * @since 3.0.0\n * @type {Constructor}\n */\n mapperClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply options provided by the user\n utils.fillIn(this, opts)\n\n /**\n * Defaults options to pass to {@link Container#mapperClass} when creating a\n * new {@link Mapper}.\n *\n * @example Container#mapperDefaults\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: {\n * idAttribute: '_id'\n * }\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').idAttribute)\n *\n * @default {}\n * @name Container#mapperDefaults\n * @since 3.0.0\n * @type {Object}\n */\n this.mapperDefaults = this.mapperDefaults || {}\n\n // Use the Mapper class if the user didn't provide a mapperClass\n this.mapperClass || (this.mapperClass = Mapper)\n}\n\nconst props = {\n constructor: Container,\n\n /**\n * Register a new event listener on this Container.\n *\n * Proxy for {@link Component#on}. If an event was emitted by a {@link Mapper}\n * in the Container, then the name of the {@link Mapper} will be prepended to\n * the arugments passed to the listener.\n *\n * @example Container#on\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.on('foo', function (...args) { console.log(args.join(':')) })\n * store.defineMapper('user')\n * store.emit('foo', 'arg1', 'arg2')\n * store.getMapper('user').emit('foo', 'arg1', 'arg2')\n *\n * @method Container#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n\n /**\n * Used to bind to events emitted by mappers in this container.\n *\n * @method Container#_onMapperEvent\n * @param {string} name Name of the mapper that emitted the event.\n * @param {...*} [args] Args See {@link Mapper#emit}.\n * @private\n * @since 3.0.0\n */\n _onMapperEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * Return a container scoped to a particular mapper.\n *\n * @example Container#as\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method Container#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} A container scoped to a particular mapper.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n proxiedMapperMethods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Create a new mapper and register it in this container.\n *\n * @example Container#defineMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: { foo: 'bar' }\n * })\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(UserMapper.foo)\n *\n * @method Container#defineMapper\n * @param {string} name Name under which to register the new {@link Mapper}.\n * {@link Mapper#name} will be set to this value.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Container#mapperClass} when creating the new {@link Mapper}.\n * @returns {Mapper} The newly created instance of {@link Mapper}.\n * @see Container#as\n * @since 3.0.0\n */\n defineMapper (name, opts) {\n // For backwards compatibility with defineResource\n if (utils.isObject(name)) {\n opts = name\n name = opts.name\n }\n if (!utils.isString(name)) {\n throw utils.err(`${DOMAIN}#defineMapper`, 'name')(400, 'string', name)\n }\n\n // Default values for arguments\n opts || (opts = {})\n // Set Mapper#name\n opts.name = name\n opts.relations || (opts.relations = {})\n\n // Check if the user is overriding the datastore's default mapperClass\n const mapperClass = opts.mapperClass || this.mapperClass\n delete opts.mapperClass\n\n // Apply the datastore's defaults to the options going into the mapper\n utils.fillIn(opts, this.mapperDefaults)\n\n // Instantiate a mapper\n const mapper = this._mappers[name] = new mapperClass(opts) // eslint-disable-line\n mapper.relations || (mapper.relations = {})\n // Make sure the mapper's name is set\n mapper.name = name\n // All mappers in this datastore will share adapters\n mapper._adapters = this.getAdapters()\n\n mapper.datastore = this\n\n mapper.on('all', (...args) => this._onMapperEvent(name, ...args))\n mapper.defineRelations()\n\n return mapper\n },\n\n defineResource (name, opts) {\n console.warn('DEPRECATED: defineResource is deprecated, use defineMapper instead')\n return this.defineMapper(name, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Container#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n */\n getAdapter (name) {\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Container#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || this.mapperDefaults.defaultAdapter\n },\n\n /**\n * Return the registered adapters of this container.\n *\n * @method Container#getAdapters\n * @returns {Adapter}\n * @since 3.0.0\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Return the mapper registered under the specified name.\n *\n * @example Container#getMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * store.getMapper('profile') // throws Error, there is no mapper with name \"profile\"\n *\n * @method Container#getMapper\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapper (name) {\n const mapper = this.getMapperByName(name)\n if (!mapper) {\n throw utils.err(`${DOMAIN}#getMapper`, name)(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Return the mapper registered under the specified name.\n * Doesn't throw error if mapper doesn't exist.\n *\n * @example Container#getMapperByName\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(store.getMapper('profile')) // Does NOT throw an error\n *\n * @method Container#getMapperByName\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapperByName (name) {\n return this._mappers[name]\n },\n\n /**\n * Register an adapter on this container under the given name. Adapters\n * registered on a container are shared by all mappers in the container.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n *\n * @method Container#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for all Mappers in this container.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.mapperDefaults.defaultAdapter = name\n utils.forOwn(this._mappers, function (mapper) {\n mapper.defaultAdapter = name\n })\n }\n }\n}\n\nproxiedMapperMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getMapper(name)[method](...args)\n }\n})\n\nComponent.extend(props)\n\n/**\n * Create a subclass of this Container:\n * @example Container.extend\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomContainerClass extends Container {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customContainer = new CustomContainerClass()\n * console.log(customContainer.foo())\n * console.log(CustomContainerClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherContainerClass = Container.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherContainer = new OtherContainerClass()\n * console.log(otherContainer.foo())\n * console.log(OtherContainerClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherContainerClass () {\n * Container.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Container.extend({\n * constructor: AnotherContainerClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherContainer = new AnotherContainerClass()\n * console.log(anotherContainer.created_at)\n * console.log(anotherContainer.foo())\n * console.log(AnotherContainerClass.beep())\n *\n * @method Container.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Container class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport './decorators'\nimport Collection from './Collection'\n\nconst DOMAIN = 'LinkedCollection'\n\n/**\n * Extends {@link Collection}. Used by a {@link DataStore} to implement an\n * Identity Map.\n *\n * ```javascript\n * import {LinkedCollection} from 'js-data'\n * ```\n *\n * @class LinkedCollection\n * @extends Collection\n * @param {Array} [records] Initial set of records to insert into the\n * collection. See {@link Collection}.\n * @param {Object} [opts] Configuration options. See {@link Collection}.\n * @returns {Mapper}\n */\nfunction LinkedCollection (records, opts) {\n utils.classCallCheck(this, LinkedCollection)\n // Make sure this collection has somewhere to store \"added\" timestamps\n Object.defineProperties(this, {\n _added: {\n value: {}\n },\n datastore: {\n writable: true,\n value: undefined\n }\n })\n\n Collection.call(this, records, opts)\n\n // Make sure this collection has a reference to a datastore\n if (!this.datastore) {\n throw utils.err(`new ${DOMAIN}`, 'opts.datastore')(400, 'DataStore', this.datastore)\n }\n}\n\nexport default Collection.extend({\n constructor: LinkedCollection,\n\n _addMeta (record, timestamp) {\n // Track when this record was added\n this._added[this.recordId(record)] = timestamp\n\n if (utils.isFunction(record._set)) {\n record._set('$', timestamp)\n }\n },\n\n _clearMeta (record) {\n delete this._added[this.recordId(record)]\n if (utils.isFunction(record._set)) {\n record._set('$') // unset\n }\n },\n\n _onRecordEvent (...args) {\n Collection.prototype._onRecordEvent.apply(this, args)\n const event = args[0]\n // This is a very brute force method\n // Lots of room for optimization\n if (utils.isString(event) && event.indexOf('change') === 0) {\n this.updateIndexes(args[1])\n }\n },\n\n add (records, opts) {\n const mapper = this.mapper\n const timestamp = new Date().getTime()\n const singular = utils.isObject(records) && !utils.isArray(records)\n\n if (singular) {\n records = [records]\n }\n records = Collection.prototype.add.call(this, records, opts)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.addLinkedRecords(records)\n })\n }\n\n records.forEach((record) => this._addMeta(record, timestamp))\n\n return singular ? records[0] : records\n },\n\n remove (idOrRecord, opts) {\n const mapper = this.mapper\n const record = Collection.prototype.remove.call(this, idOrRecord, opts)\n if (record) {\n this._clearMeta(record)\n }\n\n if (mapper.relationList.length && record) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, [record])\n })\n }\n\n return record\n },\n\n removeAll (query, opts) {\n const mapper = this.mapper\n const records = Collection.prototype.removeAll.call(this, query, opts)\n records.forEach(this._clearMeta, this)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, records)\n })\n }\n\n return records\n }\n})\n\n/**\n * Create a subclass of this LinkedCollection:\n *\n * @example LinkedCollection.extend\n * // Normally you would do: import {LinkedCollection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {LinkedCollection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomLinkedCollectionClass extends LinkedCollection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customLinkedCollection = new CustomLinkedCollectionClass()\n * console.log(customLinkedCollection.foo())\n * console.log(CustomLinkedCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherLinkedCollectionClass = LinkedCollection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherLinkedCollection = new OtherLinkedCollectionClass()\n * console.log(otherLinkedCollection.foo())\n * console.log(OtherLinkedCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherLinkedCollectionClass () {\n * LinkedCollection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * LinkedCollection.extend({\n * constructor: AnotherLinkedCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherLinkedCollection = new AnotherLinkedCollectionClass()\n * console.log(anotherLinkedCollection.created_at)\n * console.log(anotherLinkedCollection.foo())\n * console.log(AnotherLinkedCollectionClass.beep())\n *\n * @method LinkedCollection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this LinkedCollection class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\nimport {proxiedMapperMethods, Container} from './Container'\nimport LinkedCollection from './LinkedCollection'\n\nconst DOMAIN = 'DataStore'\nconst proxiedCollectionMethods = [\n /**\n * Wrapper for {@link LinkedCollection#add}.\n *\n * @example DataStore#add\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n *\n * // Add one book to the in-memory store:\n * store.add('book', { id: 1, title: 'Respect your Data' })\n * // Add multiple books to the in-memory store:\n * store.add('book', [\n * { id: 2, title: 'Easy data recipes' },\n * { id: 3, title: 'Active Record 101' }\n * ])\n *\n * @fires DataStore#add\n * @method DataStore#add\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Object[]|Record|Record[])} data See {@link LinkedCollection#add}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#add}.\n * @returns {(Object|Object[]|Record|Record[])} See {@link LinkedCollection#add}.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n 'add',\n\n /**\n * Wrapper for {@link LinkedCollection#between}.\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = store.between('user', 18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = store.between('user', [18], [30], { index: 'age' })\n *\n * @method DataStore#between\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Array} leftKeys See {@link LinkedCollection#between}.\n * @param {Array} rightKeys See {@link LinkedCollection#between}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#between}.\n * @returns {Object[]|Record[]} See {@link LinkedCollection#between}.\n * @see LinkedCollection#between\n * @see Collection#between\n * @since 3.0.0\n */\n 'between',\n\n /**\n * Wrapper for {@link LinkedCollection#createIndex}.\n *\n * @example\n * // Index users by age\n * store.createIndex('user', 'age')\n *\n * @example\n * // Index users by status and role\n * store.createIndex('user', 'statusAndRole', ['status', 'role'])\n *\n * @method DataStore#createIndex\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {string} name See {@link LinkedCollection#createIndex}.\n * @param {string[]} [fieldList] See {@link LinkedCollection#createIndex}.\n * @see LinkedCollection#createIndex\n * @see Collection#createIndex\n * @since 3.0.0\n */\n 'createIndex',\n\n /**\n * Wrapper for {@link LinkedCollection#filter}.\n *\n * @example DataStore#filter\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = store.filter('post', function (post) { return post.id % 2 === 0 })\n *\n * @method DataStore#filter\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Function)} [queryOrFn={}] See {@link LinkedCollection#filter}.\n * @param {Object} [thisArg] See {@link LinkedCollection#filter}.\n * @returns {Array} See {@link LinkedCollection#filter}.\n * @see LinkedCollection#filter\n * @see Collection#filter\n * @since 3.0.0\n */\n 'filter',\n\n /**\n * Wrapper for {@link LinkedCollection#get}.\n *\n * @example DataStore#get\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * console.log(store.get('post', 1)) // {...}\n * console.log(store.get('post', 2)) // undefined\n *\n * @method DataStore#get\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link LinkedCollection#get}.\n * @returns {(Object|Record)} See {@link LinkedCollection#get}.\n * @see LinkedCollection#get\n * @see Collection#get\n * @since 3.0.0\n */\n 'get',\n\n /**\n * Wrapper for {@link LinkedCollection#getAll}.\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = store.getAll('post', 'draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = store.getAll('post', ['draft'], ['inReview'], { index: 'status' })\n *\n * @method DataStore#getAll\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {...Array} [keyList] See {@link LinkedCollection#getAll}.\n * @param {Object} [opts] See {@link LinkedCollection#getAll}.\n * @returns {Array} See {@link LinkedCollection#getAll}.\n * @see LinkedCollection#getAll\n * @see Collection#getAll\n * @since 3.0.0\n */\n 'getAll',\n\n /**\n * Wrapper for {@link LinkedCollection#prune}.\n *\n * @method DataStore#prune\n * @param {Object} [opts] See {@link LinkedCollection#prune}.\n * @returns {Array} See {@link LinkedCollection#prune}.\n * @see LinkedCollection#prune\n * @see Collection#prune\n * @since 3.0.0\n */\n 'prune',\n\n /**\n * Wrapper for {@link LinkedCollection#query}.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * store.query('user')\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method DataStore#query\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @returns {Query} See {@link LinkedCollection#query}.\n * @see LinkedCollection#query\n * @see Collection#query\n * @since 3.0.0\n */\n 'query',\n\n /**\n * Wrapper for {@link LinkedCollection#toJSON}.\n *\n * @example\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * title: { type: 'string' }\n * }\n * }\n * })\n * store.add('post', [\n * { id: 1, status: 'published', title: 'Respect your Data' },\n * { id: 2, status: 'draft', title: 'Connecting to a data source' }\n * ])\n * console.log(store.toJSON('post'))\n * const draftsJSON = store.query('post')\n * .filter({ status: 'draft' })\n * .mapCall('toJSON')\n * .run()\n *\n * @method DataStore#toJSON\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Object} [opts] See {@link LinkedCollection#toJSON}.\n * @returns {Array} See {@link LinkedCollection#toJSON}.\n * @see LinkedCollection#toJSON\n * @see Collection#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Wrapper for {@link LinkedCollection#unsaved}.\n *\n * @method DataStore#unsaved\n * @returns {Array} See {@link LinkedCollection#unsaved}.\n * @see LinkedCollection#unsaved\n * @see Collection#unsaved\n * @since 3.0.0\n */\n 'unsaved'\n]\nconst ownMethodsForScoping = [\n 'addToCache',\n 'cachedFind',\n 'cachedFindAll',\n 'cacheFind',\n 'cacheFindAll',\n 'hashQuery'\n]\n\nconst safeSetProp = function (record, field, value) {\n if (record && record._set) {\n record._set(`props.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nconst safeSetLink = function (record, field, value) {\n if (record && record._set) {\n record._set(`links.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nconst cachedFn = function (name, hashOrId, opts) {\n const cached = this._completedQueries[name][hashOrId]\n if (utils.isFunction(cached)) {\n return cached(name, hashOrId, opts)\n }\n return cached\n}\n\nconst DATASTORE_DEFAULTS = {\n /**\n * Whether in-memory relations should be unlinked from records after they are\n * destroyed.\n *\n * @default true\n * @name DataStore#unlinkOnDestroy\n * @since 3.0.0\n * @type {boolean}\n */\n unlinkOnDestroy: true,\n\n /**\n * Whether to use the pending query if a `find` request for the specified\n * record is currently underway. Can be set to `true`, `false`, or to a\n * function that returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFind\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFind: true,\n\n /**\n * Whether to use the pending query if a `findAll` request for the given query\n * is currently underway. Can be set to `true`, `false`, or to a function that\n * returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFindAll\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFindAll: true\n}\n\n/**\n * The `DataStore` class is an extension of {@link Container}. Not only does\n * `DataStore` manage mappers, but also collections. `DataStore` implements the\n * asynchronous {@link Mapper} methods, such as {@link Mapper#find} and\n * {@link Mapper#create}. If you use the asynchronous `DataStore` methods\n * instead of calling them directly on the mappers, then the results of the\n * method calls will be inserted into the store's collections. You can think of\n * a `DataStore` as an [Identity Map](https://en.wikipedia.org/wiki/Identity_map_pattern)\n * for the [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)\n * (the Mappers).\n *\n * ```javascript\n * import {DataStore} from 'js-data'\n * ```\n *\n * @example\n * import {DataStore} from 'js-data'\n * import HttpAdapter from 'js-data-http'\n * const store = new DataStore()\n *\n * // DataStore#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n *\n * // DataStore#as returns the store scoped to a particular Mapper.\n * const UserStore = store.as('user')\n *\n * // Call \"find\" on \"UserMapper\" (Stateless ORM)\n * UserMapper.find(1).then((user) => {\n * // retrieved a \"user\" record via the http adapter, but that's it\n *\n * // Call \"find\" on \"store\" targeting \"user\" (Stateful DataStore)\n * return store.find('user', 1) // same as \"UserStore.find(1)\"\n * }).then((user) => {\n * // not only was a \"user\" record retrieved, but it was added to the\n * // store's \"user\" collection\n * const cachedUser = store.getCollection('user').get(1)\n * console.log(user === cachedUser) // true\n * })\n *\n * @class DataStore\n * @extends Container\n * @param {Object} [opts] Configuration options. See {@link Container}.\n * @param {boolean} [opts.collectionClass={@link LinkedCollection}] See {@link DataStore#collectionClass}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {boolean} [opts.unlinkOnDestroy=true] See {@link DataStore#unlinkOnDestroy}.\n * @param {boolean|Function} [opts.usePendingFind=true] See {@link DataStore#usePendingFind}.\n * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link DataStore#usePendingFindAll}.\n * @returns {DataStore}\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/working-with-the-datastore\",\"Working with the DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/jsdata-and-the-browser\",\"Notes on using JSData in the Browser\"]\n */\nfunction DataStore (opts) {\n utils.classCallCheck(this, DataStore)\n\n opts || (opts = {})\n // Fill in any missing options with the defaults\n utils.fillIn(opts, DATASTORE_DEFAULTS)\n Container.call(this, opts)\n\n this.collectionClass = this.collectionClass || LinkedCollection\n this._collections = {}\n this._pendingQueries = {}\n this._completedQueries = {}\n}\n\nconst props = {\n constructor: DataStore,\n\n _callSuper (method, ...args) {\n return this.constructor.__super__.prototype[method].apply(this, args)\n },\n\n /**\n * Internal method used to handle Mapper responses.\n *\n * @method DataStore#_end\n * @private\n * @param {string} name Name of the {@link LinkedCollection} to which to\n * add the data.\n * @param {Object} result The result from a Mapper.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object|Array)} Result.\n */\n _end (name, result, opts) {\n let data = opts.raw ? result.data : result\n if (data && utils.isFunction(this.addToCache)) {\n data = this.addToCache(name, data, opts)\n if (opts.raw) {\n result.data = data\n } else {\n result = data\n }\n }\n return result\n },\n\n /**\n * Register a new event listener on this DataStore.\n *\n * Proxy for {@link Container#on}. If an event was emitted by a Mapper or\n * Collection in the DataStore, then the name of the Mapper or Collection will\n * be prepended to the arugments passed to the provided event handler.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * store.on('add', (mapperName, records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * store.on('change', (mapperName, record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method DataStore#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n */\n\n /**\n * Used to bind to events emitted by collections in this store.\n *\n * @method DataStore#_onCollectionEvent\n * @private\n * @param {string} name Name of the collection that emitted the event.\n * @param {...*} [args] Args passed to {@link Collection#emit}.\n */\n _onCollectionEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * This method takes the data received from {@link DataStore#find},\n * {@link DataStore#findAll}, {@link DataStore#update}, etc., and adds the\n * data to the store. _You don't need to call this method directly._\n *\n * If you're using the http adapter and your response data is in an unexpected\n * format, you may need to override this method so the right data gets added\n * to the store.\n *\n * @example\n * const store = new DataStore({\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return DataStore.prototype.addToCache.call(this, mapperName, data, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return super.addToCache(mapperName, data, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#addToCache\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {*} data Data from which data should be selected for add.\n * @param {Object} [opts] Configuration options.\n */\n addToCache (name, data, opts) {\n return this.getCollection(name).add(data, opts)\n },\n\n /**\n * Return the store scoped to a particular mapper/collection pair.\n *\n * @example DataStore.as\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method DataStore#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} The store, scoped to a particular Mapper/Collection pair.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n const methods = ownMethodsForScoping\n .concat(proxiedMapperMethods)\n .concat(proxiedCollectionMethods)\n\n methods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n props.getCollection = {\n writable: true,\n value () {\n return original.getCollection(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Retrieve a cached `find` result, if any. This method is called during\n * {@link DataStore#find} to determine if {@link Mapper#find} needs to be\n * called. If this method returns `undefined` then {@link Mapper#find} will\n * be called. Otherwise {@link DataStore#find} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFind.call(this, mapperName, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cachedFind(mapperName, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cachedFind: cachedFn,\n\n /**\n * Retrieve a cached `findAll` result, if any. This method is called during\n * {@link DataStore#findAll} to determine if {@link Mapper#findAll} needs to be\n * called. If this method returns `undefined` then {@link Mapper#findAll} will\n * be called. Otherwise {@link DataStore#findAll} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return super.cachedFindAll(mapperName, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cachedFindAll: cachedFn,\n\n /**\n * Mark a {@link Mapper#find} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `find` entry is\n * added it means subsequent calls to the same Resource with the same `id`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#get} instead of delegating to {@link Mapper#find}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cacheFind.call(this, mapperName, data, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cacheFind(mapperName, data, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {*} data The result to cache.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cacheFind (name, data, id, opts) {\n this._completedQueries[name][id] = (name, id, opts) => this.get(name, id)\n },\n\n /**\n * Mark a {@link Mapper#findAll} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `findAll` entry is\n * added it means subsequent calls to the same Resource with the same `query`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#filter} instead of delegating to {@link Mapper#findAll}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, data, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return super.cachedFindAll(mapperName, data, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {*} data The result to cache.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cacheFindAll (name, data, hash, opts) {\n this._completedQueries[name][hash] = (name, hash, opts) => this.filter(name, utils.fromJson(hash))\n },\n\n /**\n * Remove __all__ records from the in-memory store and reset\n * {@link DataStore#_completedQueries}.\n *\n * @method DataStore#clear\n * @returns {Object} Object containing all records that were in the store.\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n clear () {\n const removed = {}\n utils.forOwn(this._collections, (collection, name) => {\n removed[name] = collection.removeAll()\n this._completedQueries[name] = {}\n })\n return removed\n },\n\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~beforeCreateListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreate\n * @see DataStore~beforeCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback DataStore~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see DataStore#event:beforeCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~afterCreateListener} for how to listen for this event.\n *\n * @event DataStore#afterCreate\n * @see DataStore~afterCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback DataStore~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see DataStore#event:afterCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}. Adds the created record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book {\"author_id\":1234,...}\n * store.create('book', {\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }).then((book) => {\n * console.log(book.id) // 120392\n * console.log(book.title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreate\n * @fires DataStore#afterCreate\n * @fires DataStore#add\n * @method DataStore#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} record Passed to {@link Mapper#create}.\n * @param {Object} [opts] Passed to {@link Mapper#create}. See\n * {@link Mapper#create} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n create (name, record, opts) {\n opts || (opts = {})\n return this._callSuper('create', name, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~beforeCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreateMany\n * @see DataStore~beforeCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback DataStore~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see DataStore#event:beforeCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~afterCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterCreateMany\n * @see DataStore~afterCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback DataStore~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see DataStore#event:afterCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}. Adds the created records to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book [{\"author_id\":1234,...},{...}]\n * store.createMany('book', [{\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }, {\n * author_id: 1234,\n * edition: 'Second Edition',\n * title: 'Respect your Data'\n * }]).then((books) => {\n * console.log(books[0].id) // 142394\n * console.log(books[0].title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreateMany\n * @fires DataStore#afterCreateMany\n * @fires DataStore#add\n * @method DataStore#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Array} records Passed to {@link Mapper#createMany}.\n * @param {Object} [opts] Passed to {@link Mapper#createMany}. See\n * {@link Mapper#createMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n createMany (name, records, opts) {\n opts || (opts = {})\n return this._callSuper('createMany', name, records, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n defineMapper (name, opts) {\n // Complexity of this method is beyond simply using => functions to bind context\n const self = this\n const mapper = Container.prototype.defineMapper.call(self, name, opts)\n self._pendingQueries[name] = {}\n self._completedQueries[name] = {}\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n\n // The datastore uses a subclass of Collection that is \"datastore-aware\"\n const collection = self._collections[name] = new self.collectionClass(null, { // eslint-disable-line\n // Make sure the collection has somewhere to store \"added\" timestamps\n _added: {},\n // Give the collection a reference to this datastore\n datastore: self,\n // The mapper tied to the collection\n mapper\n })\n\n const schema = mapper.schema || {}\n const properties = schema.properties || {}\n // TODO: Make it possible index nested properties?\n utils.forOwn(properties, function (opts, prop) {\n if (opts.indexed) {\n collection.createIndex(prop)\n }\n })\n\n // Create a secondary index on the \"added\" timestamps of records in the\n // collection\n collection.createIndex('addedTimestamps', ['$'], {\n fieldGetter (obj) {\n return collection._added[collection.recordId(obj)]\n }\n })\n\n collection.on('all', function (...args) {\n self._onCollectionEvent(name, ...args)\n })\n\n const idAttribute = mapper.idAttribute\n\n mapper.relationList.forEach(function (def) {\n const relation = def.relation\n const localField = def.localField\n const path = `links.${localField}`\n const foreignKey = def.foreignKey\n const type = def.type\n const updateOpts = { index: foreignKey }\n let descriptor\n\n const getter = function () { return this._get(path) }\n\n if (type === belongsToType) {\n if (!collection.indexes[foreignKey]) {\n collection.createIndex(foreignKey)\n }\n\n descriptor = {\n get: getter,\n // e.g. profile.user = someUser\n // or comment.post = somePost\n set (record) {\n // e.g. const otherUser = profile.user\n const currentParent = this._get(path)\n // e.g. profile.user === someUser\n if (record === currentParent) {\n return currentParent\n }\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n\n // e.g. profile.user !== someUser\n // or comment.post !== somePost\n if (currentParent) {\n // e.g. otherUser.profile = undefined\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n // e.g. remove comment from otherPost.comments\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n if (record) {\n // e.g. profile.user = someUser\n const relatedIdAttribute = def.getRelation().idAttribute\n const relatedId = utils.get(record, relatedIdAttribute)\n\n // Prefer store record\n if (relatedId !== undefined && this._get('$')) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n // e.g. profile.user = someUser\n // or comment.post = somePost\n safeSetLink(this, localField, record)\n safeSetProp(this, foreignKey, relatedId)\n collection.updateIndex(this, updateOpts)\n\n // Update (set) inverse relation\n if (inverseDef.type === hasOneType) {\n // e.g. someUser.profile = profile\n safeSetLink(record, inverseDef.localField, this)\n } else if (inverseDef.type === hasManyType) {\n // e.g. add comment to somePost.comments\n const children = utils.get(record, inverseDef.localField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n } else {\n // Unset in-memory link only\n // e.g. profile.user = undefined\n // or comment.post = undefined\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n\n let foreignKeyDescriptor = Object.getOwnPropertyDescriptor(mapper.recordClass.prototype, foreignKey)\n if (!foreignKeyDescriptor) {\n foreignKeyDescriptor = {\n enumerable: true\n }\n }\n const originalGet = foreignKeyDescriptor.get\n foreignKeyDescriptor.get = function () {\n if (originalGet) {\n return originalGet.call(this)\n }\n return this._get(`props.${foreignKey}`)\n }\n const originalSet = foreignKeyDescriptor.set\n foreignKeyDescriptor.set = function (value) {\n if (originalSet) {\n originalSet.call(this, value)\n }\n const currentParent = utils.get(this, localField)\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n const currentParentId = currentParent ? utils.get(currentParent, def.getRelation().idAttribute) : undefined\n\n if (currentParent && currentParentId !== undefined && currentParentId !== value) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n\n safeSetProp(this, foreignKey, value)\n collection.updateIndex(this, updateOpts)\n\n if ((value === undefined || value === null)) {\n if (currentParentId !== undefined) {\n // Unset locals\n utils.set(this, localField, undefined)\n }\n } else if (this._get('$')) {\n const storeRecord = self.get(relation, value)\n if (storeRecord) {\n utils.set(this, localField, storeRecord)\n }\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, foreignKey, foreignKeyDescriptor)\n } else if (type === hasManyType) {\n const localKeys = def.localKeys\n const foreignKeys = def.foreignKeys\n\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n\n descriptor = {\n get () {\n let current = getter.call(this)\n if (!current) {\n this._set(path, [])\n }\n return getter.call(this)\n },\n // e.g. post.comments = someComments\n // or user.groups = someGroups\n // or group.users = someUsers\n set (records) {\n if (records && !utils.isArray(records)) {\n records = [records]\n }\n const id = utils.get(this, idAttribute)\n const relatedIdAttribute = def.getRelation().idAttribute\n const inverseDef = def.getInverse(mapper)\n const inverseLocalField = inverseDef.localField\n const current = this._get(path) || []\n const toLink = []\n const toLinkIds = {}\n\n if (records) {\n records.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n const currentParent = utils.get(record, inverseLocalField)\n if (currentParent && currentParent !== this) {\n const currentChildrenOfParent = utils.get(currentParent, localField)\n // e.g. somePost.comments.remove(comment)\n if (relatedId === undefined) {\n utils.remove(currentChildrenOfParent, (child) => child === record)\n } else {\n utils.remove(currentChildrenOfParent, (child) => child === record || relatedId === utils.get(child, relatedIdAttribute))\n }\n }\n if (relatedId !== undefined) {\n if (this._get('$')) {\n // Prefer store record\n record = self.get(relation, relatedId) || record\n }\n // e.g. toLinkIds[comment.id] = comment\n toLinkIds[relatedId] = record\n }\n toLink.push(record)\n })\n }\n\n // e.g. post.comments = someComments\n if (foreignKey) {\n current.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(record) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update (unset) inverse relation\n if (records) {\n // e.g. comment.post_id = undefined\n safeSetProp(record, foreignKey, undefined)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n }\n // e.g. comment.post = undefined\n safeSetLink(record, inverseLocalField, undefined)\n }\n })\n toLink.forEach((record) => {\n // Update (set) inverse relation\n // e.g. comment.post_id = post.id\n safeSetProp(record, foreignKey, id)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n // e.g. comment.post = post\n safeSetLink(record, inverseLocalField, this)\n })\n } else if (localKeys) {\n // Update locals\n // e.g. group.users = someUsers\n // Update (set) inverse relation\n const ids = toLink.map((child) => utils.get(child, relatedIdAttribute)).filter((id) => id !== undefined)\n // e.g. group.user_ids = [1,2,3,...]\n utils.set(this, localKeys, ids)\n // Update (unset) inverse relation\n if (inverseDef.foreignKeys) {\n current.forEach((child) => {\n const relatedId = utils.get(child, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(child) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update inverse relation\n // safeSetLink(child, inverseLocalField, undefined)\n const parents = utils.get(child, inverseLocalField) || []\n // e.g. someUser.groups.remove(group)\n if (id === undefined) {\n utils.remove(parents, (parent) => parent === this)\n } else {\n utils.remove(parents, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n }\n })\n toLink.forEach((child) => {\n // Update (set) inverse relation\n const parents = utils.get(child, inverseLocalField)\n // e.g. someUser.groups.push(group)\n if (id === undefined) {\n utils.noDupeAdd(parents, this, (parent) => parent === this)\n } else {\n utils.noDupeAdd(parents, this, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n })\n }\n } else if (foreignKeys) {\n // e.g. user.groups = someGroups\n // Update (unset) inverse relation\n current.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n // e.g. someGroup.user_ids.remove(user.id)\n utils.remove(ids, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n // e.g. someGroup.users.remove(user)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n // Update (set) inverse relation\n toLink.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n utils.noDupeAdd(ids, id, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n }\n\n this._set(path, toLink)\n return toLink\n }\n }\n } else if (type === hasOneType) {\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n descriptor = {\n get: getter,\n // e.g. user.profile = someProfile\n set (record) {\n const current = this._get(path)\n if (record === current) {\n return current\n }\n const inverseLocalField = def.getInverse(mapper).localField\n if (record) {\n // Update (unset) inverse relation\n if (current) {\n safeSetProp(current, foreignKey, undefined)\n self.getCollection(relation).updateIndex(current, updateOpts)\n safeSetLink(current, inverseLocalField, undefined)\n }\n const relatedId = utils.get(record, def.getRelation().idAttribute)\n // Prefer store record\n if (relatedId !== undefined) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n safeSetLink(this, localField, record)\n\n // Update (set) inverse relation\n safeSetProp(record, foreignKey, utils.get(this, idAttribute))\n self.getCollection(relation).updateIndex(record, updateOpts)\n safeSetLink(record, inverseLocalField, this)\n } else {\n // Unset locals\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n }\n\n if (descriptor) {\n descriptor.enumerable = def.enumerable === undefined ? false : def.enumerable\n if (def.get) {\n let origGet = descriptor.get\n descriptor.get = function () {\n return def.get(def, this, (...args) => origGet.apply(this, args))\n }\n }\n if (def.set) {\n let origSet = descriptor.set\n descriptor.set = function (related) {\n return def.set(def, this, related, (value) => origSet.call(this, value === undefined ? related : value))\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, localField, descriptor)\n }\n })\n\n return mapper\n },\n\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~beforeDestroyListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroy\n * @see DataStore~beforeDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback DataStore~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see DataStore#event:beforeDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~afterDestroyListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroy\n * @see DataStore~afterDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback DataStore~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see DataStore#event:afterDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}. Removes any destroyed record from the\n * in-memory store. Clears out any {@link DataStore#_completedQueries} entries\n * associated with the provided `id`.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is no longer in the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n *\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroy\n * @fires DataStore#afterDestroy\n * @fires DataStore#remove\n * @method DataStore#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#destroy}.\n * @param {Object} [opts] Passed to {@link Mapper#destroy}. See\n * {@link Mapper#destroy} for more configuration options.\n * @returns {Promise} Resolves when the destroy operation completes.\n * @since 3.0.0\n */\n destroy (name, id, opts) {\n opts || (opts = {})\n return this._callSuper('destroy', name, id, opts).then((result) => {\n const record = this.getCollection(name).remove(id, opts)\n\n if (record && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n utils.set(record, def.localField, undefined)\n })\n }\n\n if (opts.raw) {\n result.data = record\n } else {\n result = record\n }\n delete this._pendingQueries[name][id]\n delete this._completedQueries[name][id]\n return result\n })\n },\n\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroyAll\n * @see DataStore~beforeDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback DataStore~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see DataStore#event:beforeDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~afterDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroyAll\n * @see DataStore~afterDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback DataStore~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see DataStore#event:afterDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}. Removes any destroyed records from\n * the in-memory store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is gone from the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroyAll\n * @fires DataStore#afterDestroyAll\n * @fires DataStore#remove\n * @method DataStore#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper#destroyAll}.\n * @param {Object} [opts] Passed to {@link Mapper#destroyAll}. See\n * {@link Mapper#destroyAll} for more configuration options.\n * @returns {Promise} Resolves when the delete completes.\n * @since 3.0.0\n */\n destroyAll (name, query, opts) {\n opts || (opts = {})\n return this._callSuper('destroyAll', name, query, opts).then((result) => {\n const records = this.getCollection(name).removeAll(query, opts)\n\n if (records && records.length && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n records.forEach((record) => {\n utils.set(record, def.localField, undefined)\n })\n })\n }\n\n if (opts.raw) {\n result.data = records\n } else {\n result = records\n }\n const hash = this.hashQuery(name, query, opts)\n delete this._pendingQueries[name][hash]\n delete this._completedQueries[name][hash]\n return result\n })\n },\n\n eject (name, id, opts) {\n console.warn('DEPRECATED: \"eject\" is deprecated, use \"remove\" instead')\n return this.remove(name, id, opts)\n },\n\n ejectAll (name, query, opts) {\n console.warn('DEPRECATED: \"ejectAll\" is deprecated, use \"removeAll\" instead')\n return this.removeAll(name, query, opts)\n },\n\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~beforeFindListener} for how to listen for this event.\n *\n * @event DataStore#beforeFind\n * @see DataStore~beforeFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback DataStore~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see DataStore#event:beforeFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~afterFindListener} for how to listen for this event.\n *\n * @event DataStore#afterFind\n * @see DataStore~afterFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback DataStore~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see DataStore#event:afterFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}. Adds any found record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /book/1234\n * store.find('book', 1234).then((book) => {\n * // The book record is now in the in-memory store\n * console.log(store.get('book', 1234) === book) // true\n * })\n *\n * @fires DataStore#beforeFind\n * @fires DataStore#afterFind\n * @fires DataStore#add\n * @method DataStore#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#find}.\n * @param {Object} [opts] Passed to {@link Mapper#find}.\n * @param {boolean|Function} [opts.usePendingFind] See {@link DataStore#usePendingFind}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n find (name, id, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const pendingQuery = this._pendingQueries[name][id]\n const usePendingFind = opts.usePendingFind === undefined ? this.usePendingFind : opts.usePendingFind\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFind) ? usePendingFind.call(this, name, id, opts) : usePendingFind)) {\n return pendingQuery\n }\n const item = this.cachedFind(name, id, opts)\n let promise\n\n if (opts.force || !item) {\n promise = this._pendingQueries[name][id] = this._callSuper('find', name, id, opts).then((result) => {\n delete this._pendingQueries[name][id]\n result = this._end(name, result, opts)\n this.cacheFind(name, result, id, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][id]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(item)\n }\n return promise\n },\n\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~beforeFindAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeFindAll\n * @see DataStore~beforeFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback DataStore~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see DataStore#event:beforeFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~afterFindAllListener} for how to listen for this event.\n *\n * @event DataStore#afterFindAll\n * @see DataStore~afterFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback DataStore~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see DataStore#event:afterFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#findAll}. Adds any found records to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('movie')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /movie?rating=PG\n * store.find('movie', { rating: 'PG' }).then((movies) => {\n * // The movie records are now in the in-memory store\n * console.log(store.filter('movie'))\n * })\n *\n * @fires DataStore#beforeFindAll\n * @fires DataStore#afterFindAll\n * @fires DataStore#add\n * @method DataStore#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper.findAll}.\n * @param {Object} [opts] Passed to {@link Mapper.findAll}.\n * @param {boolean|Function} [opts.usePendingFindAll] See {@link DataStore#usePendingFindAll}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n findAll (name, query, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const hash = this.hashQuery(name, query, opts)\n const pendingQuery = this._pendingQueries[name][hash]\n const usePendingFindAll = opts.usePendingFindAll === undefined ? this.usePendingFindAll : opts.usePendingFindAll\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFindAll) ? usePendingFindAll.call(this, name, query, opts) : usePendingFindAll)) {\n return pendingQuery\n }\n\n const items = this.cachedFindAll(name, hash, opts)\n let promise\n\n if (opts.force || !items) {\n promise = this._pendingQueries[name][hash] = this._callSuper('findAll', name, query, opts).then((result) => {\n delete this._pendingQueries[name][hash]\n result = this._end(name, result, opts)\n this.cacheFindAll(name, result, hash, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][hash]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(items)\n }\n return promise\n },\n\n /**\n * Return the {@link LinkedCollection} with the given name, if for some\n * reason you need a direct reference to the collection.\n *\n * @method DataStore#getCollection\n * @param {string} name Name of the {@link LinkedCollection} to retrieve.\n * @returns {LinkedCollection}\n * @since 3.0.0\n * @throws {Error} Thrown if the specified {@link LinkedCollection} does not\n * exist.\n */\n getCollection (name) {\n const collection = this._collections[name]\n if (!collection) {\n throw utils.err(`${DOMAIN}#getCollection`, name)(404, 'collection')\n }\n return collection\n },\n\n /**\n * Hashing function used to cache {@link DataStore#find} and\n * {@link DataStore#findAll} requests. This method simply JSONifies the\n * `query` argument passed to {@link DataStore#find} or\n * {@link DataStore#findAll}.\n *\n * Override this method for custom hashing behavior.\n * @method DataStore#hashQuery\n * @param {string} name The `name` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @param {Object} query The `query` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @returns {string} The JSONified `query`.\n * @since 3.0.0\n */\n hashQuery (name, query, opts) {\n return utils.toJson(query)\n },\n\n inject (name, records, opts) {\n console.warn('DEPRECATED: \"inject\" is deprecated, use \"add\" instead')\n return this.add(name, records, opts)\n },\n\n /**\n * Wrapper for {@link LinkedCollection#remove}. Removes the specified\n * {@link Record} from the store.\n *\n * @example DataStore#remove\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n * console.log(store.getAll('book').length)\n * store.add('book', { id: 1234 })\n * console.log(store.getAll('book').length)\n * store.remove('book', 1234)\n * console.log(store.getAll('book').length)\n *\n * @fires DataStore#remove\n * @method DataStore#remove\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {string|number} id The primary key of the {@link Record} to remove.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n remove (name, id, opts) {\n const record = this.getCollection(name).remove(id, opts)\n if (record) {\n this.removeRelated(name, [record], opts)\n }\n return record\n },\n\n /**\n * Wrapper for {@link LinkedCollection#removeAll}. Removes the selected\n * {@link Record}s from the store.\n *\n * @example DataStore#removeAll\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('movie')\n * console.log(store.getAll('movie').length)\n * store.add('movie', [{ id: 3, rating: 'R' }, { id: 4, rating: 'PG-13' })\n * console.log(store.getAll('movie').length)\n * store.removeAll('movie', { rating: 'R' })\n * console.log(store.getAll('movie').length)\n *\n * @fires DataStore#remove\n * @method DataStore#removeAll\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}s, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n removeAll (name, query, opts) {\n const records = this.getCollection(name).removeAll(query, opts)\n if (records.length) {\n this.removeRelated(name, records, opts)\n }\n return records\n },\n\n /**\n * Remove from the store {@link Record}s that are related to the provided\n * {@link Record}(s).\n *\n * @fires DataStore#remove\n * @method DataStore#removeRelated\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Record|Record[]} records {@link Record}s whose relations are to be\n * removed.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record}(s) to remove\n * from the store.\n * @since 3.0.0\n */\n removeRelated (name, records, opts) {\n if (!utils.isArray(records)) {\n records = [records]\n }\n utils.forEachRelation(this.getMapper(name), opts, (def, optsCopy) => {\n records.forEach((record) => {\n let relatedData\n let query\n if (def.foreignKey && (def.type === hasOneType || def.type === hasManyType)) {\n query = { [def.foreignKey]: def.getForeignKey(record) }\n } else if (def.type === hasManyType && def.localKeys) {\n query = {\n where: {\n [def.getRelation().idAttribute]: {\n 'in': utils.get(record, def.localKeys)\n }\n }\n }\n } else if (def.type === hasManyType && def.foreignKeys) {\n query = {\n where: {\n [def.foreignKeys]: {\n 'contains': def.getForeignKey(record)\n }\n }\n }\n } else if (def.type === belongsToType) {\n relatedData = this.remove(def.relation, def.getForeignKey(record), optsCopy)\n }\n if (query) {\n relatedData = this.removeAll(def.relation, query, optsCopy)\n }\n if (relatedData) {\n if (utils.isArray(relatedData) && !relatedData.length) {\n return\n }\n if (def.type === hasOneType) {\n relatedData = relatedData[0]\n }\n def.setLocalField(record, relatedData)\n }\n })\n })\n },\n\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~beforeUpdateListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdate\n * @see DataStore~beforeUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback DataStore~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see DataStore#event:beforeUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~afterUpdateListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdate\n * @see DataStore~afterUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback DataStore~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see DataStore#event:afterUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}. Adds the updated {@link Record} to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post/1234 {\"status\":\"published\"}\n * store.update('post', 1, { status: 'published' }).then((post) => {\n * // The post record has also been updated in the in-memory store\n * console.log(store.get('post', 1234))\n * })\n *\n * @fires DataStore#beforeUpdate\n * @fires DataStore#afterUpdate\n * @fires DataStore#add\n * @method DataStore#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#update}.\n * @param {Object} record Passed to {@link Mapper#update}.\n * @param {Object} [opts] Passed to {@link Mapper#update}. See\n * {@link Mapper#update} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n update (name, id, record, opts) {\n opts || (opts = {})\n return this._callSuper('update', name, id, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateAll\n * @see DataStore~beforeUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback DataStore~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see DataStore#event:beforeUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~afterUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateAll\n * @see DataStore~afterUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback DataStore~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see DataStore#event:afterUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post?author_id=1234 {\"status\":\"published\"}\n * store.updateAll('post', { author_id: 1234 }, { status: 'published' }).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.filter('posts', { author_id: 1234 }))\n * })\n *\n * @fires DataStore#beforeUpdateAll\n * @fires DataStore#afterUpdateAll\n * @fires DataStore#add\n * @method DataStore#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props Passed to {@link Mapper#updateAll}.\n * @param {Object} [query] Passed to {@link Mapper#updateAll}.\n * @param {Object} [opts] Passed to {@link Mapper#updateAll}. See\n * {@link Mapper#updateAll} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateAll (name, props, query, opts) {\n opts || (opts = {})\n return this._callSuper('updateAll', name, query, props, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateMany\n * @see DataStore~beforeUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback DataStore~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see DataStore#event:beforeUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~afterUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateMany\n * @see DataStore~afterUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback DataStore~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see DataStore#event:afterUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post [{\"id\":3,status\":\"published\"},{\"id\":4,status\":\"published\"}]\n * store.updateMany('post', [\n * { id: 3, status: 'published' },\n * { id: 4, status: 'published' }\n * ]).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.getAll('post', 3, 4))\n * })\n *\n * @fires DataStore#beforeUpdateMany\n * @fires DataStore#afterUpdateMany\n * @fires DataStore#add\n * @method DataStore#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records Passed to {@link Mapper#updateMany}.\n * @param {Object} [opts] Passed to {@link Mapper#updateMany}. See\n * {@link Mapper#updateMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateMany (name, records, opts) {\n opts || (opts = {})\n return this._callSuper('updateMany', name, records, opts)\n .then((result) => this._end(name, result, opts))\n }\n}\n\nproxiedCollectionMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getCollection(name)[method](...args)\n }\n})\n\nexport default Container.extend(props)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link DataStore~changeListener} on how to listen for this event.\n *\n * @event DataStore#change\n * @see DataStore~changeListener\n */\n\n/**\n * Callback signature for the {@link DataStore#event:change} event.\n *\n * @example\n * function onChange (mapperName, record, changes) {\n * // do something\n * }\n * store.on('change', onChange)\n *\n * @callback DataStore~changeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record} record The Record that changed.\n * @param {Object} changes The changes.\n * @see DataStore#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the in-memory store. See\n * {@link DataStore~addListener} on how to listen for this event.\n *\n * @event DataStore#add\n * @see DataStore~addListener\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n */\n\n/**\n * Callback signature for the {@link DataStore#event:add} event.\n *\n * @example\n * function onAdd (mapperName, recordOrRecords) {\n * // do something\n * }\n * store.on('add', onAdd)\n *\n * @callback DataStore~addListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} The Record or Records that were added.\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the in-memory store. See\n * {@link DataStore~removeListener} for how to listen for this event.\n *\n * @event DataStore#remove\n * @see DataStore~removeListener\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n */\n\n/**\n * Callback signature for the {@link DataStore#event:remove} event.\n *\n * @example\n * function onRemove (mapperName, recordsOrRecords) {\n * // do something\n * }\n * store.on('remove', onRemove)\n *\n * @callback DataStore~removeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} Record or Records that were removed.\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this DataStore:\n * @example DataStore.extend\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomDataStoreClass extends DataStore {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customDataStore = new CustomDataStoreClass()\n * console.log(customDataStore.foo())\n * console.log(CustomDataStoreClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherDataStoreClass = DataStore.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherDataStore = new OtherDataStoreClass()\n * console.log(otherDataStore.foo())\n * console.log(OtherDataStoreClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherDataStoreClass () {\n * DataStore.call(this)\n * this.created_at = new Date().getTime()\n * }\n * DataStore.extend({\n * constructor: AnotherDataStoreClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherDataStore = new AnotherDataStoreClass()\n * console.log(anotherDataStore.created_at)\n * console.log(anotherDataStore.foo())\n * console.log(AnotherDataStoreClass.beep())\n *\n * @method DataStore.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this DataStore class.\n * @since 3.0.0\n */\n","/**\n * Registered as `js-data` in NPM and Bower.\n *\n * Also available from CDN.JS and JSDelivr.\n *\n * @module js-data\n *\n * @example Install from NPM\n * npm i --save js-data@beta\n * @example Install from Bower\n * bower i --save js-data@3.0.0-beta.1\n * @example Install from CDN.JS\n * \n * @example Install from JSDelivr\n * \n * @example Load into your app via script tag\n * \n * \n * @example Load into your app via CommonJS\n * var JSData = require('js-data');\n * @example Load into your app via ES2015 Modules\n * import * as JSData from 'js-data';\n * @example Load into your app via AMD\n * define('myApp', ['js-data'], function (JSData) { ... })\n */\n\n/**\n * Describes the version of this `JSData` object.\n *\n * @example\n * console.log(JSData.version.full) // \"3.0.0-beta.1\"\n *\n * @name version\n * @memberof module:js-data\n * @property {string} full The full semver value.\n * @property {number} major The major version number.\n * @property {number} minor The minor version number.\n * @property {number} patch The patch version number.\n * @property {(string|boolean)} alpha The alpha version value, otherwise `false`\n * if the current version is not alpha.\n * @property {(string|boolean)} beta The beta version value, otherwise `false`\n * if the current version is not beta.\n * @since 2.0.0\n * @type {Object}\n */\nexport const version = '<%= version %>'\n\n/**\n * JSData's utility methods.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @name module:js-data.utils\n * @property {Function} Promise See {@link utils.Promise}.\n * @see utils\n * @since 3.0.0\n * @type {Object}\n */\nimport utils from './utils'\n\n/**\n * JSData's {@link Collection} class.\n *\n * @example\n * import {Collection} from 'js-data'\n * const collection = new Collection()\n *\n * @name module:js-data.Collection\n * @see Collection\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#collection\",\"Components of JSData: Collection\"]\n * @type {Constructor}\n */\nimport Collection from './Collection'\n\n/**\n * JSData's {@link Component} class. Most components in JSData extend this\n * class.\n *\n * @example\n * import {Component} from 'js-data'\n * // Make a custom component.\n * const MyComponent = Component.extend({\n * myMethod (someArg) { ... }\n * })\n *\n * @name module:js-data.Component\n * @see Component\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Component from './Component'\n\n/**\n * JSData's {@link Container} class. Defines and manages {@link Mapper}s. Used\n * in Node.js and in the browser, though in the browser you may want to use\n * {@link DataStore} instead.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n *\n * @name module:js-data.Container\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#container\",\"Components of JSData: Container\"]\n * @type {Constructor}\n */\nimport {Container} from './Container'\n\n/**\n * JSData's {@link DataStore} class. Primarily for use in the browser. In\n * Node.js you probably want to use {@link Container} instead.\n *\n * @example\n * import {DataStore} from 'js-data'\n * const store = new DataStore()\n *\n * @name module:js-data.DataStore\n * @see DataStore\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @type {Constructor}\n */\nimport DataStore from './DataStore'\n\n/**\n * JSData's {@link Index} class, based on [mindex]{@link https://github.com/internalfx/mindex}.\n *\n * @name module:js-data.Index\n * @see Index\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Index from '../lib/mindex/index'\n\n/**\n * JSData's {@link LinkedCollection} class. Used by the {@link DataStore}\n * component. If you need to create a collection manually, you should probably\n * use the {@link Collection} class.\n *\n * @name module:js-data.LinkedCollection\n * @see DataStore\n * @see LinkedCollection\n * @since 3.0.0\n * @type {Constructor}\n */\nimport LinkedCollection from './LinkedCollection'\n\n/**\n * JSData's {@link Mapper} class. The core of the ORM.\n *\n * @example Recommended use\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @example Create Mapper manually\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @name module:js-data.Mapper\n * @see Container\n * @see Mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @type {Constructor}\n */\nimport Mapper from './Mapper'\n\n/**\n * JSData's {@link Query} class. Used by the {@link Collection} component.\n *\n * @name module:js-data.Query\n * @see Query\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Query from './Query'\n\n/**\n * JSData's {@link Record} class.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n *\n * @name module:js-data.Record\n * @see Record\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#record\",\"Components of JSData: Record\"]\n * @type {Constructor}\n */\nimport Record from './Record'\n\n/**\n * JSData's {@link Schema} class. Implements http://json-schema.org/draft-04.\n *\n * @example\n * import {Container, Schema} from 'js-data'\n * const userSchema = new Schema({\n * properties: {\n * id: { type: 'string' },\n * name: { type: 'string' }\n * }\n * })\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: userSchema\n * })\n *\n * @name module:js-data.Schema\n * @see Schema\n * @see http://json-schema.org/\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#schema\",\"Components of JSData: schema\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/schemas\",\"JSData's Schema Syntax\"]\n * @type {Constructor}\n */\nimport Schema from './Schema'\n\n/**\n * JSData's {@link Settable} class.\n *\n * @example\n * import {Settable} from 'js-data'\n * const obj = new Settable()\n * obj.set('secret', 'value')\n * console.log(JSON.stringify(obj)) // {}\n *\n * @name module:js-data.Settable\n * @see Settable\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Settable from './Settable'\n\nexport * from './decorators'\n\nexport {\n Collection,\n Component,\n Container,\n DataStore,\n Index,\n LinkedCollection,\n Mapper,\n Query,\n Record,\n Schema,\n Settable,\n utils\n}\n"],"names":["DOMAIN","Component","Query","Schema","Record","_belongsTo","_hasMany","_hasOne","Mapper","Collection","LinkedCollection","props"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["../src/utils.js","../src/Settable.js","../src/Component.js","../src/Query.js","../lib/mindex/_utils.js","../lib/mindex/index.js","../src/Collection.js","../src/Relation.js","../src/Relation/BelongsTo.js","../src/Relation/HasMany.js","../src/Relation/HasOne.js","../src/relations.js","../src/decorators.js","../src/Record.js","../src/Schema.js","../src/Mapper.js","../src/Container.js","../src/LinkedCollection.js","../src/DataStore.js","../src/index.js"],"sourcesContent":["/**\n * Utility methods used by JSData.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @namespace utils\n * @type {Object}\n */\n\nconst DOMAIN = 'utils'\n\nconst INFINITY = 1 / 0\nconst MAX_INTEGER = 1.7976931348623157e+308\nconst BOOL_TAG = '[object Boolean]'\nconst DATE_TAG = '[object Date]'\nconst FUNC_TAG = '[object Function]'\nconst NUMBER_TAG = '[object Number]'\nconst OBJECT_TAG = '[object Object]'\nconst REGEXP_TAG = '[object RegExp]'\nconst STRING_TAG = '[object String]'\nconst objToString = Object.prototype.toString\nconst PATH = /^(.+)\\.(.+)$/\n\nconst ERRORS = {\n '400' () { return `expected: ${arguments[0]}, found: ${arguments[2] ? arguments[1] : typeof arguments[1]}` },\n '404' () { return `${arguments[0]} not found` }\n}\n\nconst toInteger = function (value) {\n if (!value) {\n return 0\n }\n // Coerce to number\n value = +value\n if (value === INFINITY || value === -INFINITY) {\n const sign = (value < 0 ? -1 : 1)\n return sign * MAX_INTEGER\n }\n const remainder = value % 1\n return value === value ? (remainder ? value - remainder : value) : 0 // eslint-disable-line\n}\n\nconst toStr = function (value) {\n return objToString.call(value)\n}\n\nconst isPlainObject = function (value) {\n return (!!value && typeof value === 'object' && value.constructor === Object)\n}\n\nconst mkdirP = function (object, path) {\n if (!path) {\n return object\n }\n const parts = path.split('.')\n parts.forEach(function (key) {\n if (!object[key]) {\n object[key] = {}\n }\n object = object[key]\n })\n return object\n}\n\nconst utils = {\n /**\n * Reference to the Promise constructor used by JSData. Defaults to\n * `window.Promise` or `global.Promise`.\n *\n * @example Make JSData use a different `Promise` constructor\n * import Promise from 'bluebird'\n * import {utils} from 'js-data'\n * utils.Promise = Promise\n *\n * @name utils.Promise\n * @since 3.0.0\n * @type {Function}\n */\n Promise: Promise,\n\n /**\n * Shallow copy properties that meet the following criteria from `src` to\n * `dest`:\n *\n * - own enumerable\n * - not a function\n * - does not start with \"_\"\n *\n * @method utils._\n * @param {Object} dest Destination object.\n * @param {Object} src Source object.\n * @private\n * @since 3.0.0\n */\n _ (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (key && dest[key] === undefined && !utils.isFunction(value) && key.indexOf('_') !== 0) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Recursively iterates over relations found in `opts.with`.\n *\n * @method utils._forRelation\n * @param {Object} opts Configuration options.\n * @param {Relation} def Relation definition.\n * @param {Function} fn Callback function.\n * @param {*} [thisArg] Execution context for the callback function.\n * @private\n * @since 3.0.0\n */\n _forRelation (opts, def, fn, thisArg) {\n const relationName = def.relation\n let containedName = null\n let index\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n if ((index = utils._getIndex(opts.with, relationName)) >= 0) {\n containedName = relationName\n } else if ((index = utils._getIndex(opts.with, def.localField)) >= 0) {\n containedName = def.localField\n }\n\n if (opts.withAll) {\n fn.call(thisArg, def, {})\n return\n } else if (!containedName) {\n return\n }\n let optsCopy = {}\n utils.fillIn(optsCopy, def.getRelation())\n utils.fillIn(optsCopy, opts)\n optsCopy.with = opts.with.slice()\n optsCopy._activeWith = optsCopy.with.splice(index, 1)[0]\n optsCopy.with.forEach(function (relation, i) {\n if (relation && relation.indexOf(containedName) === 0 && relation.length >= containedName.length && relation[containedName.length] === '.') {\n optsCopy.with[i] = relation.substr(containedName.length + 1)\n } else {\n optsCopy.with[i] = ''\n }\n })\n fn.call(thisArg, def, optsCopy)\n },\n\n /**\n * Find the index of a relation in the given list\n *\n * @method utils._getIndex\n * @param {string[]} list List to search.\n * @param {string} relation Relation to find.\n * @private\n * @returns {number}\n */\n _getIndex (list, relation) {\n let index = -1\n list.forEach(function (_relation, i) {\n if (_relation === relation) {\n index = i\n return false\n } else if (utils.isObject(_relation)) {\n if (_relation.relation === relation) {\n index = i\n return false\n }\n }\n })\n return index\n },\n\n /**\n * Define hidden (non-enumerable), writable properties on `target` from the\n * provided `props`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {}\n * utils.addHiddenPropsToTarget(Cat.prototype, {\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat.say() // \"meow\"\n *\n * @method utils.addHiddenPropsToTarget\n * @param {Object} target That to which `props` should be added.\n * @param {Object} props Properties to be added to `target`.\n * @since 3.0.0\n */\n addHiddenPropsToTarget (target, props) {\n const map = {}\n Object.keys(props).forEach(function (propName) {\n const descriptor = Object.getOwnPropertyDescriptor(props, propName)\n\n descriptor.enumerable = false\n map[propName] = descriptor\n })\n Object.defineProperties(target, map)\n },\n\n /**\n * Return whether the two objects are deeply different.\n *\n * @example\n * import {utils} from 'js-data'\n * utils.areDifferent({}, {}) // false\n * utils.areDifferent({ a: 1 }, { a: 1 }) // false\n * utils.areDifferent({ foo: 'bar' }, {}) // true\n *\n * @method utils.areDifferent\n * @param {Object} a Base object.\n * @param {Object} b Comparison object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Whether the two objects are deeply different.\n * @see utils.diffObjects\n * @since 3.0.0\n */\n areDifferent (newObject, oldObject, opts) {\n opts || (opts = {})\n const diff = utils.diffObjects(newObject, oldObject, opts)\n const diffCount = Object.keys(diff.added).length +\n Object.keys(diff.removed).length +\n Object.keys(diff.changed).length\n return diffCount > 0\n },\n\n /**\n * Verified that the given constructor is being invoked via `new`, as opposed\n * to just being called like a normal function.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {\n * utils.classCallCheck(this, Cat)\n * }\n * const cat = new Cat() // this is ok\n * Cat() // this throws an error\n *\n * @method utils.classCallCheck\n * @param {*} instance Instance that is being constructed.\n * @param {Constructor} ctor Constructor function used to construct the\n * instance.\n * @since 3.0.0\n * @throws {Error} Throws an error if the constructor is being improperly\n * invoked.\n */\n classCallCheck (instance, ctor) {\n if (!(instance instanceof ctor)) {\n throw utils.err(`${ctor.name}`)(500, 'Cannot call a class as a function')\n }\n },\n\n /**\n * Deep copy a value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' } }\n * const b = utils.copy(a)\n * a === b // false\n * utils.areDifferent(a, b) // false\n *\n * @param {*} from Value to deep copy.\n * @param {*} [to] Destination object for the copy operation.\n * @param {*} [stackFrom] For internal use.\n * @param {*} [stackTo] For internal use.\n * @param {string[]|RegExp[]} [blacklist] List of strings or RegExp of\n * properties to skip.\n * @param {boolean} [plain] Whether to make a plain copy (don't try to use\n * original prototype).\n * @returns {*} Deep copy of `from`.\n * @since 3.0.0\n */\n copy (from, to, stackFrom, stackTo, blacklist, plain) {\n if (!to) {\n to = from\n if (from) {\n if (utils.isArray(from)) {\n to = utils.copy(from, [], stackFrom, stackTo, blacklist, plain)\n } else if (utils.isDate(from)) {\n to = new Date(from.getTime())\n } else if (utils.isRegExp(from)) {\n to = new RegExp(from.source, from.toString().match(/[^\\/]*$/)[0])\n to.lastIndex = from.lastIndex\n } else if (utils.isObject(from)) {\n if (plain) {\n to = utils.copy(from, {}, stackFrom, stackTo, blacklist, plain)\n } else {\n to = utils.copy(from, Object.create(Object.getPrototypeOf(from)), stackFrom, stackTo, blacklist, plain)\n }\n }\n }\n } else {\n if (from === to) {\n throw utils.err(`${DOMAIN}.copy`)(500, 'Cannot copy! Source and destination are identical.')\n }\n\n stackFrom = stackFrom || []\n stackTo = stackTo || []\n\n if (utils.isObject(from)) {\n let index = stackFrom.indexOf(from)\n if (index !== -1) {\n return stackTo[index]\n }\n\n stackFrom.push(from)\n stackTo.push(to)\n }\n\n let result\n if (utils.isArray(from)) {\n let i\n to.length = 0\n for (i = 0; i < from.length; i++) {\n result = utils.copy(from[i], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[i])) {\n stackFrom.push(from[i])\n stackTo.push(result)\n }\n to.push(result)\n }\n } else {\n if (utils.isArray(to)) {\n to.length = 0\n } else {\n utils.forOwn(to, function (value, key) {\n delete to[key]\n })\n }\n for (var key in from) {\n if (from.hasOwnProperty(key)) {\n if (utils.isBlacklisted(key, blacklist)) {\n continue\n }\n result = utils.copy(from[key], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[key])) {\n stackFrom.push(from[key])\n stackTo.push(result)\n }\n to[key] = result\n }\n }\n }\n }\n return to\n },\n\n /**\n * Recursively shallow fill in own enumerable properties from `source` to\n * `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"bip\"}\n *\n * @method utils.deepFillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n deepFillIn (dest, source) {\n if (source) {\n utils.forOwn(source, function (value, key) {\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepFillIn(existing, value)\n } else if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n }\n return dest\n },\n\n /**\n * Recursively shallow copy enumerable properties from `source` to `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"boop\"}\n *\n * @method utils.deepMixIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepFillIn\n * @since 3.0.0\n */\n deepMixIn (dest, source) {\n if (source) {\n for (var key in source) {\n const value = source[key]\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepMixIn(existing, value)\n } else {\n dest[key] = value\n }\n }\n }\n return dest\n },\n\n /**\n * Return a diff of the base object to the comparison object.\n *\n * @example\n * import {utils} from 'js-data'\n * const oldObject = { foo: 'bar', a: 1234 }\n * const newObject = { beep: 'boop', a: 5678 }\n * const diff = utils.diffObjects(oldObject, newObject)\n * console.log(diff.added) // {\"beep\":\"boop\"}\n * console.log(diff.changed) // {\"a\":5678}\n * console.log(diff.removed) // {\"foo\":undefined}\n *\n * @method utils.diffObjects\n * @param {Object} newObject Comparison object.\n * @param {Object} oldObject Base object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} The diff from the base object to the comparison object.\n * @see utils.areDifferent\n * @since 3.0.0\n */\n diffObjects (newObject, oldObject, opts) {\n opts || (opts = {})\n let equalsFn = opts.equalsFn\n let blacklist = opts.ignore\n const diff = {\n added: {},\n changed: {},\n removed: {}\n }\n if (!utils.isFunction(equalsFn)) {\n equalsFn = utils.deepEqual\n }\n\n const newKeys = Object.keys(newObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n const oldKeys = Object.keys(oldObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n\n // Check for properties that were added or changed\n newKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (equalsFn(oldValue, newValue)) {\n return\n }\n if (oldValue === undefined) {\n diff.added[key] = newValue\n } else {\n diff.changed[key] = newValue\n }\n })\n\n // Check for properties that were removed\n oldKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (newValue === undefined && oldValue !== undefined) {\n diff.removed[key] = undefined\n }\n })\n\n return diff\n },\n\n /**\n * Return whether the two values are equal according to the `==` operator.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.equal(1,1)) // true\n * console.log(utils.equal(1,'1')) // true\n * console.log(utils.equal(93, 66)) // false\n *\n * @method utils.equal\n * @param {*} a First value in the comparison.\n * @param {*} b Second value in the comparison.\n * @returns {boolean} Whether the two values are equal according to `==`.\n * @since 3.0.0\n */\n equal (a, b) {\n return a == b // eslint-disable-line\n },\n\n /**\n * Produce a factory function for making Error objects with the provided\n * metadata. Used throughout the various js-data components.\n *\n * @example\n * import {utils} from 'js-data'\n * const errorFactory = utils.err('domain', 'target')\n * const error400 = errorFactory(400, 'expected type', 'actual type')\n * console.log(error400) // [Error: [domain:target] expected: expected type, found: string\nhttp://www.js-data.io/v3.0/docs/errors#400]\n * @method utils.err\n * @param {string} domain Namespace.\n * @param {string} target Target.\n * @returns {Function} Factory function.\n * @since 3.0.0\n */\n err (domain, target) {\n return function (code) {\n const prefix = `[${domain}:${target}] `\n let message = ERRORS[code].apply(null, Array.prototype.slice.call(arguments, 1))\n message = `${prefix}${message}\nhttp://www.js-data.io/v3.0/docs/errors#${code}`\n return new Error(message)\n }\n },\n\n /**\n * Add eventing capabilities into the target object.\n *\n * @example\n * import {utils} from 'js-data'\n * const user = { name: 'John' }\n * utils.eventify(user)\n * user.on('foo', () => console.log(arguments))\n * user.emit('foo', 1, 'bar') // should log to console values (1, \"bar\")\n *\n * @method utils.eventify\n * @param {Object} target Target object.\n * @param {Function} [getter] Custom getter for retrieving the object's event\n * listeners.\n * @param {Function} [setter] Custom setter for setting the object's event\n * listeners.\n * @since 3.0.0\n */\n eventify (target, getter, setter) {\n target = target || this\n let _events = {}\n if (!getter && !setter) {\n getter = function () { return _events }\n setter = function (value) { _events = value }\n }\n Object.defineProperties(target, {\n emit: {\n value (...args) {\n const events = getter.call(this) || {}\n const type = args.shift()\n let listeners = events[type] || []\n let i\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n listeners = events.all || []\n args.unshift(type)\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n }\n },\n off: {\n value (type, func) {\n const events = getter.call(this)\n const listeners = events[type]\n if (!listeners) {\n setter.call(this, {})\n } else if (func) {\n for (let i = 0; i < listeners.length; i++) {\n if (listeners[i].f === func) {\n listeners.splice(i, 1)\n break\n }\n }\n } else {\n listeners.splice(0, listeners.length)\n }\n }\n },\n on: {\n value (type, func, thisArg) {\n if (!getter.call(this)) {\n setter.call(this, {})\n }\n const events = getter.call(this)\n events[type] = events[type] || []\n events[type].push({\n c: thisArg,\n f: func\n })\n }\n }\n })\n },\n\n /**\n * Used for sublcassing. Invoke this method in the context of a superclass to\n * to produce a subclass based on `props` and `classProps`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Animal () {}\n * Animal.extend = utils.extend\n * const Cat = Animal.extend({\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat instanceof Animal // true\n * cat instanceof Cat // true\n * cat.say() // \"meow\"\n *\n * @method utils.extend\n * @param {Object} props Instance properties for the subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to use as the subclass.\n * @param {Object} props Static properties for the subclass.\n * @returns {Constructor} A new subclass.\n * @since 3.0.0\n */\n extend (props, classProps) {\n const superClass = this\n let subClass\n\n props || (props = {})\n classProps || (classProps = {})\n\n if (props.hasOwnProperty('constructor')) {\n subClass = props.constructor\n delete props.constructor\n } else {\n subClass = function (...args) {\n utils.classCallCheck(this, subClass)\n superClass.apply(this, args)\n }\n }\n\n // Setup inheritance of instance members\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n configurable: true,\n enumerable: false,\n value: subClass,\n writable: true\n }\n })\n\n const obj = Object\n // Setup inheritance of static members\n if (obj.setPrototypeOf) {\n obj.setPrototypeOf(subClass, superClass)\n } else if (classProps.strictEs6Class) {\n subClass.__proto__ = superClass // eslint-disable-line\n } else {\n utils.forOwn(superClass, function (value, key) {\n subClass[key] = value\n })\n }\n if (!subClass.hasOwnProperty('__super__')) {\n Object.defineProperty(subClass, '__super__', {\n configurable: true,\n value: superClass\n })\n }\n\n utils.addHiddenPropsToTarget(subClass.prototype, props)\n utils.fillIn(subClass, classProps)\n\n return subClass\n },\n\n /**\n * Shallow copy own enumerable properties from `src` to `dest` that are on\n * `src` but are missing from `dest.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: 'bar', beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.fillIn(b, a)\n * console.log(b) // {\"foo\":\"bar\",\"beep\":\"bip\"}\n *\n * @method utils.fillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.deepFillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n fillIn (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Find the last index of an item in an array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = { name: 'John', age: 20 }\n * const sara = { name: 'Sara', age: 25 }\n * const dan = { name: 'Dan', age: 20 }\n * const users = [john, sara, dan]\n *\n * console.log(utils.findIndex(users, (user) => user.age === 25)) // 1\n * console.log(utils.findIndex(users, (user) => user.age > 19)) // 2\n * console.log(utils.findIndex(users, (user) => user.name === 'John')) // 0\n * console.log(utils.findIndex(users, (user) => user.name === 'Jimmy')) // -1\n *\n * @method utils.findIndex\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n * @returns {number} Index if found or -1 if not found.\n * @since 3.0.0\n */\n findIndex (array, fn) {\n let index = -1\n if (!array) {\n return index\n }\n array.forEach(function (record, i) {\n if (fn(record)) {\n index = i\n return false\n }\n })\n return index\n },\n\n /**\n * Recursively iterate over a {@link Mapper}'s relations according to\n * `opts.with`.\n *\n * @method utils.forEachRelation\n * @param {Mapper} mapper Mapper.\n * @param {Object} opts Configuration options.\n * @param {Function} fn Callback function.\n * @param {*} thisArg Execution context for the callback function.\n * @since 3.0.0\n */\n forEachRelation (mapper, opts, fn, thisArg) {\n const relationList = mapper.relationList || []\n if (!relationList.length) {\n return\n }\n relationList.forEach(function (def) {\n utils._forRelation(opts, def, fn, thisArg)\n })\n },\n\n /**\n * Iterate over an object's own enumerable properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { b: 1, c: 4 }\n * let sum = 0\n * utils.forOwn(a, function (value, key) {\n * sum += value\n * })\n * console.log(sum) // 5\n *\n * @method utils.forOwn\n * @param {Object} object The object whose properties are to be enumerated.\n * @param {Function} fn Iteration function.\n * @param {Object} [thisArg] Content to which to bind `fn`.\n * @since 3.0.0\n */\n forOwn (obj, fn, thisArg) {\n const keys = Object.keys(obj)\n const len = keys.length\n let i\n for (i = 0; i < len; i++) {\n fn.call(thisArg, obj[keys[i]], keys[i], obj)\n }\n },\n\n /**\n * Proxy for `JSON.parse`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = utils.fromJson('{\"name\" : \"John\"}')\n * console.log(a) // { name: 'John' }\n *\n * @method utils.fromJson\n * @param {string} json JSON to parse.\n * @returns {Object} Parsed object.\n * @see utils.toJson\n * @since 3.0.0\n */\n fromJson (json) {\n return utils.isString(json) ? JSON.parse(json) : json\n },\n\n /**\n * Retrieve the specified property from the given object. Supports retrieving\n * nested properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * console.log(utils.get(a, 'beep')) // \"boop\"\n * console.log(utils.get(a, 'foo.bar')) // \"baz\"\n *\n * @method utils.get\n * @param {Object} object Object from which to retrieve a property's value.\n * @param {string} prop Property to retrieve.\n * @returns {*} Value of the specified property.\n * @see utils.set\n * @since 3.0.0\n */\n 'get': function (object, prop) {\n if (!prop) {\n return\n }\n const parts = prop.split('.')\n const last = parts.pop()\n\n while (prop = parts.shift()) { // eslint-disable-line\n object = object[prop]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n return object[last]\n },\n\n /**\n * Return the superclass for the given instance or subclass. If an instance is\n * provided, then finds the parent class of the instance's constructor.\n *\n * @example\n * import {utils} from 'js-data'\n * // using ES2015 classes\n * class Foo {}\n * class Bar extends Foo {}\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * // using Function constructor with utils.extend\n * function Foo () {}\n * Foo.extend = utils.extend\n * const Bar = Foo.extend()\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * @method utils.getSuper\n * @param {Object|Function} instance Instance or constructor.\n * @param {boolean} [isCtor=false] Whether `instance` is a constructor.\n * @returns {Constructor} The superclass (grandparent constructor).\n * @since 3.0.0\n */\n getSuper (instance, isCtor) {\n const ctor = isCtor ? instance : instance.constructor\n if (ctor.hasOwnProperty('__super__')) {\n return ctor.__super__\n }\n return Object.getPrototypeOf(ctor) || ctor.__proto__ // eslint-disable-line\n },\n\n /**\n * Return the intersection of two arrays.\n *\n * @example\n * import {utils} from 'js-data'\n * const arrA = ['green', 'red', 'blue', 'red']\n * const arrB = ['green', 'yellow', 'red']\n * const intersected = utils.intersection(arrA, arrB)\n *\n * console.log(intersected) // ['green', 'red'])\n *\n * @method utils.intersection\n * @param {Array} array1 First array.\n * @param {Array} array2 Second array.\n * @returns {Array} Array of elements common to both arrays.\n * @since 3.0.0\n */\n intersection (array1, array2) {\n if (!array1 || !array2) {\n return []\n }\n const result = []\n let item\n let i\n const len = array1.length\n for (i = 0; i < len; i++) {\n item = array1[i]\n if (result.indexOf(item) !== -1) {\n continue\n }\n if (array2.indexOf(item) !== -1) {\n result.push(item)\n }\n }\n return result\n },\n\n /**\n * Proxy for `Array.isArray`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = [1,2,3,4,5]\n * const b = { foo: \"bar\" }\n * console.log(utils.isArray(a)) // true\n * console.log(utils.isArray(b)) // false\n *\n * @method utils.isArray\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an array.\n * @since 3.0.0\n */\n isArray: Array.isArray,\n\n /**\n * Return whether `prop` is matched by any string or regular expression in\n * `blacklist`.\n *\n * @example\n * import {utils} from 'js-data'\n * const blacklist = [/^\\$hashKey/g, /^_/g, 'id']\n * console.log(utils.isBlacklisted(\"$hashKey\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"id\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"_myProp\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"my_id\", blacklist)) // false\n *\n * @method utils.isBlacklisted\n * @param {string} prop The name of a property to check.\n * @param {Array} blacklist Array of strings and regular expressions.\n * @returns {boolean} Whether `prop` was matched.\n * @since 3.0.0\n */\n isBlacklisted (prop, blacklist) {\n if (!blacklist || !blacklist.length) {\n return false\n }\n let matches\n for (var i = 0; i < blacklist.length; i++) {\n if ((toStr(blacklist[i]) === REGEXP_TAG && blacklist[i].test(prop)) || blacklist[i] === prop) {\n matches = prop\n return !!matches\n }\n }\n return !!matches\n },\n\n /**\n * Return whether the provided value is a boolean.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = true\n * const b = { foo: \"bar\" }\n * console.log(utils.isBoolean(a)) // true\n * console.log(utils.isBoolean(b)) // false\n *\n * @method utils.isBoolean\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a boolean.\n * @since 3.0.0\n */\n isBoolean (value) {\n return toStr(value) === BOOL_TAG\n },\n\n /**\n * Return whether the provided value is a date.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = new Date()\n * const b = { foo: \"bar\" }\n * console.log(utils.isDate(a)) // true\n * console.log(utils.isDate(b)) // false\n *\n * @method utils.isDate\n * @param {*} value The value to test.\n * @returns {Date} Whether the provided value is a date.\n * @since 3.0.0\n */\n isDate (value) {\n return (value && typeof value === 'object' && toStr(value) === DATE_TAG)\n },\n\n /**\n * Return whether the provided value is a function.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = function (){ console.log('foo bar')}\n * const b = { foo: \"bar\" }\n * console.log(utils.isFunction(a)) // true\n * console.log(utils.isFunction(b)) // false\n *\n * @method utils.isFunction\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a function.\n * @since 3.0.0\n */\n isFunction (value) {\n return typeof value === 'function' || (value && toStr(value) === FUNC_TAG)\n },\n\n /**\n * Return whether the provided value is an integer.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = 1.25\n * const c = '1'\n * console.log(utils.isInteger(a)) // true\n * console.log(utils.isInteger(b)) // false\n * console.log(utils.isInteger(c)) // false\n *\n * @method utils.isInteger\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an integer.\n * @since 3.0.0\n */\n isInteger (value) {\n return toStr(value) === NUMBER_TAG && value == toInteger(value) // eslint-disable-line\n },\n\n /**\n * Return whether the provided value is `null`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = null\n * const b = { foo: \"bar\" }\n * console.log(utils.isNull(a)) // true\n * console.log(utils.isNull(b)) // false\n *\n * @method utils.isNull\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is `null`.\n * @since 3.0.0\n */\n isNull (value) {\n return value === null\n },\n\n /**\n * Return whether the provided value is a number.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = -1.25\n * const c = '1'\n * console.log(utils.isNumber(a)) // true\n * console.log(utils.isNumber(b)) // true\n * console.log(utils.isNumber(c)) // false\n *\n * @method utils.isNumber\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a number.\n * @since 3.0.0\n */\n isNumber (value) {\n const type = typeof value\n return type === 'number' || (value && type === 'object' && toStr(value) === NUMBER_TAG)\n },\n\n /**\n * Return whether the provided value is an object.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\" }\n * const b = 'foo bar'\n * console.log(utils.isObject(a)) // true\n * console.log(utils.isObject(b)) // false\n *\n * @method utils.isObject\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an object.\n * @since 3.0.0\n */\n isObject (value) {\n return toStr(value) === OBJECT_TAG\n },\n\n /**\n * Return whether the provided value is a regular expression.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = /^\\$.+$/ig\n * const b = new RegExp('^\\$.+$', 'ig')\n * const c = { foo: \"bar\" }\n * console.log(utils.isRegExp(a)) // true\n * console.log(utils.isRegExp(b)) // true\n * console.log(utils.isRegExp(c)) // false\n *\n * @method utils.isRegExp\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a regular expression.\n * @since 3.0.0\n */\n isRegExp (value) {\n return toStr(value) === REGEXP_TAG\n },\n\n /**\n * Return whether the provided value is a string or a number.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isSorN('')) // true\n * console.log(utils.isSorN(-1.65)) // true\n * console.log(utils.isSorN('my string')) // true\n * console.log(utils.isSorN({})) // false\n * console.log(utils.isSorN([1,2,4])) // false\n *\n * @method utils.isSorN\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string or a number.\n * @since 3.0.0\n */\n isSorN (value) {\n return utils.isString(value) || utils.isNumber(value)\n },\n\n /**\n * Return whether the provided value is a string.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('')) // true\n * console.log(utils.isString('my string')) // true\n * console.log(utils.isString(100)) // false\n * console.log(utils.isString([1,2,4])) // false\n *\n * @method utils.isString\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string.\n * @since 3.0.0\n */\n isString (value) {\n return typeof value === 'string' || (value && typeof value === 'object' && toStr(value) === STRING_TAG)\n },\n\n /**\n * Return whether the provided value is a `undefined`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = undefined\n * const b = { foo: \"bar\"}\n * console.log(utils.isUndefined(a)) // true\n * console.log(utils.isUndefined(b.baz)) // true\n * console.log(utils.isUndefined(b)) // false\n * console.log(utils.isUndefined(b.foo)) // false\n *\n * @method utils.isUndefined\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a `undefined`.\n * @since 3.0.0\n */\n isUndefined (value) {\n return value === undefined\n },\n\n /**\n * Mix in logging capabilities to the target.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\"}\n *\n * // Add standard logging to an object\n * utils.logify(a)\n * a.log('info', 'test log info') // output 'test log info' to console.\n *\n * // Toggle debug output of an object\n * a.dbg('test debug output') // does not output because debug is off.\n * a.debug = true\n * a.dbg('test debug output') // output 'test debug output' to console.\n *\n * @method utils.logify\n * @param {*} target The target.\n * @since 3.0.0\n */\n logify (target) {\n utils.addHiddenPropsToTarget(target, {\n dbg (...args) {\n if (utils.isFunction(this.log)) {\n this.log('debug', ...args)\n }\n },\n log (level, ...args) {\n if (level && !args.length) {\n args.push(level)\n level = 'debug'\n }\n if (level === 'debug' && !this.debug) {\n return\n }\n const prefix = `${level.toUpperCase()}: (${this.name || this.constructor.name})`\n if (utils.isFunction(console[level])) {\n console[level](prefix, ...args)\n } else {\n console.log(prefix, ...args)\n }\n }\n })\n },\n\n /**\n * Adds the given record to the provided array only if it's not already in the\n * array.\n *\n * @example\n * import {utils} from 'js-data'\n * const colors = ['red', 'green', 'yellow']\n *\n * console.log(colors.length) // 3\n * utils.noDupeAdd(colors, 'red')\n * console.log(colors.length) // 3, red already exists\n *\n * utils.noDupeAdd(colors, 'blue')\n * console.log(colors.length) // 4, blue was added\n *\n * @method utils.noDupeAdd\n * @param {Array} array The array.\n * @param {*} record The value to add.\n * @param {Function} fn Callback function passed to {@link utils.findIndex}.\n * @since 3.0.0\n */\n noDupeAdd (array, record, fn) {\n if (!array) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index < 0) {\n array.push(record)\n }\n },\n\n /**\n * Return a shallow copy of the provided object, minus the properties\n * specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.omit(a, ['$hashKey'])\n * console.log(b) // { name: 'John' }\n *\n * @method utils.omit\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to skip.\n * @returns {Object} Shallow copy of `props`, minus `keys`.\n * @since 3.0.0\n */\n omit (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) === -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a shallow copy of the provided object, but only include the\n * properties specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.pick(a, ['$hashKey'])\n * console.log(b) // { $hashKey: 1214910 }\n *\n * @method utils.pick\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to keep.\n * @returns {Object} Shallow copy of `props`, but only including `keys`.\n * @since 3.0.0\n */\n pick (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) !== -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a plain copy of the given value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John' }\n * let b = utils.plainCopy(a)\n * console.log(a === b) // false\n *\n * @method utils.plainCopy\n * @param {*} value The value to copy.\n * @returns {*} Plain copy of `value`.\n * @see utils.copy\n * @since 3.0.0\n */\n plainCopy (value) {\n return utils.copy(value, undefined, undefined, undefined, undefined, true)\n },\n\n /**\n * Shortcut for `utils.Promise.reject(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.reject(\"Testing static reject\").then(function(data) {\n * // not called\n * }).catch(function(reason) {\n * console.log(reason); // \"Testing static reject\"\n * })\n *\n * @method utils.reject\n * @param {*} [value] Value with which to reject the Promise.\n * @returns {Promise} Promise reject with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n reject (value) {\n return utils.Promise.reject(value)\n },\n\n /**\n * Remove the last item found in array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const colors = ['red', 'green', 'yellow', 'red']\n * utils.remove(colors, (color) => color === 'red')\n * console.log(colors) // ['red', 'green', 'yellow']\n *\n * @method utils.remove\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n */\n remove (array, fn) {\n if (!array || !array.length) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index >= 0) {\n array.splice(index, 1) // todo should this be recursive?\n }\n },\n\n /**\n * Shortcut for `utils.Promise.resolve(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.resolve(\"Testing static resolve\").then(function(data) {\n * console.log(data); // \"Testing static resolve\"\n * }).catch(function(reason) {\n * // not called\n * })\n *\n * @param {*} [value] Value with which to resolve the Promise.\n * @returns {Promise} Promise resolved with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n resolve (value) {\n return utils.Promise.resolve(value)\n },\n\n /**\n * Set the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n * // set value by key\n * utils.set(john, 'id', 98)\n * console.log(john.id) // 98\n *\n * // set value by path\n * utils.set(john, 'parent.id', 20)\n * console.log(john.parent.id) // 20\n *\n * // set value by path/value map\n * utils.set(john, {\n * 'id': 1098,\n * 'parent': { id: 1020 },\n * 'parent.age': '55'\n * })\n * console.log(john.id) // 1098\n * console.log(john.parent.id) // 1020\n * console.log(john.parent.age) // 55\n *\n * @method utils.set\n * @param {Object} object The object on which to set a property.\n * @param {(string|Object)} path The key or path to the property. Can also\n * pass in an object of path/value pairs, which will all be set on the target\n * object.\n * @param {*} [value] The value to set.\n */\n set: function (object, path, value) {\n if (utils.isObject(path)) {\n utils.forOwn(path, function (value, _path) {\n utils.set(object, _path, value)\n })\n } else {\n const parts = PATH.exec(path)\n if (parts) {\n mkdirP(object, parts[1])[parts[2]] = value\n } else {\n object[path] = value\n }\n }\n },\n\n /**\n * Check whether the two provided objects are deeply equal.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const objA = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * const objB = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * console.log(utils.deepEqual(a,b)) // true\n * objB.nested.colors.add('yellow') // make a change to a nested object's array\n * console.log(utils.deepEqual(a,b)) // false\n *\n * @method utils.deepEqual\n * @param {Object} a First object in the comparison.\n * @param {Object} b Second object in the comparison.\n * @returns {boolean} Whether the two provided objects are deeply equal.\n * @see utils.equal\n * @since 3.0.0\n */\n deepEqual (a, b) {\n if (a === b) {\n return true\n }\n let _equal = true\n if (utils.isObject(a) && utils.isObject(b)) {\n utils.forOwn(a, function (value, key) {\n _equal = _equal && utils.deepEqual(value, b[key])\n })\n if (!_equal) {\n return _equal\n }\n utils.forOwn(b, function (value, key) {\n _equal = _equal && utils.deepEqual(value, a[key])\n })\n } else if (utils.isArray(a) && utils.isArray(b)) {\n a.forEach(function (value, i) {\n _equal = _equal && utils.deepEqual(value, b[i])\n if (!_equal) {\n return false\n }\n })\n } else {\n return false\n }\n return _equal\n },\n\n /**\n * Proxy for `JSON.stringify`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = { name: 'John' }\n * let jsonVal = utils.toJson(a)\n * console.log(jsonVal) // '{\"name\" : \"John\"}'\n *\n * @method utils.toJson\n * @param {*} value Value to serialize to JSON.\n * @returns {string} JSON string.\n * @see utils.fromJson\n * @since 3.0.0\n */\n toJson: JSON.stringify,\n\n /**\n * Unset the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n *\n * utils.unset(john, age)\n * utils.unset(john, parent.age)\n *\n * console.log(john.age) // null\n * console.log(john.parent.age) // null\n *\n * @method utils.unset\n * @param {Object} object The object from which to delete the property.\n * @param {string} path The key or path to the property.\n * @see utils.set\n * @since 3.0.0\n */\n unset (object, path) {\n const parts = path.split('.')\n const last = parts.pop()\n\n while (path = parts.shift()) { // eslint-disable-line\n object = object[path]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n object[last] = undefined\n },\n\n}\n\nexport const safeSetProp = function (record, field, value) {\n if (record && record._set) {\n record._set(`props.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nexport const safeSetLink = function (record, field, value) {\n if (record && record._set) {\n record._set(`links.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nexport default utils\n","import utils from './utils'\n\n/**\n * A base class which gives instances private properties.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Settable.extend} for an example of using {@link Settable} as a\n * base class.\n *\n *```javascript\n * import {Settable} from 'js-data'\n * ```\n *\n * @class Settable\n * @returns {Settable} A new {@link Settable} instance.\n * @since 3.0.0\n */\nexport default function Settable () {\n const _props = {}\n Object.defineProperties(this, {\n /**\n * Get a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method Settable#_get\n * @param {string} key The property to retrieve.\n * @returns {*} The value of the property.\n * @since 3.0.0\n */\n _get: { value (key) { return utils.get(_props, key) } },\n\n /**\n * Set a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_set\n * @param {(string|Object)} key The key or path to the property. Can also\n * pass in an object of key/value pairs, which will all be set on the instance.\n * @param {*} [value] The value to set.\n * @since 3.0.0\n */\n _set: { value (key, value) { return utils.set(_props, key, value) } },\n\n /**\n * Unset a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_unset\n * @param {string} key The property to unset.\n * @since 3.0.0\n */\n _unset: { value (key) { return utils.unset(_props, key) } }\n })\n}\n\n/**\n * Create a subclass of this Settable:\n *\n * @example Settable.extend\n * // Normally you would do: import {Settable} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Settable} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSettableClass extends Settable {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSettable = new CustomSettableClass()\n * console.log(customSettable.foo())\n * console.log(CustomSettableClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSettableClass = Settable.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSettable = new OtherSettableClass()\n * console.log(otherSettable.foo())\n * console.log(OtherSettableClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSettableClass () {\n * Settable.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Settable.extend({\n * constructor: AnotherSettableClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSettable = new AnotherSettableClass()\n * console.log(anotherSettable.created_at)\n * console.log(anotherSettable.foo())\n * console.log(AnotherSettableClass.beep())\n *\n * @method Settable.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Settable class.\n * @since 3.0.0\n */\nSettable.extend = utils.extend\n","import utils from './utils'\nimport Settable from './Settable'\n\n/**\n * The base class from which all JSData components inherit some basic\n * functionality.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Component.extend} for an example of using {@link Component} as a\n * base class.\n *\n *```javascript\n * import {Component} from 'js-data'\n * ```\n *\n * @class Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @returns {Component} A new {@link Component} instance.\n * @since 3.0.0\n */\nfunction Component (opts) {\n Settable.call(this)\n opts || (opts = {})\n\n /**\n * Whether to enable debug-level logs for this component. Anything that\n * extends `Component` inherits this option and the corresponding logging\n * functionality.\n *\n * @example Component#debug\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const component = new Component()\n * component.log('debug', 'some message') // nothing gets logged\n * // Display debug logs:\n * component.debug = true\n * component.log('debug', 'other message') // this DOES get logged\n *\n * @default false\n * @name Component#debug\n * @since 3.0.0\n * @type {boolean}\n */\n this.debug = opts.hasOwnProperty('debug') ? !!opts.debug : false\n\n /**\n * Event listeners attached to this Component. __Do not modify.__ Use\n * {@link Component#on} and {@link Component#off} instead.\n *\n * @name Component#_listeners\n * @instance\n * @since 3.0.0\n * @type {Object}\n */\n Object.defineProperty(this, '_listeners', { value: {}, writable: true })\n}\n\nexport default Settable.extend({\n constructor: Component\n})\n\n/**\n * Create a subclass of this Component:\n *\n * @example Component.extend\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomComponentClass extends Component {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customComponent = new CustomComponentClass()\n * console.log(customComponent.foo())\n * console.log(CustomComponentClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherComponentClass = Component.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherComponent = new OtherComponentClass()\n * console.log(otherComponent.foo())\n * console.log(OtherComponentClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherComponentClass () {\n * Component.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Component.extend({\n * constructor: AnotherComponentClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherComponent = new AnotherComponentClass()\n * console.log(anotherComponent.created_at)\n * console.log(anotherComponent.foo())\n * console.log(AnotherComponentClass.beep())\n *\n * @method Component.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Component class.\n * @since 3.0.0\n */\nComponent.extend = utils.extend\n\n/**\n * Log the provided values at the \"debug\" level. Debug-level logs are only\n * logged if {@link Component#debug} is `true`.\n *\n * `.dbg(...)` is shorthand for `.log('debug', ...)`.\n *\n * @method Component#dbg\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\n/**\n * Log the provided values. By default sends values to `console[level]`.\n * Debug-level logs are only logged if {@link Component#debug} is `true`.\n *\n * Will attempt to use appropriate `console` methods if they are available.\n *\n * @method Component#log\n * @param {string} level Log level.\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\nutils.logify(Component.prototype)\n\n/**\n * Register a new event listener on this Component.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * collection.on('add', (records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * post.on('change', (record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method Component#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n/**\n * Remove an event listener from this Component. If no listener is provided,\n * then all listeners for the specified event will be removed. If no event is\n * specified then all listeners for all events will be removed.\n *\n * @example\n * // Remove a particular listener for a particular event\n * collection.off('add', handler)\n *\n * @example\n * // Remove all listeners for a particular event\n * record.off('change')\n *\n * @example\n * // Remove all listeners to all events\n * store.off()\n *\n * @method Component#off\n * @param {string} [event] Name of event to unsubsribe to.\n * @param {Function} [listener] Listener to remove.\n * @since 3.0.0\n */\n/**\n * Trigger an event on this Component.\n *\n * @example Component#emit\n * // import {Collection, DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, DataStore} = JSData\n *\n * const collection = new Collection()\n * collection.on('foo', function (msg) {\n * console.log(msg)\n * })\n * collection.emit('foo', 'bar')\n *\n * const store = new DataStore()\n * store.on('beep', function (msg) {\n * console.log(msg)\n * })\n * store.emit('beep', 'boop')\n *\n * @method Component#emit\n * @param {string} event Name of event to emit.\n * @param {...*} [args] Arguments to pass to any listeners.\n * @since 3.0.0\n */\nutils.eventify(\n Component.prototype,\n function () {\n return this._listeners\n },\n function (value) {\n this._listeners = value\n }\n)\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Query'\nconst INDEX_ERR = 'Index inaccessible after first operation'\n\n// Reserved words used by JSData's Query Syntax\nconst reserved = {\n limit: '',\n offset: '',\n orderBy: '',\n skip: '',\n sort: '',\n where: ''\n}\n\n// Used by our JavaScript implementation of the LIKE operator\nconst escapeRegExp = /([.*+?^=!:${}()|[\\]\\/\\\\])/g\nconst percentRegExp = /%/g\nconst underscoreRegExp = /_/g\nconst escape = function (pattern) {\n return pattern.replace(escapeRegExp, '\\\\$1')\n}\n\n/**\n * A class used by the {@link Collection} class to build queries to be executed\n * against the collection's data. An instance of `Query` is returned by\n * {@link Collection#query}. Query instances are typically short-lived, and you\n * shouldn't have to create them yourself. Just use {@link Collection#query}.\n *\n * ```javascript\n * import {Query} from 'js-data'\n * ```\n *\n * @example\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const drafts = store.query('post').filter({ status: 'draft' }).limit(2).run()\n * console.log(drafts)\n *\n * @class Query\n * @extends Component\n * @param {Collection} collection The collection on which this query operates.\n * @since 3.0.0\n */\nfunction Query (collection) {\n utils.classCallCheck(this, Query)\n\n /**\n * The {@link Collection} on which this query operates.\n *\n * @name Query#collection\n * @since 3.0.0\n * @type {Collection}\n */\n this.collection = collection\n\n /**\n * The current data result of this query.\n *\n * @name Query#data\n * @since 3.0.0\n * @type {Array}\n */\n this.data = null\n}\n\nexport default Component.extend({\n constructor: Query,\n\n _applyWhereFromObject (where) {\n const fields = []\n const ops = []\n const predicates = []\n utils.forOwn(where, (clause, field) => {\n if (!utils.isObject(clause)) {\n clause = {\n '==': clause\n }\n }\n utils.forOwn(clause, (expr, op) => {\n fields.push(field)\n ops.push(op)\n predicates.push(expr)\n })\n })\n return {\n fields,\n ops,\n predicates\n }\n },\n\n _applyWhereFromArray (where) {\n const groups = []\n where.forEach((_where, i) => {\n if (utils.isString(_where)) {\n return\n }\n const prev = where[i - 1]\n const parser = utils.isArray(_where) ? this._applyWhereFromArray : this._applyWhereFromObject\n const group = parser.call(this, _where)\n if (prev === 'or') {\n group.isOr = true\n }\n groups.push(group)\n })\n groups.isArray = true\n return groups\n },\n\n _testObjectGroup (keep, first, group, item) {\n let i\n const fields = group.fields\n const ops = group.ops\n const predicates = group.predicates\n const len = ops.length\n for (i = 0; i < len; i++) {\n let op = ops[i]\n const isOr = op.charAt(0) === '|'\n op = isOr ? op.substr(1) : op\n const expr = this.evaluate(utils.get(item, fields[i]), op, predicates[i])\n if (expr !== undefined) {\n keep = first ? expr : (isOr ? keep || expr : keep && expr)\n }\n first = false\n }\n return { keep, first }\n },\n\n _testArrayGroup (keep, first, groups, item) {\n let i\n const len = groups.length\n for (i = 0; i < len; i++) {\n const group = groups[i]\n const parser = group.isArray ? this._testArrayGroup : this._testObjectGroup\n const result = parser.call(this, true, true, group, item)\n if (groups[i - 1]) {\n if (group.isOr) {\n keep = keep || result.keep\n } else {\n keep = keep && result.keep\n }\n } else {\n keep = result.keep\n }\n first = result.first\n }\n return { keep, first }\n },\n\n /**\n * Find all entities between two boundaries.\n *\n * @example Get the users ages 18 to 30.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between(18, 30, { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @example Same as above.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between([18], [30], { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @method Query#between\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#between`)(500, 'Cannot access index')\n }\n this.data = this.collection.getIndex(opts.index).between(leftKeys, rightKeys, opts)\n return this\n },\n\n /**\n * The comparison function used by the {@link Query} class.\n *\n * @method Query#compare\n * @param {Array} orderBy An orderBy clause used for sorting and sub-sorting.\n * @param {number} index The index of the current orderBy clause being used.\n * @param {*} a The first item in the comparison.\n * @param {*} b The second item in the comparison.\n * @returns {number} -1 if `b` should preceed `a`. 0 if `a` and `b` are equal.\n * 1 if `a` should preceed `b`.\n * @since 3.0.0\n */\n compare (orderBy, index, a, b) {\n const def = orderBy[index]\n let cA = utils.get(a, def[0])\n let cB = utils.get(b, def[0])\n if (cA && utils.isString(cA)) {\n cA = cA.toUpperCase()\n }\n if (cB && utils.isString(cB)) {\n cB = cB.toUpperCase()\n }\n if (a === undefined) {\n a = null\n }\n if (b === undefined) {\n b = null\n }\n if (def[1].toUpperCase() === 'DESC') {\n const temp = cB\n cB = cA\n cA = temp\n }\n if (cA < cB) {\n return -1\n } else if (cA > cB) {\n return 1\n } else {\n if (index < orderBy.length - 1) {\n return this.compare(orderBy, index + 1, a, b)\n } else {\n return 0\n }\n }\n },\n\n /**\n * Predicate evaluation function used by the {@link Query} class.\n *\n * @method Query#evaluate\n * @param {*} value The value to evaluate.\n * @param {string} op The operator to use in this evaluation.\n * @param {*} predicate The predicate to use in this evaluation.\n * @returns {boolean} Whether the value passed the evaluation or not.\n * @since 3.0.0\n */\n evaluate (value, op, predicate) {\n const ops = this.constructor.ops\n if (ops[op]) {\n return ops[op](value, predicate)\n }\n if (op.indexOf('like') === 0) {\n return this.like(predicate, op.substr(4)).exec(value) !== null\n } else if (op.indexOf('notLike') === 0) {\n return this.like(predicate, op.substr(7)).exec(value) === null\n }\n },\n\n /**\n * Find the record or records that match the provided query or are accepted by\n * the provided filter function.\n *\n * @example Get the draft posts by authors younger than 30\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * let results = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * age: {\n * '<': 30\n * }\n * }\n * }).run()\n * console.log(results)\n *\n * @example Use a custom filter function\n * const posts = query.filter(function (post) {\n * return post.isReady()\n * }).run()\n *\n * @method Query#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Function} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n filter (query, thisArg) {\n /**\n * Selection query as defined by JSData's [Query Syntax][querysyntax].\n *\n * [querysyntax]: http://www.js-data.io/v3.0/docs/query-syntax\n *\n * @example Empty \"findAll\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * store.findAll('post').then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @example Empty \"filter\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = store.filter('post')\n * console.log(posts) // [...]\n *\n * @example Complex \"filter\" query\n * const PAGE_SIZE = 2\n * let currentPage = 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * // Retrieve a filtered page of blog posts\n * // Would typically replace filter with findAll\n * store.filter('post', {\n * where: {\n * status: {\n * // WHERE status = 'published'\n * '==': 'published'\n * },\n * author: {\n * // AND author IN ('bob', 'alice')\n * 'in': ['bob', 'alice'],\n * // OR author IN ('karen')\n * '|in': ['karen']\n * }\n * },\n * orderBy: [\n * // ORDER BY date_published DESC,\n * ['date_published', 'DESC'],\n * // ORDER BY title ASC\n * ['title', 'ASC']\n * ],\n * // LIMIT 2\n * limit: PAGE_SIZE,\n * // SKIP 4\n * offset: PAGE_SIZE * (currentPage - 1)\n * })\n *\n * @namespace query\n * @property {number} [limit] See {@link query.limit}.\n * @property {number} [offset] See {@link query.offset}.\n * @property {string|Array[]} [orderBy] See {@link query.orderBy}.\n * @property {number} [skip] Alias for {@link query.offset}.\n * @property {string|Array[]} [sort] Alias for {@link query.orderBy}.\n * @property {Object} [where] See {@link query.where}.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/query-syntax\",\"JSData's Query Syntax\"]\n */\n query || (query = {})\n this.getData()\n if (utils.isObject(query)) {\n let where = {}\n\n /**\n * Filtering criteria. Records that do not meet this criteria will be exluded\n * from the result.\n *\n * @example Return posts where author is at least 32 years old\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * where: {\n * age: {\n * '>=': 30\n * }\n * }\n * })\n * console.log(results)\n *\n * @name query.where\n * @type {Object}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isObject(query.where) || utils.isArray(query.where)) {\n where = query.where\n }\n utils.forOwn(query, function (value, key) {\n if (!(key in reserved) && !(key in where)) {\n where[key] = {\n '==': value\n }\n }\n })\n let groups\n\n // Apply filter for each field\n if (utils.isObject(where) && Object.keys(where).length !== 0) {\n groups = this._applyWhereFromArray([where])\n } else if (utils.isArray(where)) {\n groups = this._applyWhereFromArray(where)\n }\n\n if (groups) {\n this.data = this.data.filter((item, i) => this._testArrayGroup(true, true, groups, item).keep)\n }\n\n // Sort\n let orderBy = query.orderBy || query.sort\n\n if (utils.isString(orderBy)) {\n orderBy = [\n [orderBy, 'ASC']\n ]\n }\n if (!utils.isArray(orderBy)) {\n orderBy = null\n }\n\n /**\n * Determines how records should be ordered in the result.\n *\n * @example Order posts by `author` then by `id` descending \n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * orderBy:[['author','ASC'],['id','DESC']]\n * })\n * console.log(results)\n *\n * @name query.orderBy\n * @type {string|Array[]}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (orderBy) {\n let index = 0\n orderBy.forEach(function (def, i) {\n if (utils.isString(def)) {\n orderBy[i] = [def, 'ASC']\n }\n })\n this.data.sort((a, b) => this.compare(orderBy, index, a, b))\n }\n\n /**\n * Number of records to skip.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n *\n * @name query.offset\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.skip)) {\n this.skip(query.skip)\n } else if (utils.isNumber(query.offset)) {\n this.skip(query.offset)\n }\n\n /**\n * Maximum number of records to retrieve.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n * @name query.limit\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.limit)) {\n this.limit(query.limit)\n }\n } else if (utils.isFunction(query)) {\n this.data = this.data.filter(query, thisArg)\n }\n return this\n },\n\n /**\n * Iterate over all entities.\n *\n * @method Query#forEach\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n forEach (forEachFn, thisArg) {\n this.getData().forEach(forEachFn, thisArg)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided key.\n *\n * @example Get the entity whose primary key is 25.\n * const entities = query.get(25).run()\n *\n * @example Same as above.\n * const entities = query.get([25]).run()\n *\n * @example Get all users who are active and have the \"admin\" role.\n * const activeAdmins = query.get(['active', 'admin'], {\n * index: 'activityAndRoles'\n * }).run()\n *\n * @example Get all entities that match a certain weather condition.\n * const niceDays = query.get(['sunny', 'humid', 'calm'], {\n * index: 'weatherConditions'\n * }).run()\n *\n * @method Query#get\n * @param {Array} keyList Key(s) defining the entity to retrieve. If\n * `keyList` is not an array (i.e. for a single-value key), it will be\n * wrapped in an array.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.string] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n get (keyList, opts) {\n keyList || (keyList = [])\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#get`)(500, INDEX_ERR)\n }\n if (keyList && !utils.isArray(keyList)) {\n keyList = [keyList]\n }\n if (!keyList.length) {\n this.getData()\n return this\n }\n this.data = this.collection.getIndex(opts.index).get(keyList)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided keyLists.\n *\n * @example Get the posts where \"status\" is \"draft\" or \"inReview\".\n * const posts = query.getAll('draft', 'inReview', { index: 'status' }).run()\n *\n * @example Same as above.\n * const posts = query.getAll(['draft'], ['inReview'], { index: 'status' }).run()\n *\n * @method Query#getAll\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * entities matching each keyList will be retrieved. If no keyLists are\n * provided, all entities will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n getAll (...args) {\n let opts = {}\n if (this.data) {\n throw utils.err(`${DOMAIN}#getAll`)(500, INDEX_ERR)\n }\n if (!args.length || args.length === 1 && utils.isObject(args[0])) {\n this.getData()\n return this\n } else if (args.length && utils.isObject(args[args.length - 1])) {\n opts = args[args.length - 1]\n args.pop()\n }\n const collection = this.collection\n const index = collection.getIndex(opts.index)\n this.data = []\n args.forEach((keyList) => {\n this.data = this.data.concat(index.get(keyList))\n })\n return this\n },\n\n /**\n * Return the current data result of this query.\n *\n * @method Query#getData\n * @returns {Array} The data in this query.\n * @since 3.0.0\n */\n getData () {\n if (!this.data) {\n this.data = this.collection.index.getAll()\n }\n return this.data\n },\n\n /**\n * Implementation used by the `like` operator. Takes a pattern and flags and\n * returns a `RegExp` instance that can test strings.\n *\n * @method Query#like\n * @param {string} pattern Testing pattern.\n * @param {string} flags Flags for the regular expression.\n * @returns {RegExp} Regular expression for testing strings.\n * @since 3.0.0\n */\n like (pattern, flags) {\n return new RegExp(`^${(escape(pattern).replace(percentRegExp, '.*').replace(underscoreRegExp, '.'))}$`, flags)\n },\n\n /**\n * Limit the result.\n *\n * @example Get only the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').limit(2).run()\n * console.log(results)\n *\n * @method Query#limit\n * @param {number} num The maximum number of entities to keep in the result.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n limit (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#limit`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n this.data = data.slice(0, Math.min(data.length, num))\n return this\n },\n\n /**\n * Apply a mapping function to the result data.\n *\n * @example\n * // Return the age of all users\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const ages = store.query('user').map((user) => {\n * return user.age\n * }).run()\n * console.log(ages)\n *\n * @method Query#map\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n map (mapFn, thisArg) {\n this.data = this.getData().map(mapFn, thisArg)\n return this\n },\n\n /**\n * Return the result of calling the specified function on each item in this\n * collection's main index.\n *\n * @example\n * const stringAges = UserCollection.query().mapCall('toString').run()\n *\n * @method Query#mapCall\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n mapCall (funcName, ...args) {\n this.data = this.getData().map(function (item) {\n return item[funcName](...args)\n })\n return this\n },\n\n /**\n * Complete the execution of the query and return the resulting data.\n *\n * @method Query#run\n * @returns {Array} The result of executing this query.\n * @since 3.0.0\n */\n run () {\n const data = this.data\n this.data = null\n return data\n },\n\n /**\n * Skip a number of results.\n *\n * @example Get all but the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').skip(2).run()\n * console.log(results)\n *\n * @method Query#skip\n * @param {number} num The number of entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n skip (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#skip`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n if (num < data.length) {\n this.data = data.slice(num)\n } else {\n this.data = []\n }\n return this\n }\n}, {\n /**\n * The filtering operators supported by {@link Query#filter}, and which are\n * implemented by adapters (for the most part).\n *\n * @example Variant 1\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * status: 'published',\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n *\n * @example Variant 2\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * }\n * },\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n * @example Variant 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * status: 'published'\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Variant 4\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'published'\n * }\n * }\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Multiple operators\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const myPublishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * },\n * user_id: {\n * '==': currentUser.id\n * }\n * }\n * })\n *\n * console.log(myPublishedPosts)\n *\n * @name Query.ops\n * @property {Function} == Equality operator.\n * @property {Function} != Inequality operator.\n * @property {Function} > Greater than operator.\n * @property {Function} >= Greater than (inclusive) operator.\n * @property {Function} < Less than operator.\n * @property {Function} <= Less than (inclusive) operator.\n * @property {Function} isectEmpty Operator that asserts that the intersection\n * between two arrays is empty.\n * @property {Function} isectNotEmpty Operator that asserts that the\n * intersection between two arrays is __not__ empty.\n * @property {Function} in Operator that asserts whether a value is in an\n * array.\n * @property {Function} notIn Operator that asserts whether a value is __not__\n * in an array.\n * @property {Function} contains Operator that asserts whether an array\n * contains a value.\n * @property {Function} notContains Operator that asserts whether an array\n * does __not__ contain a value.\n * @since 3.0.0\n * @type {Object}\n */\n ops: {\n '=': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '==': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '===': function (value, predicate) {\n return value === predicate\n },\n '!=': function (value, predicate) {\n return value != predicate // eslint-disable-line\n },\n '!==': function (value, predicate) {\n return value !== predicate\n },\n '>': function (value, predicate) {\n return value > predicate\n },\n '>=': function (value, predicate) {\n return value >= predicate\n },\n '<': function (value, predicate) {\n return value < predicate\n },\n '<=': function (value, predicate) {\n return value <= predicate\n },\n 'isectEmpty': function (value, predicate) {\n return !utils.intersection((value || []), (predicate || [])).length\n },\n 'isectNotEmpty': function (value, predicate) {\n return utils.intersection((value || []), (predicate || [])).length\n },\n 'in': function (value, predicate) {\n return predicate.indexOf(value) !== -1\n },\n 'notIn': function (value, predicate) {\n return predicate.indexOf(value) === -1\n },\n 'contains': function (value, predicate) {\n return (value || []).indexOf(predicate) !== -1\n },\n 'notContains': function (value, predicate) {\n return (value || []).indexOf(predicate) === -1\n }\n }\n})\n\n/**\n * Create a subclass of this Query:\n * @example Query.extend\n * // Normally you would do: import {Query} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Query} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomQueryClass extends Query {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customQuery = new CustomQueryClass()\n * console.log(customQuery.foo())\n * console.log(CustomQueryClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherQueryClass = Query.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherQuery = new OtherQueryClass()\n * console.log(otherQuery.foo())\n * console.log(OtherQueryClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherQueryClass (collection) {\n * Query.call(this, collection)\n * this.created_at = new Date().getTime()\n * }\n * Query.extend({\n * constructor: AnotherQueryClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherQuery = new AnotherQueryClass()\n * console.log(anotherQuery.created_at)\n * console.log(anotherQuery.foo())\n * console.log(AnotherQueryClass.beep())\n *\n * @method Query.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Query class.\n * @since 3.0.0\n */\n","export function sort (a, b, hashCode) {\n // Short-circuit comparison if a and b are strictly equal\n // This is absolutely necessary for indexed objects that\n // don't have the idAttribute field\n if (a === b) {\n return 0\n }\n if (hashCode) {\n a = hashCode(a)\n b = hashCode(b)\n }\n if ((a === null && b === null) || (a === undefined && b === undefined)) {\n return -1\n }\n\n if (a === null || a === undefined) {\n return -1\n }\n\n if (b === null || b === undefined) {\n return 1\n }\n\n if (a < b) {\n return -1\n }\n\n if (a > b) {\n return 1\n }\n\n return 0\n}\n\nexport function insertAt (array, index, value) {\n array.splice(index, 0, value)\n return array\n}\n\nexport function removeAt (array, index) {\n array.splice(index, 1)\n return array\n}\n\nexport function binarySearch (array, value, field) {\n let lo = 0\n let hi = array.length\n let compared\n let mid\n\n while (lo < hi) {\n mid = ((lo + hi) / 2) | 0\n compared = sort(value, array[mid], field)\n if (compared === 0) {\n return {\n found: true,\n index: mid\n }\n } else if (compared < 0) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n\n return {\n found: false,\n index: hi\n }\n}\n","// Copyright (c) 2015, InternalFX.\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose with or\n// without fee is hereby granted, provided that the above copyright notice and this permission\n// notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO\n// THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT\n// SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR\n// ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE\n// USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// Modifications\n// Copyright 2015-2016 Jason Dobry\n//\n// Summary of modifications:\n// Reworked dependencies so as to re-use code already in js-data\n// Removed unused code\nimport utils from '../../src/utils'\nimport {binarySearch, insertAt, removeAt} from './_utils'\n\nexport default function Index (fieldList, opts) {\n utils.classCallCheck(this, Index)\n fieldList || (fieldList = [])\n\n if (!utils.isArray(fieldList)) {\n throw new Error('fieldList must be an array.')\n }\n\n opts || (opts = {})\n this.fieldList = fieldList\n this.fieldGetter = opts.fieldGetter\n this.hashCode = opts.hashCode\n this.isIndex = true\n this.keys = []\n this.values = []\n}\n\nutils.addHiddenPropsToTarget(Index.prototype, {\n 'set' (keyList, value) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n let dataLocation = binarySearch(this.values[pos.index], value, this.hashCode)\n if (!dataLocation.found) {\n insertAt(this.values[pos.index], dataLocation.index, value)\n }\n } else {\n insertAt(this.keys, pos.index, key)\n insertAt(this.values, pos.index, [value])\n }\n } else {\n if (pos.found) {\n this.values[pos.index].set(keyList, value)\n } else {\n insertAt(this.keys, pos.index, key)\n let newIndex = new Index([], { hashCode: this.hashCode })\n newIndex.set(keyList, value)\n insertAt(this.values, pos.index, newIndex)\n }\n }\n },\n\n 'get' (keyList) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n if (this.values[pos.index].isIndex) {\n return this.values[pos.index].getAll()\n } else {\n return this.values[pos.index].slice()\n }\n } else {\n return []\n }\n } else {\n if (pos.found) {\n return this.values[pos.index].get(keyList)\n } else {\n return []\n }\n }\n },\n\n getAll (opts) {\n opts || (opts = {})\n let results = []\n const values = this.values\n if (opts.order === 'desc') {\n for (let i = values.length - 1; i >= 0; i--) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n } else {\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n }\n return results\n },\n\n visitAll (cb, thisArg) {\n this.values.forEach(function (value) {\n if (value.isIndex) {\n value.visitAll(cb, thisArg)\n } else {\n value.forEach(cb, thisArg)\n }\n })\n },\n\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (!utils.isArray(leftKeys)) {\n leftKeys = [leftKeys]\n }\n if (!utils.isArray(rightKeys)) {\n rightKeys = [rightKeys]\n }\n utils.fillIn(opts, {\n leftInclusive: true,\n rightInclusive: false,\n limit: undefined,\n offset: 0\n })\n\n let results = this._between(leftKeys, rightKeys, opts)\n\n if (opts.limit) {\n return results.slice(opts.offset, opts.limit + opts.offset)\n } else {\n return results.slice(opts.offset)\n }\n },\n\n _between (leftKeys, rightKeys, opts) {\n let results = []\n\n let leftKey = leftKeys.shift()\n let rightKey = rightKeys.shift()\n\n let pos\n\n if (leftKey !== undefined) {\n pos = binarySearch(this.keys, leftKey)\n } else {\n pos = {\n found: false,\n index: 0\n }\n }\n\n if (leftKeys.length === 0) {\n if (pos.found && opts.leftInclusive === false) {\n pos.index += 1\n }\n\n for (let i = pos.index; i < this.keys.length; i += 1) {\n if (rightKey !== undefined) {\n if (opts.rightInclusive) {\n if (this.keys[i] > rightKey) { break }\n } else {\n if (this.keys[i] >= rightKey) { break }\n }\n }\n\n if (this.values[i].isIndex) {\n results = results.concat(this.values[i].getAll())\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n } else {\n for (let i = pos.index; i < this.keys.length; i += 1) {\n let currKey = this.keys[i]\n if (currKey > rightKey) { break }\n\n if (this.values[i].isIndex) {\n if (currKey === leftKey) {\n results = results.concat(this.values[i]._between(utils.copy(leftKeys), rightKeys.map(function () { return undefined }), opts))\n } else if (currKey === rightKey) {\n results = results.concat(this.values[i]._between(leftKeys.map(function () { return undefined }), utils.copy(rightKeys), opts))\n } else {\n results = results.concat(this.values[i].getAll())\n }\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n }\n\n if (opts.limit) {\n return results.slice(0, opts.limit + opts.offset)\n } else {\n return results\n }\n },\n\n peek () {\n if (this.values.length) {\n if (this.values[0].isIndex) {\n return this.values[0].peek()\n } else {\n return this.values[0]\n }\n }\n return []\n },\n\n clear () {\n this.keys = []\n this.values = []\n },\n\n insertRecord (data) {\n let keyList = this.fieldList.map(function (field) {\n if (utils.isFunction(field)) {\n return field(data) || undefined\n } else {\n return data[field] || undefined\n }\n })\n this.set(keyList, data)\n },\n\n removeRecord (data) {\n let removed\n const isUnique = this.hashCode(data) !== undefined\n this.values.forEach((value, i) => {\n if (value.isIndex) {\n if (value.removeRecord(data)) {\n if (value.keys.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n } else {\n let dataLocation = {}\n if (this.keys[i] === undefined || !isUnique) {\n for (let j = value.length - 1; j >= 0; j--) {\n if (value[j] === data) {\n dataLocation = {\n found: true,\n index: j\n }\n break\n }\n }\n } else if (isUnique) {\n dataLocation = binarySearch(value, data, this.hashCode)\n }\n if (dataLocation.found) {\n removeAt(value, dataLocation.index)\n if (value.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n }\n })\n return removed ? data : undefined\n },\n\n updateRecord (data) {\n const removed = this.removeRecord(data)\n if (removed !== undefined) {\n this.insertRecord(data)\n }\n }\n})\n","import utils from './utils'\nimport Component from './Component'\nimport Query from './Query'\nimport Index from '../lib/mindex/index'\n\nconst DOMAIN = 'Collection'\n\nconst COLLECTION_DEFAULTS = {\n /**\n * Whether to call {@link Record#commit} on records that are added to the\n * collection and already exist in the collection.\n *\n * @name Collection#commitOnMerge\n * @type {boolean}\n * @default true\n */\n commitOnMerge: true,\n\n /**\n * Field to be used as the unique identifier for records in this collection.\n * Defaults to `\"id\"` unless {@link Collection#mapper} is set, in which case\n * this will default to {@link Mapper#idAttribute}.\n *\n * @name Collection#idAttribute\n * @type {string}\n * @default \"id\"\n */\n idAttribute: 'id',\n\n /**\n * What to do when inserting a record into this Collection that shares a\n * primary key with a record already in this Collection.\n *\n * Possible values:\n * merge\n * replace\n *\n * Merge:\n *\n * Recursively shallow copy properties from the new record onto the existing\n * record.\n *\n * Replace:\n *\n * Shallow copy top-level properties from the new record onto the existing\n * record. Any top-level own properties of the existing record that are _not_\n * on the new record will be removed.\n *\n * @name Collection#onConflict\n * @type {string}\n * @default \"merge\"\n */\n onConflict: 'merge'\n}\n\n/**\n * An ordered set of {@link Record} instances.\n *\n * @example Collection#constructor\n * // import {Collection, Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const user1 = new Record({ id: 1 })\n * const user2 = new Record({ id: 2 })\n * const UserCollection = new Collection([user1, user2])\n * console.log(UserCollection.get(1) === user1)\n *\n * @class Collection\n * @extends Component\n * @param {Array} [records] Initial set of records to insert into the\n * collection.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.commitOnMerge] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.idAttribute] See {@link Collection#idAttribute}.\n * @param {string} [opts.onConflict=\"merge\"] See {@link Collection#onConflict}.\n * @param {string} [opts.mapper] See {@link Collection#mapper}.\n * @since 3.0.0\n */\nfunction Collection (records, opts) {\n utils.classCallCheck(this, Collection)\n Component.call(this, opts)\n\n if (records && !utils.isArray(records)) {\n opts = records\n records = []\n }\n if (utils.isString(opts)) {\n opts = { idAttribute: opts }\n }\n\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * Default Mapper for this collection. Optional. If a Mapper is provided, then\n * the collection will use the {@link Mapper#idAttribute} setting, and will\n * wrap records in {@link Mapper#recordClass}.\n *\n * @example Collection#mapper\n * // Normally you would do: import {Collection, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const myMapper = new MyMapperClass({ name: 'myMapper' })\n * const collection = new Collection(null, { mapper: myMapper })\n *\n * @name Collection#mapper\n * @type {Mapper}\n * @default null\n * @since 3.0.0\n */\n mapper: {\n value: undefined,\n writable: true\n },\n // Query class used by this collection\n queryClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(COLLECTION_DEFAULTS))\n\n if (!this.queryClass) {\n this.queryClass = Query\n }\n\n const idAttribute = this.recordId()\n\n Object.defineProperties(this, {\n /**\n * The main index, which uses @{link Collection#recordId} as the key.\n *\n * @name Collection#index\n * @type {Index}\n */\n index: {\n value: new Index([idAttribute], {\n hashCode (obj) {\n return utils.get(obj, idAttribute)\n }\n })\n },\n\n /**\n * Object that holds the secondary indexes of this collection.\n *\n * @name Collection#indexes\n * @type {Object.}\n */\n indexes: {\n value: {}\n }\n })\n\n // Insert initial data into the collection\n if (utils.isObject(records) || (utils.isArray(records) && records.length)) {\n this.add(records)\n }\n}\n\nexport default Component.extend({\n constructor: Collection,\n\n /**\n * Used to bind to events emitted by records in this Collection.\n *\n * @method Collection#_onRecordEvent\n * @since 3.0.0\n * @private\n * @param {...*} [arg] Args passed to {@link Collection#emit}.\n */\n _onRecordEvent (...args) {\n this.emit(...args)\n },\n\n /**\n * Insert the provided record or records.\n *\n * If a record is already in the collection then the provided record will\n * either merge with or replace the existing record based on the value of the\n * `onConflict` option.\n *\n * The collection's secondary indexes will be updated as each record is\n * visited.\n *\n * @method Collection#add\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} data The record or records to insert.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.onConflict] See {@link Collection#onConflict}.\n * @returns {(Object|Object[]|Record|Record[])} The added record or records.\n */\n add (records, opts) {\n // Default values for arguments\n opts || (opts = {})\n\n // Fill in \"opts\" with the Collection's configuration\n utils._(opts, this)\n records = this.beforeAdd(records, opts) || records\n\n // Track whether just one record or an array of records is being inserted\n let singular = false\n const idAttribute = this.recordId()\n if (!utils.isArray(records)) {\n if (utils.isObject(records)) {\n records = [records]\n singular = true\n } else {\n throw utils.err(`${DOMAIN}#add`, 'records')(400, 'object or array', records)\n }\n }\n\n // Map the provided records to existing records.\n // New records will be inserted. If any records map to existing records,\n // they will be merged into the existing records according to the onConflict\n // option.\n records = records.map((record) => {\n let id = this.recordId(record)\n // Grab existing record if there is one\n const existing = id === undefined ? id : this.get(id)\n // If the currently visited record is just a reference to an existing\n // record, then there is nothing to be done. Exit early.\n if (record === existing) {\n return existing\n }\n\n if (existing) {\n // Here, the currently visited record corresponds to a record already\n // in the collection, so we need to merge them\n const onConflict = opts.onConflict || this.onConflict\n if (onConflict === 'merge') {\n utils.deepMixIn(existing, record)\n } else if (onConflict === 'replace') {\n utils.forOwn(existing, (value, key) => {\n if (key !== idAttribute && record[key] === undefined) {\n existing[key] = undefined\n }\n })\n existing.set(record)\n } else {\n throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)\n }\n record = existing\n if (opts.commitOnMerge && utils.isFunction(record.commit)) {\n record.commit()\n }\n // Update all indexes in the collection\n this.updateIndexes(record)\n } else {\n // Here, the currently visted record does not correspond to any record\n // in the collection, so (optionally) instantiate this record and insert\n // it into the collection\n record = this.mapper ? this.mapper.createRecord(record, opts) : record\n this.index.insertRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.insertRecord(record)\n })\n if (record && utils.isFunction(record.on)) {\n record.on('all', this._onRecordEvent, this)\n }\n }\n return record\n })\n // Finally, return the inserted data\n const result = singular ? records[0] : records\n this.emit('add', result)\n return this.afterAdd(records, opts, result) || result\n },\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then {@link Collection#add} will return that same value.\n *\n * @method Collection#method\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} result The record or records\n * that were added to this Collection by {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n afterAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}. If this method returns\n * a value then {@link Collection#remove} will return that same value.\n *\n * @method Collection#afterRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n * @param {Object} record The result that will be returned by {@link Collection#remove}.\n */\n afterRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}. If this method\n * returns a value then {@link Collection#removeAll} will return that same\n * value.\n *\n * @method Collection#afterRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n * @param {Object} records The result that will be returned by {@link Collection#removeAll}.\n */\n afterRemoveAll () {},\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then the `records` argument in {@link Collection#add} will be\n * re-assigned to the returned value.\n *\n * @method Collection#beforeAdd\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} records The `records` argument passed to {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n beforeAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}.\n *\n * @method Collection#beforeRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n */\n beforeRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}.\n *\n * @method Collection#beforeRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n */\n beforeRemoveAll () {},\n\n /**\n * Find all records between two boundaries.\n *\n * Shortcut for `collection.query().between(18, 30, { index: 'age' }).run()`\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = collection.between(18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = collection.between([18], [30], { index: 'age' })\n *\n * @method Collection#between\n * @since 3.0.0\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting records to skip.\n * @returns {Object[]|Record[]} The result.\n */\n between (leftKeys, rightKeys, opts) {\n return this.query().between(leftKeys, rightKeys, opts).run()\n },\n\n /**\n * Create a new secondary index on the contents of the collection.\n *\n * @example\n * // Index users by age\n * collection.createIndex('age')\n *\n * @example\n * // Index users by status and role\n * collection.createIndex('statusAndRole', ['status', 'role'])\n *\n * @method Collection#createIndex\n * @since 3.0.0\n * @param {string} name The name of the new secondary index.\n * @param {string[]} [fieldList] Array of field names to use as the key or\n * compound key of the new secondary index. If no fieldList is provided, then\n * the name will also be the field that is used to index the collection.\n */\n createIndex (name, fieldList, opts) {\n if (utils.isString(name) && fieldList === undefined) {\n fieldList = [name]\n }\n opts || (opts = {})\n opts.hashCode || (opts.hashCode = (obj) => this.recordId(obj))\n const index = this.indexes[name] = new Index(fieldList, opts)\n this.index.visitAll(index.insertRecord, index)\n },\n\n /**\n * Find the record or records that match the provided query or pass the\n * provided filter function.\n *\n * Shortcut for `collection.query().filter(queryOrFn[, thisArg]).run()`\n *\n * @example Collection#filter\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const collection = new Collection([\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = collection.filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = collection.filter(function (post) {\n * return post.id % 2 === 0\n * })\n *\n * @method Collection#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Object} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Array} The result.\n * @see query\n * @since 3.0.0\n */\n filter (query, thisArg) {\n return this.query().filter(query, thisArg).run()\n },\n\n /**\n * Iterate over all records.\n *\n * @example\n * collection.forEach(function (record) {\n * // do something\n * })\n *\n * @method Collection#forEach\n * @since 3.0.0\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Array} The result.\n */\n forEach (cb, thisArg) {\n this.index.visitAll(cb, thisArg)\n },\n\n /**\n * Get the record with the given id.\n *\n * @method Collection#get\n * @since 3.0.0\n * @param {(string|number)} id The primary key of the record to get.\n * @returns {(Object|Record)} The record with the given id.\n */\n get (id) {\n const instances = this.query().get(id).run()\n return instances.length ? instances[0] : undefined\n },\n\n /**\n * Find the record or records that match the provided keyLists.\n *\n * Shortcut for `collection.query().getAll(keyList1, keyList2, ...).run()`\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = collection.getAll('draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = collection.getAll(['draft'], ['inReview'], { index: 'status' })\n *\n * @method Collection#getAll\n * @since 3.0.0\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * records matching each keyList will be retrieved. If no keyLists are\n * provided, all records will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Array} The result.\n */\n getAll (...args) {\n return this.query().getAll(...args).run()\n },\n\n /**\n * Return the index with the given name. If no name is provided, return the\n * main index. Throws an error if the specified index does not exist.\n *\n * @method Collection#getIndex\n * @since 3.0.0\n * @param {string} [name] The name of the index to retrieve.\n */\n getIndex (name) {\n const index = name ? this.indexes[name] : this.index\n if (!index) {\n throw utils.err(`${DOMAIN}#getIndex`, name)(404, 'index')\n }\n return index\n },\n\n /**\n * Limit the result.\n *\n * Shortcut for `collection.query().limit(maximumNumber).run()`\n *\n * @example\n * const posts = collection.limit(10)\n *\n * @method Collection#limit\n * @since 3.0.0\n * @param {number} num The maximum number of records to keep in the result.\n * @returns {Array} The result.\n */\n limit (num) {\n return this.query().limit(num).run()\n },\n\n /**\n * Apply a mapping function to all records.\n *\n * @example\n * const names = collection.map(function (user) {\n * return user.name\n * })\n *\n * @method Collection#map\n * @since 3.0.0\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Array} The result of the mapping.\n */\n map (cb, thisArg) {\n const data = []\n this.index.visitAll(function (value) {\n data.push(cb.call(thisArg, value))\n })\n return data\n },\n\n /**\n * Return the result of calling the specified function on each record in this\n * collection's main index.\n *\n * @method Collection#mapCall\n * @since 3.0.0\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Array} The result.\n */\n mapCall (funcName, ...args) {\n const data = []\n this.index.visitAll(function (record) {\n data.push(record[funcName](...args))\n })\n return data\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#prune\n * @param {Object} [opts] Configuration options, passed to {@link Collection#removeAll}.\n * @since 3.0.0\n * @returns {Array} The removed records, if any.\n */\n prune (opts) {\n return this.removeAll(this.unsaved(), opts)\n },\n\n /**\n * Create a new query to be executed against the contents of the collection.\n * The result will be all or a subset of the contents of the collection.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * collection.query()\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method Collection#query\n * @since 3.0.0\n * @returns {Query} New query object.\n */\n query () {\n const Ctor = this.queryClass\n return new Ctor(this)\n },\n\n /**\n * Return the primary key of the given, or if no record is provided, return the\n * name of the field that holds the primary key of records in this Collection.\n *\n * @method Collection#recordId\n * @since 3.0.0\n * @param {(Object|Record)} [record] The record whose primary key is to be\n * returned.\n * @returns {(string|number)} Primary key or name of field that holds primary\n * key.\n */\n recordId (record) {\n if (record) {\n return utils.get(record, this.recordId())\n }\n return this.mapper ? this.mapper.idAttribute : this.idAttribute\n },\n\n /**\n * Reduce the data in the collection to a single value and return the result.\n *\n * @example\n * const totalVotes = collection.reduce(function (prev, record) {\n * return prev + record.upVotes + record.downVotes\n * }, 0)\n *\n * @method Collection#reduce\n * @since 3.0.0\n * @param {Function} cb Reduction callback.\n * @param {*} initialValue Initial value of the reduction.\n * @returns {*} The result.\n */\n reduce (cb, initialValue) {\n const data = this.getAll()\n return data.reduce(cb, initialValue)\n },\n\n /**\n * Remove the record with the given id from this Collection.\n *\n * @method Collection#remove\n * @since 3.0.0\n * @param {(string|number|object|Record)} idOrRecord The primary key of the\n * record to be removed, or a reference to the record that is to be removed.\n * @param {Object} [opts] Configuration options.\n * @returns {Object|Record} The removed record, if any.\n */\n remove (idOrRecord, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemove(idOrRecord, opts)\n let record = utils.isSorN(idOrRecord) ? this.get(idOrRecord) : idOrRecord\n\n // The record is in the collection, remove it\n if (utils.isObject(record)) {\n record = this.index.removeRecord(record)\n if (record) {\n utils.forOwn(this.indexes, function (index, name) {\n index.removeRecord(record)\n })\n if (utils.isFunction(record.off)) {\n record.off('all', this._onRecordEvent, this)\n if (!opts.silent) {\n this.emit('remove', record)\n }\n }\n }\n }\n return this.afterRemove(idOrRecord, opts, record) || record\n },\n\n /**\n * Remove from this collection the given records or the records selected by\n * the given \"query\".\n *\n * @method Collection#removeAll\n * @since 3.0.0\n * @param {Object|Object[]|Record[]} [queryOrRecords={}] Records to be removed or selection query. See {@link query}.\n * @param {Object} [queryOrRecords.where] See {@link query.where}.\n * @param {number} [queryOrRecords.offset] See {@link query.offset}.\n * @param {number} [queryOrRecords.limit] See {@link query.limit}.\n * @param {string|Array[]} [queryOrRecords.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object[]|Record[])} The removed records, if any.\n */\n removeAll (queryOrRecords, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemoveAll(queryOrRecords, opts)\n let records = utils.isArray(queryOrRecords) ? queryOrRecords.slice() : this.filter(queryOrRecords)\n\n // Remove each selected record from the collection\n const optsCopy = utils.plainCopy(opts)\n optsCopy.silent = true\n records = records\n .map((record) => this.remove(record, optsCopy))\n .filter((record) => record)\n if (!opts.silent) {\n this.emit('remove', records)\n }\n return this.afterRemoveAll(queryOrRecords, opts, records) || records\n },\n\n /**\n * Skip a number of results.\n *\n * Shortcut for `collection.query().skip(numberToSkip).run()`\n *\n * @example\n * const posts = collection.skip(10)\n *\n * @method Collection#skip\n * @since 3.0.0\n * @param {number} num The number of records to skip.\n * @returns {Array} The result.\n */\n skip (num) {\n return this.query().skip(num).run()\n },\n\n /**\n * Return the plain JSON representation of all items in this collection.\n * Assumes records in this collection have a toJSON method.\n *\n * @method Collection#toJSON\n * @since 3.0.0\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation.\n * @returns {Array} The records.\n */\n toJSON (opts) {\n return this.mapCall('toJSON', opts)\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#unsaved\n * @since 3.0.0\n * @returns {Array} The unsaved records, if any.\n */\n unsaved (opts) {\n return this.index.get()\n },\n\n /**\n * Update a record's position in a single index of this collection. See\n * {@link Collection#updateIndexes} to update a record's position in all\n * indexes at once.\n *\n * @method Collection#updateIndex\n * @since 3.0.0\n * @param {Object} record The record to update.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] The index in which to update the record's\n * position. If you don't specify an index then the record will be updated\n * in the main index.\n */\n updateIndex (record, opts) {\n opts || (opts = {})\n this.getIndex(opts.index).updateRecord(record)\n },\n\n /**\n * Updates all indexes in this collection for the provided record. Has no\n * effect if the record is not in the collection.\n *\n * @method Collection#updateIndexes\n * @since 3.0.0\n * @param {Object} record TODO\n */\n updateIndexes (record) {\n this.index.updateRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.updateRecord(record)\n })\n }\n})\n\n/**\n * Fired when a record changes. Only works for records that have tracked changes.\n * See {@link Collection~changeListener} on how to listen for this event.\n *\n * @event Collection#change\n * @see Collection~changeListener\n */\n\n/**\n * Callback signature for the {@link Collection#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * collection.on('change', onChange)\n *\n * @callback Collection~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Collection#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the Collection. See\n * {@link Collection~addListener} on how to listen for this event.\n *\n * @event Collection#add\n * @see Collection~addListener\n * @see Collection#event:add\n * @see Collection#add\n */\n\n/**\n * Callback signature for the {@link Collection#event:add} event.\n *\n * @example\n * function onAdd (recordOrRecords) {\n * // do something\n * }\n * collection.on('add', onAdd)\n *\n * @callback Collection~addListener\n * @param {Record|Record[]} The Record or Records that were added.\n * @see Collection#event:add\n * @see Collection#add\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the Collection. See\n * {@link Collection~removeListener} for how to listen for this event.\n *\n * @event Collection#remove\n * @see Collection~removeListener\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n */\n\n/**\n * Callback signature for the {@link Collection#event:remove} event.\n *\n * @example\n * function onRemove (recordsOrRecords) {\n * // do something\n * }\n * collection.on('remove', onRemove)\n *\n * @callback Collection~removeListener\n * @param {Record|Record[]} Record or Records that were removed.\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Collection:\n * @example Collection.extend\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomCollectionClass extends Collection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customCollection = new CustomCollectionClass()\n * console.log(customCollection.foo())\n * console.log(CustomCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherCollectionClass = Collection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherCollection = new OtherCollectionClass()\n * console.log(otherCollection.foo())\n * console.log(OtherCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherCollectionClass () {\n * Collection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Collection.extend({\n * constructor: AnotherCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherCollection = new AnotherCollectionClass()\n * console.log(anotherCollection.created_at)\n * console.log(anotherCollection.foo())\n * console.log(AnotherCollectionClass.beep())\n *\n * @method Collection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Collection class.\n * @since 3.0.0\n */\n","import utils from './utils'\n\n// TODO: remove this when the rest of the project is cleaned\nexport const belongsToType = 'belongsTo'\nexport const hasManyType = 'hasMany'\nexport const hasOneType = 'hasOne'\n\nconst DOMAIN = 'Relation'\n\nexport function Relation (relatedMapper, options = {}) {\n utils.classCallCheck(this, Relation)\n\n options.type = this.constructor.TYPE_NAME\n this.validateOptions(relatedMapper, options)\n\n if (typeof relatedMapper === 'object') {\n Object.defineProperty(this, 'relatedMapper', { value: relatedMapper })\n }\n\n Object.defineProperty(this, 'inverse', { writable: true })\n utils.fillIn(this, options)\n}\n\nRelation.extend = utils.extend\n\nutils.addHiddenPropsToTarget(Relation.prototype, {\n get canAutoAddLinks () {\n return this.add === undefined || !!this.add\n },\n\n get relatedCollection () {\n return this.mapper.datastore.getCollection(this.relation)\n },\n\n validateOptions (related, opts) {\n const DOMAIN_ERR = `new ${DOMAIN}`\n\n const localField = opts.localField\n if (!localField) {\n throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField)\n }\n\n const foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey\n if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) {\n throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey)\n }\n\n if (utils.isString(related)) {\n opts.relation = related\n if (!utils.isFunction(opts.getRelation)) {\n throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation)\n }\n } else if (related) {\n opts.relation = related.name\n } else {\n throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related)\n }\n },\n\n assignTo (mapper) {\n this.name = mapper.name\n Object.defineProperty(this, 'mapper', { value: mapper })\n\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] })\n mapper.relationList.push(this)\n mapper.relationFields.push(this.localField)\n },\n\n canFindLinkFor () {\n return !!(this.foreignKey || this.localKey)\n },\n\n getRelation () {\n return this.relatedMapper\n },\n\n getForeignKey (record) {\n return utils.get(record, this.mapper.idAttribute)\n },\n\n setForeignKey (record, relatedRecord) {\n if (!record || !relatedRecord) {\n return\n }\n\n this._setForeignKey(record, relatedRecord)\n },\n\n _setForeignKey (record, relatedRecords) {\n const idAttribute = this.mapper.idAttribute\n\n if (!utils.isArray(relatedRecords)) {\n relatedRecords = [relatedRecords]\n }\n\n relatedRecords.forEach((relatedRecord) => {\n utils.set(relatedRecord, this.foreignKey, utils.get(record, idAttribute))\n })\n },\n\n getLocalField (record) {\n return utils.get(record, this.localField)\n },\n\n setLocalField (record, relatedData) {\n return utils.set(record, this.localField, relatedData)\n },\n\n getInverse (mapper) {\n if (!this.inverse) {\n this.findInverseRelation(mapper)\n }\n\n return this.inverse\n },\n\n findInverseRelation (mapper) {\n this.getRelation().relationList.forEach((def) => {\n if (def.getRelation() === mapper && this.isInversedTo(def)) {\n this.inverse = def\n return true\n }\n })\n },\n\n isInversedTo (def) {\n return !def.foreignKey || def.foreignKey === this.foreignKey\n },\n\n addLinkedRecords (records) {\n const datastore = this.mapper.datastore\n\n records.forEach((record) => {\n let relatedData = this.getLocalField(record)\n\n if (utils.isFunction(this.add)) {\n relatedData = this.add(datastore, this, record)\n } else if (relatedData) {\n relatedData = this.linkRecord(record, relatedData)\n }\n\n const isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length\n\n if (isEmptyLinks && this.canFindLinkFor(record)) {\n relatedData = this.findExistingLinksFor(record)\n }\n\n if (relatedData) {\n this.setLocalField(record, relatedData)\n }\n })\n },\n\n removeLinkedRecords (relatedMapper, records) {\n const localField = this.localField\n records.forEach((record) => {\n utils.set(record, localField, undefined)\n })\n },\n\n linkRecord (record, relatedRecord) {\n const relatedId = utils.get(relatedRecord, this.mapper.idAttribute)\n\n if (relatedId === undefined) {\n const unsaved = this.relatedCollection.unsaved()\n if (unsaved.indexOf(relatedRecord) === -1) {\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n } else {\n if (relatedRecord !== this.relatedCollection.get(relatedId)) {\n this.setForeignKey(record, relatedRecord)\n\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n }\n\n return relatedRecord\n },\n\n // e.g. user hasMany post via \"foreignKey\", so find all posts of user\n findExistingLinksByForeignKey (id) {\n if (id === undefined || id === null) {\n return\n }\n return this.relatedCollection.filter({\n [this.foreignKey]: id\n })\n }\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const BelongsToRelation = Relation.extend({\n getForeignKey (record) {\n return utils.get(record, this.foreignKey)\n },\n\n _setForeignKey (record, relatedRecord) {\n utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute))\n },\n\n findExistingLinksFor (record) {\n // console.log('\\tBelongsTo#findExistingLinksFor', record)\n if (!record) {\n return\n }\n const relatedId = utils.get(record, this.foreignKey)\n if (relatedId !== undefined && relatedId !== null) {\n return this.relatedCollection.get(relatedId)\n }\n }\n}, {\n TYPE_NAME: 'belongsTo'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasManyRelation = Relation.extend({\n validateOptions (related, opts) {\n Relation.prototype.validateOptions.call(this, related, opts)\n\n const { localKeys, foreignKeys, foreignKey } = opts\n\n if (!foreignKey && !localKeys && !foreignKeys) {\n throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey)\n }\n },\n\n canFindLinkFor (record) {\n const hasForeignKeys = this.foreignKey || this.foreignKeys\n return !!(hasForeignKeys || (this.localKeys && utils.get(record, this.localKeys)))\n },\n\n linkRecord (record, relatedRecords) {\n const relatedCollection = this.relatedCollection\n const canAutoAddLinks = this.canAutoAddLinks\n const foreignKey = this.foreignKey\n const unsaved = this.relatedCollection.unsaved()\n\n return relatedRecords.map((relatedRecord) => {\n const relatedId = relatedCollection.recordId(relatedRecord)\n\n if ((relatedId === undefined && unsaved.indexOf(relatedRecord) === -1) || relatedRecord !== relatedCollection.get(relatedId)) {\n if (foreignKey) {\n // TODO: slow, could be optimized? But user loses hook\n this.setForeignKey(record, relatedRecord)\n }\n if (canAutoAddLinks) {\n relatedRecord = relatedCollection.add(relatedRecord)\n }\n }\n\n return relatedRecord\n })\n },\n\n findExistingLinksFor (record) {\n const id = utils.get(record, this.mapper.idAttribute)\n const ids = this.localKeys ? utils.get(record, this.localKeys) : null\n let records\n\n if (id !== undefined && this.foreignKey) {\n records = this.findExistingLinksByForeignKey(id)\n } else if (this.localKeys && ids) {\n records = this.findExistingLinksByLocalKeys(ids)\n } else if (id !== undefined && this.foreignKeys) {\n records = this.findExistingLinksByForeignKeys(id)\n }\n\n if (records && records.length) {\n return records\n }\n },\n\n // e.g. user hasMany group via \"foreignKeys\", so find all users of a group\n findExistingLinksByLocalKeys (ids) {\n return this.relatedCollection.filter({\n where: {\n [this.mapper.idAttribute]: {\n 'in': ids\n }\n }\n })\n },\n\n // e.g. group hasMany user via \"localKeys\", so find all groups that own a user\n findExistingLinksByForeignKeys (id) {\n return this.relatedCollection.filter({\n where: {\n [this.foreignKeys]: {\n 'contains': id\n }\n }\n })\n }\n}, {\n TYPE_NAME: 'hasMany'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasOneRelation = Relation.extend({\n findExistingLinksFor (relatedMapper, record) {\n const recordId = utils.get(record, relatedMapper.idAttribute)\n const records = this.findExistingLinksByForeignKey(recordId)\n\n if (records && records.length) {\n return records[0]\n }\n }\n}, {\n TYPE_NAME: 'hasOne'\n})\n","import { Relation } from './Relation'\nimport { BelongsToRelation } from './Relation/BelongsTo'\nimport { HasManyRelation } from './Relation/HasMany'\nimport { HasOneRelation } from './Relation/HasOne'\n\n[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) {\n Relation[RelationType.TYPE_NAME] = function (related, options) {\n return new RelationType(related, options)\n }\n})\n\nexport { belongsToType, hasManyType, hasOneType, Relation } from './Relation'\n","import { Relation } from './relations'\n\nexport { belongsToType, hasManyType, hasOneType } from './relations'\n/**\n * BelongsTo relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.belongsTo\n * @method\n * @param {Mapper} related The relation the target belongs to.\n * @param {Object} opts Configuration options.\n * @param {string} opts.foreignKey The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const belongsTo = function (related, opts) {\n return function (mapper) {\n Relation.belongsTo(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasMany relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasMany\n * @method\n * @param {Mapper} related The relation of which the target has many.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasMany = function (related, opts) {\n return function (mapper) {\n Relation.hasMany(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasOne relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasOne\n * @method\n * @param {Mapper} related The relation of which the target has one.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasOne = function (related, opts) {\n return function (mapper) {\n Relation.hasOne(related, opts).assignTo(mapper)\n }\n}\n","import utils, { safeSetLink } from './utils'\nimport Component from './Component'\nimport Settable from './Settable'\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Record'\n\nconst superMethod = function (mapper, name) {\n const store = mapper.datastore\n if (store && store[name]) {\n return function (...args) {\n return store[name](mapper.name, ...args)\n }\n }\n return mapper[name].bind(mapper)\n}\n\n/**\n * js-data's Record class. An instance of `Record` corresponds to an in-memory\n * representation of a single row or document in a database, Firebase,\n * localstorage, etc. Basically, a `Record` instance represents whatever kind of\n * entity in your persistence layer that has a primary key.\n *\n * ```javascript\n * import {Record} from 'js-data'\n * ```\n *\n * @example Record#constructor\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a plain record\n * let record = new Record()\n * console.log('record: ' + JSON.stringify(record))\n *\n * // You can supply properties on instantiation\n * record = new Record({ name: 'John' })\n * console.log('record: ' + JSON.stringify(record))\n *\n * @example Record#constructor2\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a record that's associated with a Mapper:\n * const UserMapper = new Mapper({ name: 'user' })\n * const User = UserMapper.recordClass\n * const user = UserMapper.createRecord({ name: 'John' })\n * const user2 = new User({ name: 'Sally' })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user2: ' + JSON.stringify(user2))\n *\n * @example Record#constructor3\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n *\n * // Instantiate a record that's associated with a store's Mapper\n * const user = store.createRecord('user', { name: 'John' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor4\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Validate on instantiation\n * const user = store.createRecord('user', { name: 1234 })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor5\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Skip validation on instantiation\n * const user = store.createRecord('user', { name: 1234 }, { noValidate: true })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user.isValid(): ' + user.isValid())\n *\n * @class Record\n * @extends Component\n * @param {Object} [props] The initial properties of the new Record instance.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate=false] Whether to skip validation on the\n * initial properties.\n * @since 3.0.0\n */\nfunction Record (props, opts) {\n utils.classCallCheck(this, Record)\n Settable.call(this)\n props || (props = {})\n opts || (opts = {})\n const _set = this._set\n // TODO: Optimize these strings\n _set('creating', true)\n if (opts.noValidate) {\n _set('noValidate', true)\n }\n // Set the idAttribute value first, if it exists.\n const mapper = this.constructor.mapper\n const id = mapper ? utils.get(props, mapper.idAttribute) : undefined\n if (id !== undefined) {\n utils.set(this, mapper.idAttribute, id)\n }\n utils.fillIn(this, props)\n _set('creating', false)\n _set('noValidate', false)\n _set('previous', utils.plainCopy(props))\n}\n\nexport default Component.extend({\n constructor: Record,\n\n /**\n * Returns the {@link Mapper} paired with this record's class, if any.\n *\n * @method Record#_mapper\n * @returns {Mapper} The {@link Mapper} paired with this record's class, if any.\n * @since 3.0.0\n */\n _mapper () {\n const mapper = this.constructor.mapper\n if (!mapper) {\n throw utils.err(`${DOMAIN}#_mapper`, '')(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Lifecycle hook.\n *\n * @method Record#afterLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n afterLoadRelations () {},\n\n /**\n * Lifecycle hook.\n *\n * @method Record#beforeLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n beforeLoadRelations () {},\n\n /**\n * Return the change history of this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @method Record#changeHistory\n * @since 3.0.0\n */\n changeHistory () {\n return (this._get('history') || []).slice()\n },\n\n /**\n * Return changes to this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#changes\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n * user.name = 'John'\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n *\n * @method Record#changes\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} Object describing the changes to this record since it was\n * instantiated or its {@link Record#commit} method was last called.\n * @since 3.0.0\n */\n changes (opts) {\n opts || (opts = {})\n return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Make the record's current in-memory state it's only state, with any\n * previous property values being set to current values.\n *\n * @example Record#commit\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#commit\n * @since 3.0.0\n */\n commit () {\n this._set('changed') // unset\n this._set('history', []) // clear history\n this._set('previous', utils.plainCopy(this))\n },\n\n /**\n * Call {@link Mapper#destroy} using this record's primary key.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user')\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Destroy this user from the database\n * return user.destroy()\n * })\n *\n * @method Record#destroy\n * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}.\n * @returns {Promise} The result of calling {@link Mapper#destroy} with the\n * primary key of this record.\n * @since 3.0.0\n */\n destroy (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts)\n },\n\n /**\n * Return the value at the given path for this instance.\n *\n * @example Record#get\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', { name: 'Bob' })\n * console.log('user.get(\"name\"): ' + user.get('name'))\n *\n * @method Record#get\n * @param {string} key Path of value to retrieve.\n * @returns {*} Value at path.\n * @since 3.0.0\n */\n 'get' (key) {\n return utils.get(this, key)\n },\n\n /**\n * Return whether this record has changed since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#hasChanges\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#hasChanges\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Return whether the record has changed since it was\n * instantiated or since its {@link Record#commit} method was called.\n * @since 3.0.0\n */\n hasChanges (opts) {\n const quickHasChanges = !!(this._get('changed') || []).length\n return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Return whether the record is unsaved. Records that have primary keys are\n * considered \"saved\". Records without primary keys are considered \"unsaved\".\n *\n * @example Record#isNew\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * id: 1234\n * })\n * const user2 = store.createRecord('user')\n * console.log('user isNew: ' + user.isNew()) // false\n * console.log('user2 isNew: ' + user2.isNew()) // true\n *\n * @method Record#isNew\n * @returns {boolean} Whether the record is unsaved.\n * @since 3.0.0\n */\n isNew (opts) {\n return utils.get(this, this._mapper().idAttribute) === undefined\n },\n\n /**\n * Return whether the record in its current state passes validation.\n *\n * @example Record#isValid\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user isValid: ' + user.isValid())\n * user.name = 'John'\n * console.log('user isValid: ' + user.isValid())\n *\n * @method Record#isValid\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {boolean} Whether the record in its current state passes\n * validation.\n * @since 3.0.0\n */\n isValid (opts) {\n return !this._mapper().validate(this, opts)\n },\n\n removeInverseRelation(currentParent, id, inverseDef, idAttribute) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n // e.g. remove comment from otherPost.comments\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n },\n\n setupInverseRelation(record, id, inverseDef, idAttribute) {\n // Update (set) inverse relation\n if (inverseDef.type === hasOneType) {\n // e.g. someUser.profile = profile\n safeSetLink(record, inverseDef.localField, this)\n } else if (inverseDef.type === hasManyType) {\n // e.g. add comment to somePost.comments\n const children = utils.get(record, inverseDef.localField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n },\n\n /**\n * Lazy load relations of this record, to be attached to the record once their\n * loaded.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user', {\n * relations: {\n * hasMany: {\n * post: {\n * localField: 'posts',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.defineMapper('post', {\n * relations: {\n * belongsTo: {\n * user: {\n * localField: 'user',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Load the user's post relations\n * return user.loadRelations(['post'])\n * }).then((user) => {\n * console.log(user.posts) // [{...}, {...}, ...]\n * })\n *\n * @method Record#loadRelations\n * @param {string[]} [relations] List of relations to load. Can use localField\n * names or Mapper names to pick relations.\n * @param {Object} [opts] Configuration options.\n * @returns {Promise} Resolves with the record, with the loaded relations now\n * attached.\n * @since 3.0.0\n */\n loadRelations (relations, opts) {\n let op\n const mapper = this._mapper()\n\n // Default values for arguments\n relations || (relations = [])\n if (utils.isString(relations)) {\n relations = [relations]\n }\n opts || (opts = {})\n opts.with = relations\n\n // Fill in \"opts\" with the Model's configuration\n utils._(opts, mapper)\n opts.adapter = mapper.getAdapterName(opts)\n\n // beforeLoadRelations lifecycle hook\n op = opts.op = 'beforeLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'loadRelations'\n mapper.dbg(op, this, relations, opts)\n let tasks = []\n let task\n utils.forEachRelation(mapper, opts, (def, optsCopy) => {\n const relatedMapper = def.getRelation()\n optsCopy.raw = false\n if (utils.isFunction(def.load)) {\n task = def.load(mapper, def, this, opts)\n } else if (def.type === 'hasMany' || def.type === 'hasOne') {\n if (def.foreignKey) {\n task = superMethod(relatedMapper, 'findAll')({\n [def.foreignKey]: utils.get(this, mapper.idAttribute)\n }, optsCopy).then(function (relatedData) {\n if (def.type === 'hasOne') {\n return relatedData.length ? relatedData[0] : undefined\n }\n return relatedData\n })\n } else if (def.localKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [relatedMapper.idAttribute]: {\n 'in': utils.get(this, def.localKeys)\n }\n }\n })\n } else if (def.foreignKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [def.foreignKeys]: {\n 'contains': utils.get(this, mapper.idAttribute)\n }\n }\n }, opts)\n }\n } else if (def.type === 'belongsTo') {\n const key = utils.get(this, def.foreignKey)\n if (utils.isSorN(key)) {\n task = superMethod(relatedMapper, 'find')(key, optsCopy)\n }\n }\n if (task) {\n task = task.then((relatedData) => {\n def.setLocalField(this, relatedData)\n })\n tasks.push(task)\n }\n })\n return Promise.all(tasks)\n }).then(() => {\n // afterLoadRelations lifecycle hook\n op = opts.op = 'afterLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => this)\n })\n },\n\n /**\n * Return the properties with which this record was instantiated.\n *\n * @example Record#previous\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.name = 'Bob'\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.commit()\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n *\n * @method Record#previous\n * @param {string} [key] If specified, return just the initial value of the\n * given key.\n * @returns {Object} The initial properties of this record.\n * @since 3.0.0\n */\n previous (key) {\n if (key) {\n return this._get(`previous.${key}`)\n }\n return this._get('previous')\n },\n\n /**\n * Revert changes to this record back to the properties it had when it was\n * instantiated.\n *\n * @example Record#revert\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user: ' + JSON.stringify(user))\n * user.name = 'Bob'\n * console.log('user: ' + JSON.stringify(user))\n * user.revert()\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#revert\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.preserve] Array of strings or Regular Expressions\n * denoting properties that should not be reverted.\n * @since 3.0.0\n */\n revert (opts) {\n const previous = this._get('previous')\n opts || (opts = {})\n opts.preserve || (opts.preserve = [])\n utils.forOwn(this, (value, key) => {\n if (key !== this._mapper().idAttribute && !previous.hasOwnProperty(key) && this.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) {\n delete this[key]\n }\n })\n utils.forOwn(previous, (value, key) => {\n if (opts.preserve.indexOf(key) === -1) {\n this[key] = value\n }\n })\n this.commit()\n },\n\n /**\n * Delegates to {@link Mapper#create} or {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('session')\n * const session = store.createRecord('session', { topic: 'Node.js' })\n *\n * // Create a new record in the database\n * session.save().then(() => {\n * console.log(session.id) // 1234\n *\n * session.skill_level = 'beginner'\n *\n * // Update the record in the database\n * return user.save()\n * })\n *\n * @method Record#save\n * @param {Object} [opts] Configuration options. See {@link Mapper#create} and\n * {@link Mapper#update}.\n * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`.\n * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @param {Array} [opts.ignore] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @returns {Promise} The result of calling {@link Mapper#create} or\n * {@link Mapper#update}.\n * @since 3.0.0\n */\n save (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n const id = utils.get(this, mapper.idAttribute)\n let props = this\n\n const postProcess = (result) => {\n const record = opts.raw ? result.data : result\n if (record) {\n utils.deepMixIn(this, record)\n this.commit()\n }\n return result\n }\n\n if (id === undefined) {\n return superMethod(mapper, 'create')(props, opts).then(postProcess)\n }\n if (opts.changesOnly) {\n const changes = this.changes(opts)\n props = {}\n utils.fillIn(props, changes.added)\n utils.fillIn(props, changes.changed)\n }\n return superMethod(mapper, 'update')(id, props, opts).then(postProcess)\n },\n\n /**\n * Set the value for a given key, or the values for the given keys if \"key\" is\n * an object. Triggers change events on those properties that have `track: true`\n * in {@link Mapper#schema}.\n *\n * @example Record#set\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set('name', 'Bob')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set({ age: 30, role: 'admin' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @fires Record#change\n * @method Record#set\n * @param {(string|Object)} key Key to set or hash of key-value pairs to set.\n * @param {*} [value] Value to set for the given key.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n 'set' (key, value, opts) {\n if (utils.isObject(key)) {\n opts = value\n }\n opts || (opts = {})\n if (opts.silent) {\n this._set('silent', true)\n }\n utils.set(this, key, value)\n if (!this._get('eventId')) {\n this._set('silent') // unset\n }\n },\n\n /**\n * Return a plain object representation of this record. If the class from\n * which this record was created has a Mapper, then {@link Mapper#toJSON} will\n * be called with this record instead.\n *\n * @example Record#toJSON\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * const user = store.createRecord('user', {\n * name: 'John',\n * $$hashKey: '1234'\n * })\n * console.log('user: ' + JSON.stringify(user.toJSON()))\n * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true })))\n *\n * @method Record#toJSON\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation. Only available as an option if the class\n * from which this record was created has a Mapper and this record resides in\n * an instance of {@link DataStore}.\n * @returns {Object} Plain object representation of this record.\n * @since 3.0.0\n */\n toJSON (opts) {\n const mapper = this.constructor.mapper\n if (mapper) {\n return mapper.toJSON(this, opts)\n } else {\n const json = {}\n utils.forOwn(this, function (prop, key) {\n json[key] = utils.plainCopy(prop)\n })\n return json\n }\n },\n\n /**\n * Unset the value for a given key. Triggers change events on those properties\n * that have `track: true` in {@link Mapper#schema}.\n *\n * @example Record#unset\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', {\n * name: 'John'\n * })\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.unset('name')\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#unset\n * @param {string} key Key to unset.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n unset (key, opts) {\n this.set(key, undefined, opts)\n },\n\n /**\n * Validate this record based on its current properties.\n *\n * @example Record#validate\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user validation: ' + JSON.stringify(user.validate()))\n * user.name = 'John'\n * console.log('user validation: ' + user.validate())\n *\n * @method Record#validate\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {*} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (opts) {\n return this._mapper().validate(this, opts)\n }\n})\n\n/**\n * Allow records to emit events.\n *\n * An record's registered listeners are stored in the record's private data.\n */\nutils.eventify(\n Record.prototype,\n function () {\n return this._get('events')\n },\n function (value) {\n this._set('events', value)\n }\n)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link Record~changeListener} on how to listen for this event.\n *\n * @event Record#change\n * @see Record~changeListener\n */\n\n/**\n * Callback signature for the {@link Record#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * record.on('change', onChange)\n *\n * @callback Record~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Record#event:change\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Record:\n * @example Record.extend\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomRecordClass extends Record {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customRecord = new CustomRecordClass()\n * console.log(customRecord.foo())\n * console.log(CustomRecordClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherRecordClass = Record.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherRecord = new OtherRecordClass()\n * console.log(otherRecord.foo())\n * console.log(OtherRecordClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherRecordClass () {\n * Record.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Record.extend({\n * constructor: AnotherRecordClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherRecord = new AnotherRecordClass()\n * console.log(anotherRecord.created_at)\n * console.log(anotherRecord.foo())\n * console.log(AnotherRecordClass.beep())\n *\n * @method Record.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Record class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Schema'\n\n/**\n * A function map for each of the seven primitive JSON types defined by the core specification.\n * Each function will check a given value and return true or false if the value is an instance of that type.\n * ```\n * types.integer(1) // returns true\n * types.string({}) // returns false\n * ```\n * http://json-schema.org/latest/json-schema-core.html#anchor8\n * @name Schema.types\n * @type {Object}\n */\nconst types = {\n array: utils.isArray,\n boolean: utils.isBoolean,\n integer: utils.isInteger,\n 'null': utils.isNull,\n number: utils.isNumber,\n object: utils.isObject,\n string: utils.isString\n}\n\n/**\n * @ignore\n */\nconst segmentToString = function (segment, prev) {\n let str = ''\n if (segment) {\n if (utils.isNumber(segment)) {\n str += `[${segment}]`\n } else if (prev) {\n str += `.${segment}`\n } else {\n str += `${segment}`\n }\n }\n return str\n}\n\n/**\n * @ignore\n */\nconst makePath = function (opts) {\n opts || (opts = {})\n let path = ''\n const segments = opts.path || []\n segments.forEach(function (segment) {\n path += segmentToString(segment, path)\n })\n path += segmentToString(opts.prop, path)\n return path\n}\n\n/**\n * @ignore\n */\nconst makeError = function (actual, expected, opts) {\n return {\n expected,\n actual: '' + actual,\n path: makePath(opts)\n }\n}\n\n/**\n * @ignore\n */\nconst addError = function (actual, expected, opts, errors) {\n errors.push(makeError(actual, expected, opts))\n}\n\n/**\n * @ignore\n */\nconst maxLengthCommon = function (keyword, value, schema, opts) {\n const max = schema[keyword]\n if (value.length > max) {\n return makeError(value.length, `length no more than ${max}`, opts)\n }\n}\n\n/**\n * @ignore\n */\nconst minLengthCommon = function (keyword, value, schema, opts) {\n const min = schema[keyword]\n if (value.length < min) {\n return makeError(value.length, `length no less than ${min}`, opts)\n }\n}\n\n/**\n * A map of all object member validation functions for each keyword defined in the JSON Schema.\n * @name Schema.validationKeywords\n * @type {Object}\n */\nconst validationKeywords = {\n /**\n * Validates the provided value against all schemas defined in the Schemas `allOf` keyword.\n * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be a valid JSON Schema.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor82\n *\n * @name Schema.validationKeywords.allOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `allOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n allOf (value, schema, opts) {\n let allErrors = []\n schema.allOf.forEach(function (_schema) {\n allErrors = allErrors.concat(validate(value, _schema, opts) || [])\n })\n return allErrors.length ? undefined : allErrors\n },\n\n /**\n * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword.\n * The instance is valid against this keyword if and only if it is valid against\n * at least one of the schemas in this keyword's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor85\n *\n * @name Schema.validationKeywords.anyOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `anyOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n anyOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.anyOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * http://json-schema.org/latest/json-schema-validation.html#anchor70\n *\n * @name Schema.validationKeywords.dependencies\n * @method\n * @param {*} value TODO\n * @param {Object} schema TODO\n * @param {Object} opts TODO\n */\n dependencies (value, schema, opts) {\n // TODO\n },\n\n /**\n * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword\n * Validation succeeds if the value is deeply equal to one of the values in the array.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor76\n *\n * @name Schema.validationKeywords.enum\n * @method\n * @param {*} value Value to validate\n * @param {Object} schema Schema containing the `enum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n enum (value, schema, opts) {\n const possibleValues = schema['enum']\n if (utils.findIndex(possibleValues, (item) => utils.deepEqual(item, value)) === -1) {\n return makeError(value, `one of (${possibleValues.join(', ')})`, opts)\n }\n },\n\n /**\n * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword\n * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules.\n *\n * @name Schema.validationKeywords.items\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the items keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n items (value, schema, opts) {\n opts || (opts = {})\n // TODO: additionalItems\n let items = schema.items\n let errors = []\n const checkingTuple = utils.isArray(items)\n const length = value.length\n for (var prop = 0; prop < length; prop++) {\n if (checkingTuple) {\n // Validating a tuple, instead of just checking each item against the\n // same schema\n items = schema.items[prop]\n }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], items, opts) || [])\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword\n * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor17\n *\n * @name Schema.validationKeywords.maximum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `maximum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maximum (value, schema, opts) {\n // Must be a number\n const maximum = schema.maximum\n // Must be a boolean\n // Depends on maximum\n // default: false\n const exclusiveMaximum = schema.exclusiveMaximum\n if (typeof value === typeof maximum && !(exclusiveMaximum ? maximum > value : maximum >= value)) {\n return exclusiveMaximum\n ? makeError(value, `no more than nor equal to ${maximum}`, opts)\n : makeError(value, `no more than ${maximum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword.\n * Validation succeeds if the length of the array is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor42\n *\n * @name Schema.validationKeywords.maxItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `maxItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return maxLengthCommon('maxItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword.\n * Validation succeeds if the length of the string is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor26\n *\n * @name Schema.validationKeywords.maxLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `maxLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxLength (value, schema, opts) {\n return maxLengthCommon('maxLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword.\n * Validation succeeds if the object's property count is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor54\n *\n * @name Schema.validationKeywords.maxProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `maxProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const maxProperties = schema.maxProperties\n const length = Object.keys(value).length\n if (length > maxProperties) {\n return makeError(length, `no more than ${maxProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword\n * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor21\n *\n * @name Schema.validationKeywords.minimum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `minimum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minimum (value, schema, opts) {\n // Must be a number\n const minimum = schema.minimum\n // Must be a boolean\n // Depends on minimum\n // default: false\n const exclusiveMinimum = schema.exclusiveMinimum\n if (typeof value === typeof minimum && !(exclusiveMinimum ? value > minimum : value >= minimum)) {\n return exclusiveMinimum\n ? makeError(value, `no less than nor equal to ${minimum}`, opts)\n : makeError(value, `no less than ${minimum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword.\n * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor45\n *\n * @name Schema.validationKeywords.minItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `minItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return minLengthCommon('minItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword.\n * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor29\n *\n * @name Schema.validationKeywords.minLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `minLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minLength (value, schema, opts) {\n return minLengthCommon('minLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword.\n * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor57\n *\n * @name Schema.validationKeywords.minProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `minProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const minProperties = schema.minProperties\n const length = Object.keys(value).length\n if (length < minProperties) {\n return makeError(length, `no more than ${minProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword.\n * Validation succeeds if the number can be divided equally into the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor14\n *\n * @name Schema.validationKeywords.multipleOf\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing the `multipleOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n multipleOf (value, schema, opts) {\n const multipleOf = schema.multipleOf\n if (utils.isNumber(value)) {\n if ((value / multipleOf) % 1 !== 0) {\n return makeError(value, `multipleOf ${multipleOf}`, opts)\n }\n }\n },\n\n /**\n * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword.\n * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor91\n * @name Schema.validationKeywords.not\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the not keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n not (value, schema, opts) {\n if (!validate(value, schema.not, opts)) {\n // TODO: better messaging\n return makeError('succeeded', 'should have failed', opts)\n }\n },\n\n /**\n * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword.\n * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor88\n * @name Schema.validationKeywords.oneOf\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the `oneOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n oneOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.oneOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else if (validated) {\n allErrors = [makeError('valid against more than one', 'valid against only one', opts)]\n validated = false\n return false\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword.\n * Validation succeeds if the string is a match of the regex value of this keyword.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor33\n * @name Schema.validationKeywords.pattern\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `pattern` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n pattern (value, schema, opts) {\n const pattern = schema.pattern\n if (utils.isString(value) && !value.match(pattern)) {\n return makeError(value, pattern, opts)\n }\n },\n\n /**\n * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword.\n * Validation succeeds if the object's property are valid with each of the schema's in the provided map.\n * Validation also depends on the additionalProperties and or patternProperties.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info.\n *\n * @name Schema.validationKeywords.properties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `properties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n properties (value, schema, opts) {\n opts || (opts = {})\n // Can be a boolean or an object\n // Technically the default is an \"empty schema\", but here \"true\" is\n // functionally the same\n const additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties\n // \"s\": The property set of the instance to validate.\n const toValidate = {}\n // \"p\": The property set from \"properties\".\n // Default is an object\n const properties = schema.properties || {}\n // \"pp\": The property set from \"patternProperties\".\n // Default is an object\n const patternProperties = schema.patternProperties || {}\n let errors = []\n\n // Collect set \"s\"\n utils.forOwn(value, function (_value, prop) {\n toValidate[prop] = undefined\n })\n // Remove from \"s\" all elements of \"p\", if any.\n utils.forOwn(properties || {}, function (_schema, prop) {\n // if (value[prop] === undefined && _schema['default'] !== undefined) {\n // value[prop] = utils.copy(_schema['default'])\n // }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n })\n // For each regex in \"pp\", remove all elements of \"s\" which this regex\n // matches.\n utils.forOwn(patternProperties, function (_schema, pattern) {\n utils.forOwn(toValidate, function (undef, prop) {\n if (prop.match(pattern)) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n }\n })\n })\n const keys = Object.keys(toValidate)\n // If \"s\" is not empty, validation fails\n if (additionalProperties === false) {\n if (keys.length) {\n addError(`extra fields: ${keys.join(', ')}`, 'no extra fields', opts, errors)\n }\n } else if (utils.isObject(additionalProperties)) {\n // Otherwise, validate according to provided schema\n keys.forEach(function (prop) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], additionalProperties, opts) || [])\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided object's has all properties listed in the Schema's `properties` keyword array.\n * Validation succeeds if the object contains all properties provided in the array value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor61\n *\n * @name Schema.validationKeywords.required\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `required` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n required (value, schema, opts) {\n opts || (opts = {})\n const required = schema.required\n let errors = []\n if (!opts.existingOnly) {\n required.forEach(function (prop) {\n if (utils.get(value, prop) === undefined) {\n const prevProp = opts.prop\n opts.prop = prop\n addError(undefined, 'a value', opts, errors)\n opts.prop = prevProp\n }\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor79\n *\n * @name Schema.validationKeywords.type\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `type` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n type (value, schema, opts) {\n let type = schema.type\n let validType\n // Can be one of several types\n if (utils.isString(type)) {\n type = [type]\n }\n // Try to match the value against an expected type\n type.forEach(function (_type) {\n // TODO: throw an error if type is not defined\n if (types[_type](value, schema, opts)) {\n // Matched a type\n validType = _type\n return false\n }\n })\n // Value did not match any expected type\n if (!validType) {\n return makeError(value !== undefined && value !== null ? typeof value : '' + value, `one of (${type.join(', ')})`, opts)\n }\n // Run keyword validators for matched type\n // http://json-schema.org/latest/json-schema-validation.html#anchor12\n const validator = typeGroupValidators[validType]\n if (validator) {\n return validator(value, schema, opts)\n }\n },\n\n /**\n * Validates the provided array values are unique.\n * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true\n * see http://json-schema.org/latest/json-schema-validation.html#anchor49\n *\n * @name Schema.validationKeywords.uniqueItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `uniqueItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n uniqueItems (value, schema, opts) {\n if (value && value.length && schema.uniqueItems) {\n const length = value.length\n let item, i, j\n // Check n - 1 items\n for (i = length - 1; i > 0; i--) {\n item = value[i]\n // Only compare against unchecked items\n for (j = i - 1; j >= 0; j--) {\n // Found a duplicate\n if (utils.deepEqual(item, value[j])) {\n return makeError(item, 'no duplicates', opts)\n }\n }\n }\n }\n }\n}\n\n/**\n * @ignore\n */\nconst validateKeyword = function (op, value, schema, opts) {\n return schema[op] !== undefined && validationKeywords[op](value, schema, opts)\n}\n\n/**\n * @ignore\n */\nconst runOps = function (ops, value, schema, opts) {\n let errors = []\n ops.forEach(function (op) {\n errors = errors.concat(validateKeyword(op, value, schema, opts) || [])\n })\n return errors.length ? errors : undefined\n}\n\nconst ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']\nconst ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']\nconst NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']\nconst OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\nconst STRING_OPS = ['maxLength', 'minLength', 'pattern']\n\n/**\n * http://json-schema.org/latest/json-schema-validation.html#anchor75\n * @ignore\n */\nconst validateAny = function (value, schema, opts) {\n return runOps(ANY_OPS, value, schema, opts)\n}\n\n/**\n * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification.\n *\n * @name Schema.validate\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\nconst validate = function (value, schema, opts) {\n let errors = []\n opts || (opts = {})\n opts.ctx || (opts.ctx = { value, schema })\n let shouldPop\n let prevProp = opts.prop\n if (schema === undefined) {\n return\n }\n if (!utils.isObject(schema)) {\n throw utils.err(`${DOMAIN}#validate`)(500, `Invalid schema at path: \"${opts.path}\"`)\n }\n if (opts.path === undefined) {\n opts.path = []\n }\n // Track our location as we recurse\n if (opts.prop !== undefined) {\n shouldPop = true\n opts.path.push(opts.prop)\n opts.prop = undefined\n }\n // Validate against parent schema\n if (schema['extends']) {\n // opts.path = path\n // opts.prop = prop\n if (utils.isFunction(schema['extends'].validate)) {\n errors = errors.concat(schema['extends'].validate(value, opts) || [])\n } else {\n errors = errors.concat(validate(value, schema['extends'], opts) || [])\n }\n }\n if (value === undefined) {\n // Check if property is required\n if (schema.required === true && !opts.existingOnly) {\n addError(value, 'a value', opts, errors)\n }\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n }\n\n errors = errors.concat(validateAny(value, schema, opts) || [])\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n}\n\n// These strings are cached for optimal performance of the change detection\n// boolean - Whether a Record is changing in the current execution frame\nconst changingPath = 'changing'\n// string[] - Properties that have changed in the current execution frame\nconst changedPath = 'changed'\n// Object[] - History of change records\nconst changeHistoryPath = 'history'\n// boolean - Whether a Record is currently being instantiated\nconst creatingPath = 'creating'\n// number - The setTimeout change event id of a Record, if any\nconst eventIdPath = 'eventId'\n// boolean - Whether to skip validation for a Record's currently changing property\nconst noValidatePath = 'noValidate'\n// boolean - Whether to skip change notification for a Record's currently\n// changing property\nconst silentPath = 'silent'\nconst validationFailureMsg = 'validation failed'\n\n/**\n * Assemble a property descriptor which will be added to the prototype of\n * {@link Mapper#recordClass}. This method is called when\n * {@link Mapper#applySchema} is set to `true`.\n *\n * @ignore\n */\nconst makeDescriptor = function (prop, schema, opts) {\n const descriptor = {\n // Better to allow configurability, but at the user's own risk\n configurable: true,\n // These properties are enumerable by default, but regardless of their\n // enumerability, they won't be \"own\" properties of individual records\n enumerable: schema.enumerable === undefined ? true : !!schema.enumerable\n }\n // Cache a few strings for optimal performance\n const keyPath = `props.${prop}`\n const previousPath = `previous.${prop}`\n const getter = opts.getter\n const setter = opts.setter\n const unsetter = opts.unsetter\n const track = utils.isBoolean(opts.track) ? opts.track : schema.track\n\n descriptor.get = function () {\n return this._get(keyPath)\n }\n\n if (utils.isFunction(schema.get)) {\n const originalGet = descriptor.get\n descriptor.get = function () {\n return schema.get.call(this, originalGet)\n }\n }\n\n descriptor.set = function (value) {\n // These are accessed a lot\n const _get = this[getter]\n const _set = this[setter]\n const _unset = this[unsetter]\n\n // Optionally check that the new value passes validation\n if (!_get(noValidatePath)) {\n const errors = schema.validate(value, { path: [prop] })\n if (errors) {\n // Immediately throw an error, preventing the record from getting into\n // an invalid state\n const error = new Error(validationFailureMsg)\n error.errors = errors\n throw error\n }\n }\n // TODO: Make it so tracking can be turned on for all properties instead of\n // only per-property\n if (track && !_get(creatingPath)) {\n const previous = _get(previousPath)\n const current = _get(keyPath)\n let changing = _get(changingPath)\n let changed = _get(changedPath)\n\n if (!changing) {\n // Track properties that are changing in the current event loop\n changed = []\n }\n\n // Add changing properties to this array once at most\n const index = changed.indexOf(prop)\n if (current !== value && index === -1) {\n changed.push(prop)\n }\n if (previous === value) {\n if (index >= 0) {\n changed.splice(index, 1)\n }\n }\n // No changes in current event loop\n if (!changed.length) {\n changing = false\n _unset(changingPath)\n _unset(changedPath)\n // Cancel pending change event\n if (_get(eventIdPath)) {\n clearTimeout(_get(eventIdPath))\n _unset(eventIdPath)\n }\n }\n // Changes detected in current event loop\n if (!changing && changed.length) {\n _set(changedPath, changed)\n _set(changingPath, true)\n // Saving the timeout id allows us to batch all changes in the same\n // event loop into a single \"change\"\n // TODO: Optimize\n _set(eventIdPath, setTimeout(() => {\n // Previous event loop where changes were gathered has ended, so\n // notify any listeners of those changes and prepare for any new\n // changes\n _unset(changedPath)\n _unset(eventIdPath)\n _unset(changingPath)\n // TODO: Optimize\n if (!_get(silentPath)) {\n let i\n for (i = 0; i < changed.length; i++) {\n this.emit('change:' + changed[i], this, utils.get(this, changed[i]))\n }\n const changes = this.changes()\n const changeRecord = utils.plainCopy(changes)\n changeRecord.timestamp = new Date().getTime()\n const changeHistory = _get(changeHistoryPath) || []\n _set(changeHistoryPath, changeHistory)\n changeHistory.push(changeRecord)\n this.emit('change', this, changes)\n }\n _unset(silentPath)\n }, 0))\n }\n }\n _set(keyPath, value)\n return value\n }\n\n if (utils.isFunction(schema.set)) {\n const originalSet = descriptor.set\n descriptor.set = function (value) {\n return schema.set.call(this, value, originalSet)\n }\n }\n\n return descriptor\n}\n\n/**\n * A map of validation functions grouped by type.\n *\n * @name Schema.typeGroupValidators\n * @type {Object}\n */\nconst typeGroupValidators = {\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an array.\n * The validation keywords for the type `array` are:\n *```\n * ['items', 'maxItems', 'minItems', 'uniqueItems']\n *```\n * see http://json-schema.org/latest/json-schema-validation.html#anchor25\n *\n * @name Schema.typeGroupValidators.array\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing at least one array keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n array: function (value, schema, opts) {\n return runOps(ARRAY_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer.\n * The validation keywords for the type `integer` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.integer\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `integer` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n integer: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an number.\n * The validation keywords for the type `number` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.number\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `number` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n number: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer.\n * The validation keywords for the type `numeric` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor13.\n *\n * @name Schema.typeGroupValidators.numeric\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `numeric` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n numeric: function (value, schema, opts) {\n return runOps(NUMERIC_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an object.\n * The validation keywords for the type `object` are:\n *```\n * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor53.\n *\n * @name Schema.typeGroupValidators.object\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing at least one `object` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n object: function (value, schema, opts) {\n return runOps(OBJECT_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an string.\n * The validation keywords for the type `string` are:\n *```\n * ['maxLength', 'minLength', 'pattern']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor25.\n *\n * @name Schema.typeGroupValidators.string\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing at least one `string` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n string: function (value, schema, opts) {\n return runOps(STRING_OPS, value, schema, opts)\n }\n}\n\n/**\n * js-data's Schema class.\n *\n * @example Schema#constructor\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const PostSchema = new Schema({\n * type: 'object',\n * properties: {\n * title: { type: 'string' }\n * }\n * })\n * PostSchema.validate({ title: 1234 })\n *\n * @class Schema\n * @extends Component\n * @param {Object} definition Schema definition according to json-schema.org\n */\nfunction Schema (definition) {\n definition || (definition = {})\n // TODO: schema validation\n utils.fillIn(this, definition)\n\n if (this.type === 'object' && this.properties) {\n utils.forOwn(this.properties, (_definition, prop) => {\n if (!(_definition instanceof Schema)) {\n this.properties[prop] = new Schema(_definition)\n }\n })\n }\n if (this.type === 'array' && this.items && !(this.items instanceof Schema)) {\n this.items = new Schema(this.items)\n }\n ['allOf', 'anyOf', 'oneOf'].forEach((validationKeyword) => {\n if (this[validationKeyword]) {\n this[validationKeyword].forEach((_definition, i) => {\n if (!(_definition instanceof Schema)) {\n this[validationKeyword][i] = new Schema(_definition)\n }\n })\n }\n })\n}\n\nexport default Component.extend({\n constructor: Schema,\n\n /**\n * This adds ES5 getters/setters to the target based on the \"properties\" in\n * this Schema, which makes possible change tracking and validation on\n * property assignment.\n *\n * @name Schema#validate\n * @method\n * @param {Object} target The prototype to which to apply this schema.\n */\n apply (target, opts) {\n opts || (opts = {})\n opts.getter || (opts.getter = '_get')\n opts.setter || (opts.setter = '_set')\n opts.unsetter || (opts.unsetter = '_unset')\n opts.track || (opts.track = this.track)\n const properties = this.properties || {}\n utils.forOwn(properties, function (schema, prop) {\n Object.defineProperty(\n target,\n prop,\n makeDescriptor(prop, schema, opts)\n )\n })\n },\n\n /**\n * Apply default values to the target object for missing values.\n *\n * @name Schema#applyDefaults\n * @method\n * @param {Object} target The target to which to apply values for missing values.\n */\n applyDefaults (target) {\n if (!target) {\n return\n }\n const properties = this.properties || {}\n const hasSet = utils.isFunction(target.set) || utils.isFunction(target._set)\n utils.forOwn(properties, function (schema, prop) {\n if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) {\n if (hasSet) {\n target.set(prop, utils.plainCopy(schema['default']), { silent: true })\n } else {\n utils.set(target, prop, utils.plainCopy(schema['default']))\n }\n }\n if (schema.type === 'object' && schema.properties) {\n if (hasSet) {\n const orig = target._get('noValidate')\n target._set('noValidate', true)\n utils.set(target, prop, utils.get(target, prop) || {}, { silent: true })\n target._set('noValidate', orig)\n } else {\n utils.set(target, prop, utils.get(target, prop) || {})\n }\n schema.applyDefaults(utils.get(target, prop))\n }\n })\n },\n\n /**\n * Validate the provided value against this schema.\n *\n * @name Schema#validate\n * @method\n * @param {*} value Value to validate.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n validate (value, opts) {\n return validate(value, this, opts)\n }\n}, {\n ANY_OPS,\n ARRAY_OPS,\n NUMERIC_OPS,\n OBJECT_OPS,\n STRING_OPS,\n typeGroupValidators,\n types,\n validate,\n validationKeywords\n})\n\n/**\n * Create a subclass of this Schema:\n * @example Schema.extend\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSchemaClass extends Schema {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSchema = new CustomSchemaClass()\n * console.log(customSchema.foo())\n * console.log(CustomSchemaClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSchemaClass = Schema.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSchema = new OtherSchemaClass()\n * console.log(otherSchema.foo())\n * console.log(OtherSchemaClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSchemaClass () {\n * Schema.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Schema.extend({\n * constructor: AnotherSchemaClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSchema = new AnotherSchemaClass()\n * console.log(anotherSchema.created_at)\n * console.log(anotherSchema.foo())\n * console.log(AnotherSchemaClass.beep())\n *\n * @method Schema.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Schema class.\n * @since 3.0.0\n */\n\n","import utils from './utils'\nimport Component from './Component'\nimport Record from './Record'\nimport Schema from './Schema'\nimport { Relation } from './relations'\nimport {\n belongsTo,\n belongsToType,\n hasMany,\n hasManyType,\n hasOne,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Mapper'\nconst applyDefaultsHooks = [\n 'beforeCreate',\n 'beforeCreateMany'\n]\nconst validatingHooks = [\n 'beforeCreate',\n 'beforeCreateMany',\n 'beforeUpdate',\n 'beforeUpdateAll',\n 'beforeUpdateMany'\n]\nconst makeNotify = function (num) {\n return function (...args) {\n const opts = args[args.length - num]\n const op = opts.op\n this.dbg(op, ...args)\n\n if (applyDefaultsHooks.indexOf(op) !== -1 && opts.applyDefaults !== false) {\n const schema = this.getSchema()\n if (schema && schema.applyDefaults) {\n let toProcess = args[0]\n if (!utils.isArray(toProcess)) {\n toProcess = [toProcess]\n }\n toProcess.forEach((record) => {\n schema.applyDefaults(record)\n })\n }\n }\n\n // Automatic validation\n if (validatingHooks.indexOf(op) !== -1 && !opts.noValidate) {\n // Save current value of option\n const originalExistingOnly = opts.existingOnly\n\n // For updates, ignore required fields if they aren't present\n if (op.indexOf('beforeUpdate') === 0 && opts.existingOnly === undefined) {\n opts.existingOnly = true\n }\n const errors = this.validate(args[op === 'beforeUpdate' ? 1 : 0], utils.pick(opts, ['existingOnly']))\n\n // Restore option\n opts.existingOnly = originalExistingOnly\n\n // Abort lifecycle due to validation errors\n if (errors) {\n return utils.reject(errors)\n }\n }\n\n // Emit lifecycle event\n if (opts.notify || (opts.notify === undefined && this.notify)) {\n setTimeout(() => {\n this.emit(op, ...args)\n })\n }\n }\n}\n\n// These are the default implementations of all of the lifecycle hooks\nconst notify = makeNotify(1)\nconst notify2 = makeNotify(2)\n\n// This object provides meta information used by Mapper#crud to actually\n// execute each lifecycle method\nconst LIFECYCLE_METHODS = {\n count: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroy: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroyAll: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n find: {\n defaults: [undefined, {}],\n types: []\n },\n findAll: {\n defaults: [{}, {}],\n types: []\n },\n sum: {\n defaults: [undefined, {}, {}],\n skip: true,\n types: []\n },\n update: {\n adapterArgs (mapper, id, props, opts) {\n return [id, mapper.toJSON(props, opts), opts]\n },\n beforeAssign: 1,\n defaults: [undefined, {}, {}],\n types: []\n },\n updateAll: {\n adapterArgs (mapper, props, query, opts) {\n return [mapper.toJSON(props, opts), query, opts]\n },\n beforeAssign: 0,\n defaults: [{}, {}, {}],\n types: []\n },\n updateMany: {\n adapterArgs (mapper, records, opts) {\n return [records.map(function (record) {\n return mapper.toJSON(record, opts)\n }), opts]\n },\n beforeAssign: 0,\n defaults: [[], {}],\n types: []\n }\n}\n\nconst MAPPER_DEFAULTS = {\n /**\n * Hash of registered adapters. Don't modify directly. Use\n * {@link Mapper#registerAdapter} instead.\n *\n * @default {}\n * @name Mapper#_adapters\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n _adapters: {},\n\n /**\n * Whether {@link Mapper#beforeCreate} and {@link Mapper#beforeCreateMany}\n * should automatically receive default values according to the Mapper's schema.\n *\n * @default true\n * @name Mapper#applyDefaults\n * @since 3.0.0\n * @type {boolean}\n */\n applyDefaults: true,\n\n /**\n * Whether to augment {@link Mapper#recordClass} with ES5 getters and setters\n * according to the properties defined in {@link Mapper#schema}. This makes\n * possible validation and change tracking on individual properties\n * when using the dot (e.g. `user.name = \"Bob\"`) operator to modify a\n * property, and is `true` by default.\n *\n * @default true\n * @name Mapper#applySchema\n * @since 3.0.0\n * @type {boolean}\n */\n applySchema: true,\n\n /**\n * The name of the registered adapter that this Mapper should used by default.\n *\n * @default \"http\"\n * @name Mapper#defaultAdapter\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n * @type {string}\n */\n defaultAdapter: 'http',\n\n /**\n * The field used as the unique identifier on records handled by this Mapper.\n *\n * @default id\n * @name Mapper#idAttribute\n * @since 3.0.0\n * @type {string}\n */\n idAttribute: 'id',\n\n /**\n * Whether this Mapper should emit operational events.\n *\n * @default true\n * @name Mapper#notify\n * @since 3.0.0\n * @type {boolean}\n */\n notify: true,\n\n /**\n * Whether to skip validation when the Record instances are created.\n *\n * @default false\n * @name Mapper#noValidate\n * @since 3.0.0\n * @type {boolean}\n */\n noValidate: false,\n\n /**\n * Whether {@link Mapper#create}, {@link Mapper#createMany},\n * {@link Mapper#update}, {@link Mapper#updateAll}, {@link Mapper#updateMany},\n * {@link Mapper#find}, {@link Mapper#findAll}, {@link Mapper#destroy},\n * {@link Mapper#destroyAll}, {@link Mapper#count}, and {@link Mapper#sum}\n * should return a raw result object that contains both the instance data\n * returned by the adapter _and_ metadata about the operation.\n *\n * The default is to NOT return the result object, and instead return just the\n * instance data.\n *\n * @default false\n * @name Mapper#raw\n * @since 3.0.0\n * @type {boolean}\n */\n raw: false\n}\n\n/**\n * The core of JSData's [ORM/ODM][orm] implementation. Given a minimum amout of\n * meta information about a resource, a Mapper can perform generic CRUD\n * operations against that resource. Apart from its configuration, a Mapper is\n * stateless. The particulars of various persistence layers have been abstracted\n * into adapters, which a Mapper uses to perform its operations.\n *\n * The term \"Mapper\" comes from the [Data Mapper Pattern][pattern] described in\n * Martin Fowler's [Patterns of Enterprise Application Architecture][book]. A\n * Data Mapper moves data between [in-memory object instances][record] and a\n * relational or document-based database. JSData's Mapper can work with any\n * persistence layer you can write an adapter for.\n *\n * _(\"Model\" is a heavily overloaded term and is avoided in this documentation\n * to prevent confusion.)_\n *\n * [orm]: https://en.wikipedia.org/wiki/Object-relational_mapping\n * [pattern]: https://en.wikipedia.org/wiki/Data_mapper_pattern\n * [book]: http://martinfowler.com/books/eaa.html\n * [record]: Record.html\n *\n * @example\n * // Import and instantiate\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @example\n * // Define a Mapper using the Container component\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @class Mapper\n * @extends Component\n * @param {Object} opts Configuration options.\n * @param {boolean} [opts.applySchema=true] See {@link Mapper#applySchema}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {string} [opts.defaultAdapter=http] See {@link Mapper#defaultAdapter}.\n * @param {string} [opts.idAttribute=id] See {@link Mapper#idAttribute}.\n * @param {Object} [opts.methods] See {@link Mapper#methods}.\n * @param {string} opts.name See {@link Mapper#name}.\n * @param {boolean} [opts.notify] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw=false] See {@link Mapper#raw}.\n * @param {Function|boolean} [opts.recordClass] See {@link Mapper#recordClass}.\n * @param {Object|Schema} [opts.schema] See {@link Mapper#schema}.\n * @returns {Mapper} A new {@link Mapper} instance.\n * @see http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n */\nfunction Mapper (opts) {\n utils.classCallCheck(this, Mapper)\n Component.call(this)\n opts || (opts = {})\n\n // Prepare certain properties to be non-enumerable\n Object.defineProperties(this, {\n _adapters: {\n value: undefined,\n writable: true\n },\n\n /**\n * The {@link Container} that holds this Mapper. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n datastore: {\n value: undefined,\n writable: true\n },\n\n /**\n * The meta information describing this Mapper's available lifecycle\n * methods. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n lifecycleMethods: {\n value: LIFECYCLE_METHODS\n },\n\n /**\n * Set to `false` to force the Mapper to work with POJO objects only.\n *\n * @example\n * // Use POJOs only.\n * import {Mapper, Record} from 'js-data'\n * const UserMapper = new Mapper({ recordClass: false })\n * UserMapper.recordClass // false\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n *\n * @example\n * // Set to a custom class to have records wrapped in your custom class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User {\n * constructor (props = {}) {\n * for (var key in props) {\n * if (props.hasOwnProperty(key)) {\n * this[key] = props[key]\n * }\n * }\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n * user instanceof User // true\n *\n *\n * @example\n * // Extend the {@link Record} class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User extends Record {\n * constructor () {\n * super(props)\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // true\n * user instanceof User // true\n *\n * @name Mapper#recordClass\n * @default {@link Record}\n * @see Record\n * @since 3.0.0\n */\n recordClass: {\n value: undefined,\n writable: true\n },\n\n /**\n * This Mapper's {@link Schema}.\n *\n * @example Mapper#schema\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const UserMapper = new Mapper({\n * name: 'user',\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * first: { type: 'string', track: true },\n * last: { type: 'string', track: true },\n * role: { type: 'string', track: true, required: true },\n * age: { type: 'integer', track: true },\n * is_active: { type: 'number' }\n * }\n * }\n * })\n * const user = UserMapper.createRecord({\n * id: 1,\n * name: 'John',\n * role: 'admin'\n * })\n * user.on('change', function (user, changes) {\n * console.log(changes)\n * })\n * user.on('change:role', function (user, value) {\n * console.log('change:role - ' + value)\n * })\n * user.role = 'owner'\n *\n * @name Mapper#schema\n * @see Schema\n * @since 3.0.0\n * @type {Schema}\n */\n schema: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(MAPPER_DEFAULTS))\n\n /**\n * The name for this Mapper. This is the minimum amount of meta information\n * required for a Mapper to be able to execute CRUD operations for a\n * Resource.\n *\n * @name Mapper#name\n * @since 3.0.0\n * @type {string}\n */\n if (!this.name) {\n throw utils.err(`new ${DOMAIN}`, 'opts.name')(400, 'string', this.name)\n }\n\n // Setup schema, with an empty default schema if necessary\n if (this.schema) {\n this.schema.type || (this.schema.type = 'object')\n }\n if (!(this.schema instanceof Schema)) {\n this.schema = new Schema(this.schema || { type: 'object' })\n }\n\n // Create a subclass of Record that's tied to this Mapper\n if (this.recordClass === undefined) {\n const superClass = Record\n this.recordClass = superClass.extend({\n constructor: (function Record () {\n var subClass = function Record (props, opts) {\n utils.classCallCheck(this, subClass)\n superClass.call(this, props, opts)\n }\n return subClass\n })()\n })\n }\n\n if (this.recordClass) {\n this.recordClass.mapper = this\n\n /**\n * Functions that should be added to the prototype of {@link Mapper#recordClass}.\n *\n * @name Mapper#methods\n * @since 3.0.0\n * @type {Object}\n */\n if (utils.isObject(this.methods)) {\n utils.addHiddenPropsToTarget(this.recordClass.prototype, this.methods)\n }\n\n // We can only apply the schema to the prototype of this.recordClass if the\n // class extends Record\n if (Record.prototype.isPrototypeOf(Object.create(this.recordClass.prototype)) && this.schema && this.schema.apply && this.applySchema) {\n this.schema.apply(this.recordClass.prototype)\n }\n }\n}\n\nexport default Component.extend({\n constructor: Mapper,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCount: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroy: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroyAll\n * @param {*} data The `data` returned by the adapter.\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroyAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFind: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFindAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterSum\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterSum: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @since 3.0.0\n */\n beforeCreate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @since 3.0.0\n */\n beforeCreateMany: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @since 3.0.0\n */\n beforeCount: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @since 3.0.0\n */\n beforeDestroy: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroyAll\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @since 3.0.0\n */\n beforeDestroyAll: notify,\n\n /**\n * Mappers lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @since 3.0.0\n */\n beforeFind: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @since 3.0.0\n */\n beforeFindAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeSum\n * @param {string} field The `field` argument passed to {@link Mapper#sum}.\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @since 3.0.0\n */\n beforeSum: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @since 3.0.0\n */\n beforeUpdate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @since 3.0.0\n */\n beforeUpdateAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @since 3.0.0\n */\n beforeUpdateMany: notify,\n\n /**\n * This method is called at the end of most lifecycle methods. It does the\n * following:\n *\n * 1. If `opts.raw` is `true`, add this Mapper's configuration to the `opts`\n * argument as metadata for the operation.\n * 2. Wrap the result data appropriately using {@link Mapper#wrap}, which\n * calls {@link Mapper#createRecord}.\n *\n * @method Mapper#_end\n * @private\n * @since 3.0.0\n */\n _end (result, opts, skip) {\n if (opts.raw) {\n utils._(result, opts)\n }\n if (skip) {\n return result\n }\n let _data = opts.raw ? result.data : result\n if (_data && utils.isFunction(this.wrap)) {\n _data = this.wrap(_data, opts)\n if (opts.raw) {\n result.data = _data\n } else {\n result = _data\n }\n }\n return result\n },\n\n /**\n * Define a belongsTo relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * PostMapper.belongsTo(UserMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to post records at \"post.user\"\n * localField: 'user'\n * })\n *\n * CommentMapper.belongsTo(UserMapper, {\n * // comment.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to comment records at \"comment.user\"\n * localField: 'user'\n * })\n * CommentMapper.belongsTo(PostMapper, {\n * // comment.post_id points to post.id\n * foreignKey: 'post_id'\n * // post records will be attached to comment records at \"comment.post\"\n * localField: 'post'\n * })\n *\n * @method Mapper#belongsTo\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n belongsTo (relatedMapper, opts) {\n return belongsTo(relatedMapper, opts)(this)\n },\n\n /**\n * Select records according to the `query` argument and return the count.\n *\n * {@link Mapper#beforeCount} will be called before calling the adapter.\n * {@link Mapper#afterCount} will be called after calling the adapter.\n *\n * @example\n * // Get the number of published blog posts\n * PostMapper.count({ status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Mapper#count\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `count` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the count of the selected records.\n * @since 3.0.0\n */\n count (query, opts) {\n return this.crud('count', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~beforeCreateListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreate\n * @see Mapper~beforeCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Mapper~beforeCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeCreate}.\n * @see Mapper#event:beforeCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~afterCreateListener} for how to listen for this event.\n *\n * @event Mapper#afterCreate\n * @see Mapper~afterCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Mapper~afterCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterCreate}.\n * @see Mapper#event:afterCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Create and save a new the record using the provided `props`.\n *\n * {@link Mapper#beforeCreate} will be called before calling the adapter.\n * {@link Mapper#afterCreate} will be called after calling the adapter.\n *\n * @example\n * // Create and save a new blog post\n * PostMapper.create({\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#create\n * @param {Object} props The properties for the new record.\n * @param {Object} [opts] Configuration options. Refer to the `create` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `props` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#create}\n * or {@link Mapper#createMany} call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created record.\n * @since 3.0.0\n */\n create (props, opts) {\n let op, adapter\n // Default values for arguments\n props || (props = {})\n opts || (opts = {})\n const originalRecord = props\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreate lifecycle hook\n op = opts.op = 'beforeCreate'\n return utils.resolve(this[op](props, opts)).then((_props) => {\n // Allow for re-assignment from lifecycle hook\n props = _props === undefined ? props : _props\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n const relatedMapper = def.getRelation()\n const relatedIdAttribute = relatedMapper.idAttribute\n optsCopy.raw = false\n if (!relationData) {\n return\n }\n if (def.type === belongsToType) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(relatedMapper.create(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n def.setForeignKey(props, data)\n }))\n } else if (def.type === hasManyType && def.localKeys) {\n // Create his hasMany relation first because it uses localKeys\n tasks.push(relatedMapper.createMany(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n utils.set(props, def.localKeys, data.map((record) => utils.get(record, relatedIdAttribute)))\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter for the main create\n op = opts.op = 'create'\n this.dbg(op, props, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, this.toJSON(props, { with: opts.pass || [] }), opts))\n }).then((result) => {\n const createdRecordData = opts.raw ? result.data : result\n\n // Deep post-create hasMany and hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n if (!relationData) {\n return\n }\n optsCopy.raw = false\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType && def.foreignKey) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === hasOneType) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().create(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === belongsToType && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n } else if (def.type === hasManyType && def.localKeys && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n if (opts.raw) {\n result.data = originalRecord\n } else {\n result = originalRecord\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreate lifecycle hook\n op = opts.op = 'afterCreate'\n return utils.resolve(this[op](props, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Use {@link Mapper#createRecord} instead.\n * @deprecated\n * @method Mapper#createInstance\n * @param {Object|Array} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Object|Array} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n createInstance (props, opts) {\n return this.createRecord(props, opts)\n },\n\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreateMany\n * @see Mapper~beforeCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Mapper~beforeCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Mapper#event:beforeCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~afterCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterCreateMany\n * @see Mapper~afterCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Mapper~afterCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Mapper#event:afterCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Given an array of records, batch create them via an adapter.\n *\n * {@link Mapper#beforeCreateMany} will be called before calling the adapter.\n * {@link Mapper#afterCreateMany} will be called after calling the adapter.\n *\n * @example\n * // Create and save several new blog posts\n * PostMapper.createMany([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#createMany\n * @param {Record[]} records Array of records to be created in one batch.\n * @param {Object} [opts] Configuration options. Refer to the `createMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `records` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#createMany}\n * call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created records.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n createMany (records, opts) {\n let op, adapter\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n const originalRecords = records\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreateMany lifecycle hook\n op = opts.op = 'beforeCreateMany'\n return utils.resolve(this[op](records, opts)).then((_records) => {\n // Allow for re-assignment from lifecycle hook\n records = _records === undefined ? records : _records\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (def.type === belongsToType && relationData.length === records.length) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(def.getRelation().createMany(relationData, optsCopy).then((data) => {\n const relatedRecords = optsCopy.raw ? data.data : data\n def.setLocalField(belongsToRelationData, relatedRecords)\n records.forEach((record, i) => {\n def.setForeignKey(record, relatedRecords[i])\n })\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'createMany'\n const json = records.map((record) => this.toJSON(record, { with: opts.pass || [] }))\n this.dbg(op, records, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, json, opts))\n }).then((result) => {\n const createdRecordsData = opts.raw ? result.data : result\n\n // Deep post-create hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (relationData.length !== records.length) {\n return\n }\n const belongsToData = def.getLocalField(belongsToRelationData)\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType) {\n // Not supported\n this.log('warn', 'deep createMany of hasMany type not supported!')\n } else if (def.type === hasOneType) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setForeignKey(createdRecordData, relationData[i])\n })\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n const relatedData = opts.raw ? result.data : result\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, relatedData[i])\n })\n })\n } else if (def.type === belongsToType && belongsToData && belongsToData.length === createdRecordsData.length) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, belongsToData[i])\n })\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n createdRecordsData.forEach((createdRecordData, i) => {\n const originalRecord = originalRecords[i]\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n })\n if (opts.raw) {\n result.data = originalRecords\n } else {\n result = originalRecords\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreateMany lifecycle hook\n op = opts.op = 'afterCreateMany'\n return utils.resolve(this[op](records, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Create an unsaved, uncached instance of this Mapper's\n * {@link Mapper#recordClass}.\n *\n * Returns `props` if `props` is already an instance of\n * {@link Mapper#recordClass}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * const post = PostMapper.createRecord()\n *\n * @example\n * // Create an unsaved record instance with inital properties\n * const post = PostMapper.createRecord({\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create a record instance that corresponds to a saved record\n * const post = PostMapper.createRecord({\n * // JSData thinks this record has been saved if it has a primary key\n * id: 1234,\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create record instances from an array\n * const posts = PostMapper.createRecord([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }])\n *\n * @example\n * // Records are validated by default\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * try {\n * const post = PostMapper.createRecord({\n * title: 1234,\n * })\n * } catch (err) {\n * console.log(err.errors) // [{ expected: 'one of (string)', actual: 'number', path: 'title' }]\n * }\n *\n * @example\n * // Skip validation\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * const post = PostMapper.createRecord({\n * title: 1234,\n * }, { noValidate: true })\n * console.log(post.isValid()) // false\n *\n * @method Mapper#createRecord\n * @param {Object|Object[]} props The properties for the Record instance or an\n * array of property objects for the Record instances.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @returns {Record|Record[]} The Record instance or Record instances.\n * @since 3.0.0\n */\n createRecord (props, opts) {\n props || (props = {})\n if (utils.isArray(props)) {\n return props.map((_props) => this.createRecord(_props, opts))\n }\n if (!utils.isObject(props)) {\n throw utils.err(`${DOMAIN}#createRecord`, 'props')(400, 'array or object', props)\n }\n const RecordCtor = this.recordClass\n const relationList = this.relationList || []\n relationList.forEach(function (def) {\n const relatedMapper = def.getRelation()\n const relationData = def.getLocalField(props)\n if (relationData && !relatedMapper.is(relationData)) {\n if (utils.isArray(relationData) && (!relationData.length || relatedMapper.is(relationData[0]))) {\n return\n }\n utils.set(props, def.localField, relatedMapper.createRecord(relationData, opts))\n }\n })\n // Check to make sure \"props\" is not already an instance of this Mapper.\n if (RecordCtor && (!(props instanceof RecordCtor))) {\n return new RecordCtor(props, opts)\n }\n return props\n },\n\n /**\n * Lifecycle invocation method. You probably won't call this method directly.\n *\n * @method Mapper#crud\n * @param {string} method Name of the lifecycle method to invoke.\n * @param {...*} args Arguments to pass to the lifecycle method.\n * @returns {Promise}\n * @since 3.0.0\n */\n crud (method, ...args) {\n const config = this.lifecycleMethods[method]\n if (!config) {\n throw utils.err(`${DOMAIN}#crud`, method)(404, 'method')\n }\n\n const upper = `${method.charAt(0).toUpperCase()}${method.substr(1)}`\n const before = `before${upper}`\n const after = `after${upper}`\n\n let op, adapter\n\n // Default values for arguments\n config.defaults.forEach((value, i) => {\n if (args[i] === undefined) {\n args[i] = utils.copy(value)\n }\n })\n\n const opts = args[args.length - 1]\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // before lifecycle hook\n op = opts.op = before\n return utils.resolve(this[op](...args)).then((_value) => {\n if (args[config.beforeAssign] !== undefined) {\n // Allow for re-assignment from lifecycle hook\n args[config.beforeAssign] = _value === undefined ? args[config.beforeAssign] : _value\n }\n // Now delegate to the adapter\n op = opts.op = method\n args = config.adapterArgs ? config.adapterArgs(this, ...args) : args\n this.dbg(op, ...args)\n return utils.resolve(this.getAdapter(adapter)[op](this, ...args))\n }).then((result) => {\n result = this._end(result, opts, !!config.skip)\n args.push(result)\n // after lifecycle hook\n op = opts.op = after\n return utils.resolve(this[op](...args)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~beforeDestroyListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroy\n * @see Mapper~beforeDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Mapper~beforeDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroy}.\n * @see Mapper#event:beforeDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~afterDestroyListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroy\n * @see Mapper~afterDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Mapper~afterDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroy}.\n * @see Mapper#event:afterDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Using an adapter, destroy the record with the given primary key.\n *\n * {@link Mapper#beforeDestroy} will be called before destroying the record.\n * {@link Mapper#afterDestroy} will be called after destroying the record.\n *\n * @example\n * // Destroy a specific blog post\n * PostMapper.destroy(1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @example\n * // Get full response\n * PostMapper.destroy(1234, { raw: true }).then((result) => {\n * console.log(result.deleted) e.g. 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroy\n * @fires Mapper#afterDestroy\n * @method Mapper#destroy\n * @param {(string|number)} id The primary key of the record to destroy.\n * @param {Object} [opts] Configuration options. Refer to the `destroy` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the record has been destroyed. Resolves\n * even if no record was found to be destroyed.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroy (id, opts) {\n return this.crud('destroy', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroyAll\n * @see Mapper~beforeDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Mapper~beforeDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroyAll}.\n * @see Mapper#event:beforeDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroyAll\n * @see Mapper~afterDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Mapper~afterDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroyAll}.\n * @see Mapper#event:afterDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Destroy the records selected by `query` via an adapter. If no `query` is\n * provided then all records will be destroyed.\n *\n * {@link Mapper#beforeDestroyAll} will be called before destroying the records.\n * {@link Mapper#afterDestroyAll} will be called after destroying the records.\n *\n * @example\n * // Destroy all blog posts\n * PostMapper.destroyAll().then(() => {\n * // All blog posts have been destroyed\n * })\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * PostMapper.destroyAll({ status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @example\n * // Get full response\n * const query = null\n * const options = { raw: true }\n * PostMapper.destroyAll(query, options).then((result) => {\n * console.log(result.deleted) e.g. 14\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroyAll\n * @fires Mapper#afterDestroyAll\n * @method Mapper#destroyAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `destroyAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the records have been destroyed. Resolves\n * even if no records were found to be destroyed.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroyAll (query, opts) {\n return this.crud('destroyAll', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~beforeFindListener} for how to listen for this event.\n *\n * @event Mapper#beforeFind\n * @see Mapper~beforeFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Mapper~beforeFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFind}.\n * @see Mapper#event:beforeFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~afterFindListener} for how to listen for this event.\n *\n * @event Mapper#afterFind\n * @see Mapper~afterFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFind} event.\n *\n * @example\n * function onAfterFind (id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Mapper~afterFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFind}.\n * @see Mapper#event:afterFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Retrieve via an adapter the record with the given primary key.\n *\n * {@link Mapper#beforeFind} will be called before calling the adapter.\n * {@link Mapper#afterFind} will be called after calling the adapter.\n *\n * @example\n * PostMapper.find(1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @example\n * // Get full response\n * PostMapper.find(1, { raw: true }).then((result) => {\n * console.log(result.data) // { id: 1, ...}\n * console.log(result.found) // 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFind\n * @fires Mapper#afterFind\n * @method Mapper#find\n * @param {(string|number)} id The primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options. Refer to the `find` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found record. Resolves with\n * `undefined` if no record was found.\n * @see http://www.js-data.io/v3.0/docs/reading-data\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n find (id, opts) {\n return this.crud('find', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~beforeFindAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeFindAll\n * @see Mapper~beforeFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Mapper~beforeFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFindAll}.\n * @see Mapper#event:beforeFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~afterFindAllListener} for how to listen for this event.\n *\n * @event Mapper#afterFindAll\n * @see Mapper~afterFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Mapper~afterFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFindAll}.\n * @see Mapper#event:afterFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, select records to retrieve via an adapter.\n *\n * {@link Mapper#beforeFindAll} will be called before calling the adapter.\n * {@link Mapper#afterFindAll} will be called after calling the adapter.\n *\n * @example\n * // Find all \"published\" blog posts\n * PostMapper.findAll({ status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, status: 'published', ...}, ...]\n * })\n *\n * @example\n * // Get full response\n * PostMapper.findAll({ status: 'published' }, { raw: true }).then((result) => {\n * console.log(result.data) // [{ id: 1, status: 'published', ...}, ...]\n * console.log(result.found) // e.g. 13\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFindAll\n * @fires Mapper#afterFindAll\n * @method Mapper#findAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `findAll` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n findAll (query, opts) {\n return this.crud('findAll', query, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Mapper#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapter (name) {\n this.dbg('getAdapter', 'name:', name)\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Mapper#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || opts.defaultAdapter\n },\n\n /**\n * Get the object of registered adapters for this Mapper.\n *\n * @method Mapper#getAdapters\n * @returns {Object} {@link Mapper#_adapters}\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Returns this Mapper's {@link Schema}.\n *\n * @method Mapper#getSchema\n * @returns {Schema} This Mapper's {@link Schema}.\n * @see Mapper#schema\n * @since 3.0.0\n */\n getSchema () {\n return this.schema\n },\n\n /**\n * Defines a hasMany relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * UserMapper.hasMany(PostMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // post records will be attached to user records at \"user.posts\"\n * localField: 'posts'\n * })\n *\n * @method Mapper#hasMany\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasMany (relatedMapper, opts) {\n return hasMany(relatedMapper, opts)(this)\n },\n\n /**\n * Defines a hasOne relationship. Only useful if you're managing your Mappers\n * manually and not using a {@link Container} or {@link DataStore} component.\n *\n * @example\n * UserMapper.hasOne(ProfileMapper, {\n * // profile.user_id points to user.id\n * foreignKey: 'user_id'\n * // profile records will be attached to user records at \"user.profile\"\n * localField: 'profile'\n * })\n *\n * @method Mapper#hasOne\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasOne (relatedMapper, opts) {\n return hasOne(relatedMapper, opts)(this)\n },\n\n /**\n * Return whether `record` is an instance of this Mapper's recordClass.\n *\n * @example\n * const post = PostMapper.createRecord()\n *\n * console.log(PostMapper.is(post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof PostMapper.recordClass) // true\n *\n * @method Mapper#is\n * @param {Object|Record} record The record to check.\n * @returns {boolean} Whether `record` is an instance of this Mapper's\n * {@link Mapper#recordClass}.\n * @since 3.0.0\n */\n is (record) {\n const recordClass = this.recordClass\n return recordClass ? record instanceof recordClass : false\n },\n\n /**\n * Register an adapter on this Mapper under the given name.\n *\n * @method Mapper#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for this Mapper.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.defaultAdapter = name\n }\n },\n\n /**\n * Select records according to the `query` argument, and aggregate the sum\n * value of the property specified by `field`.\n *\n * {@link Mapper#beforeSum} will be called before calling the adapter.\n * {@link Mapper#afterSum} will be called after calling the adapter.\n *\n * @example\n * PurchaseOrderMapper.sum('amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Mapper#sum\n * @param {string} field The field to sum.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `sum` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the aggregated sum.\n * @since 3.0.0\n */\n sum (field, query, opts) {\n return this.crud('sum', field, query, opts)\n },\n\n /**\n * Return a plain object representation of the given record. Relations can\n * be optionally be included. Non-schema properties can be excluded.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })\n * console.log(PersonMapper.toJSON(person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(PersonMapper.toJSON(person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Mapper#toJSON\n * @param {Record|Record[]} records Record or records from which to create a\n * POJO representation.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the POJO representation.\n * @param {boolean} [opts.withAll] Whether to simply include all relations in\n * the representation. Overrides `opts.with`.\n * @returns {Object|Object[]} POJO representation of the record or records.\n * @since 3.0.0\n */\n toJSON (records, opts) {\n let record\n opts || (opts = {})\n if (utils.isArray(records)) {\n return records.map((record) => this.toJSON(record, opts))\n } else {\n record = records\n }\n const relationFields = (this ? this.relationFields : []) || []\n let json = {}\n let properties\n if (this && this.schema) {\n properties = this.schema.properties || {}\n // TODO: Make this work recursively\n utils.forOwn(properties, (opts, prop) => {\n json[prop] = utils.plainCopy(record[prop])\n })\n }\n properties || (properties = {})\n if (!opts.strict) {\n for (var key in record) {\n if (!properties[key] && relationFields.indexOf(key) === -1) {\n json[key] = utils.plainCopy(record[key])\n }\n }\n }\n // The user wants to include relations in the resulting plain object\n // representation\n if (this && opts.withAll) {\n opts.with = relationFields.slice()\n }\n if (this && opts.with) {\n if (utils.isString(opts.with)) {\n opts.with = [opts.with]\n }\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(record)\n if (relationData) {\n // The actual recursion\n if (utils.isArray(relationData)) {\n def.setLocalField(json, relationData.map((item) => {\n return def.getRelation().toJSON(item, optsCopy)\n }))\n } else {\n def.setLocalField(json, def.getRelation().toJSON(relationData, optsCopy))\n }\n }\n })\n }\n return json\n },\n\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~beforeUpdateListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdate\n * @see Mapper~beforeUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Mapper~beforeUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeUpdate}.\n * @see Mapper#event:beforeUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~afterUpdateListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdate\n * @see Mapper~afterUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Mapper~afterUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterUpdate}.\n * @see Mapper#event:afterUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Using an adapter, update the record with the primary key specified by the\n * `id` argument.\n *\n * {@link Mapper#beforeUpdate} will be called before updating the record.\n * {@link Mapper#afterUpdate} will be called after updating the record.\n *\n * @example\n * // Update a specific post\n * PostMapper.update(1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Mapper#beforeUpdate\n * @fires Mapper#afterUpdate\n * @method Mapper#update\n * @param {(string|number)} id The primary key of the record to update.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options. Refer to the `update` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * transaction.\n * @returns {Promise} Resolves with the updated record. Rejects if the record\n * could not be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n update (id, props, opts) {\n return this.crud('update', id, props, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateAll\n * @see Mapper~beforeUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Mapper~beforeUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Mapper#event:beforeUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateAll\n * @see Mapper~afterUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Mapper~afterUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Mapper#event:afterUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, perform the a single updated to the selected\n * records.\n *\n * {@link Mapper#beforeUpdateAll} will be called before making the update.\n * {@link Mapper#afterUpdateAll} will be called after making the update.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * PostMapper.updateAll(update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateAll\n * @fires Mapper#afterUpdateAll\n * @method Mapper#updateAll\n * @param {Object} props Update to apply to selected records.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `updateAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the update records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateAll (props, query, opts) {\n return this.crud('updateAll', props, query, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateMany\n * @see Mapper~beforeUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Mapper~beforeUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Mapper#event:beforeUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateMany\n * @see Mapper~afterUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Mapper~afterUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Mapper#event:afterUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Given an array of updates, perform each of the updates via an adapter. Each\n * \"update\" is a hash of properties with which to update an record. Each\n * update must contain the primary key of the record to be updated.\n *\n * {@link Mapper#beforeUpdateMany} will be called before making the update.\n * {@link Mapper#afterUpdateMany} will be called after making the update.\n *\n * @example\n * PostMapper.updateMany([\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateMany\n * @fires Mapper#afterUpdateMany\n * @method Mapper#updateMany\n * @param {Record[]} records Array up record updates.\n * @param {Object} [opts] Configuration options. Refer to the `updateMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the updated records. Rejects if any of the\n * records could be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateMany (records, opts) {\n return this.crud('updateMany', records, opts)\n },\n\n /**\n * Validate the given record or records according to this Mapper's\n * {@link Schema}. If there are no validation errors then the return value\n * will be `undefined`.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonSchema = new Schema({\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * })\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: PersonSchema\n * })\n * let errors = PersonMapper.validate({ name: 'John' })\n * console.log(errors) // undefined\n * errors = PersonMapper.validate({ name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Mapper#validate\n * @param {Object|Object[]} record The record or records to validate.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Schema#validate}.\n * @returns {Object[]} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (record, opts) {\n opts || (opts = {})\n const schema = this.getSchema()\n const _opts = utils.pick(opts, ['existingOnly'])\n if (utils.isArray(record)) {\n const errors = record.map((_record) => schema.validate(_record, utils.pick(_opts, ['existingOnly'])))\n let hasErrors = false\n errors.forEach(function (err) {\n if (err) {\n hasErrors = true\n }\n })\n if (hasErrors) {\n return errors\n }\n return undefined\n }\n return schema.validate(record, _opts)\n },\n\n /**\n * Method used to wrap data returned by an adapter with this Mapper's\n * {@link Mapper#recordClass}. This method is used by all of a Mapper's CRUD\n * methods. The provided implementation of this method assumes that the `data`\n * passed to it is a record or records that need to be wrapped with\n * {@link Mapper#createRecord}. Override with care.\n *\n * Provided implementation of {@link Mapper#wrap}:\n *\n * ```\n * function (data, opts) {\n * return this.createRecord(data, opts)\n * }\n * ```\n *\n * @example\n * const PostMapper = new Mapper({\n * name: 'post',\n * // Override to customize behavior\n * wrap (data, opts) {\n * const originalWrap = this.constructor.prototype.wrap\n * // Let's say \"GET /post\" doesn't return JSON quite like JSData expects,\n * // but the actual post records are nested under a \"posts\" field. So,\n * // we override Mapper#wrap to handle this special case.\n * if (opts.op === 'findAll') {\n * return originalWrap.call(this, data.posts, opts)\n * }\n * // Otherwise perform original behavior\n * return originalWrap.call(this, data, opts)\n * }\n * })\n *\n * @method Mapper#wrap\n * @param {Object|Object[]} data The record or records to be wrapped.\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#createRecord}.\n * @returns {Record|Record[]} The wrapped record or records.\n * @since 3.0.0\n */\n wrap (data, opts) {\n return this.createRecord(data, opts)\n },\n\n /**\n * @ignore\n */\n defineRelations () {\n // Setup the mapper's relations, including generating Mapper#relationList\n // and Mapper#relationFields\n utils.forOwn(this.relations, (group, type) => {\n utils.forOwn(group, (relations, _name) => {\n if (utils.isObject(relations)) {\n relations = [relations]\n }\n relations.forEach((def) => {\n const relatedMapper = this.datastore.getMapperByName(_name) || _name\n def.getRelation = () => this.datastore.getMapper(_name)\n\n if (typeof Relation[type] !== 'function') {\n throw utils.err(DOMAIN, 'defineRelations')(400, 'relation type (hasOne, hasMany, etc)', type, true)\n }\n\n this[type](relatedMapper, def)\n })\n })\n })\n }\n})\n\n/**\n * Create a subclass of this Mapper:\n *\n * @example Mapper.extend\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomMapperClass extends Mapper {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customMapper = new CustomMapperClass()\n * console.log(customMapper.foo())\n * console.log(CustomMapperClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherMapperClass = Mapper.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherMapper = new OtherMapperClass()\n * console.log(otherMapper.foo())\n * console.log(OtherMapperClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherMapperClass () {\n * Mapper.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Mapper.extend({\n * constructor: AnotherMapperClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherMapper = new AnotherMapperClass()\n * console.log(anotherMapper.created_at)\n * console.log(anotherMapper.foo())\n * console.log(AnotherMapperClass.beep())\n *\n * @method Mapper.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Mapper class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Mapper from './Mapper'\n\nconst DOMAIN = 'Container'\n\nexport const proxiedMapperMethods = [\n /**\n * Wrapper for {@link Mapper#count}.\n *\n * @example\n * // Get the number of published blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.count('post', { status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Container#count\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#count}.\n * @param {Object} [opts] See {@link Mapper#count}.\n * @returns {Promise} See {@link Mapper#count}.\n * @see Mapper#count\n * @since 3.0.0\n */\n 'count',\n\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~beforeCreateListener} for how to listen for this event.\n *\n * @event Container#beforeCreate\n * @see Container~beforeCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Container~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see Container#event:beforeCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~afterCreateListener} for how to listen for this event.\n *\n * @event Container#afterCreate\n * @see Container~afterCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Container~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see Container#event:afterCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}.\n *\n * @example\n * // Create and save a new blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.create('post', {\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreate\n * @fires Container#afterCreate\n * @method Container#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props See {@link Mapper#create}.\n * @param {Object} [opts] See {@link Mapper#create}.\n * @returns {Promise} See {@link Mapper#create}.\n * @see Mapper#create\n * @since 3.0.0\n */\n 'create',\n\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Container#beforeCreateMany\n * @see Container~beforeCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Container~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Container#event:beforeCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~afterCreateManyListener} for how to listen for this event.\n *\n * @event Container#afterCreateMany\n * @see Container~afterCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Container~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Container#event:afterCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}.\n *\n * @example\n * // Create and save several new blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.createMany('post', [{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreateMany\n * @fires Container#afterCreateMany\n * @method Container#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record[]} records See {@link Mapper#createMany}.\n * @param {Object} [opts] See {@link Mapper#createMany}.\n * @returns {Promise} See {@link Mapper#createMany}.\n * @see Mapper#createMany\n * @since 3.0.0\n */\n 'createMany',\n\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = PostMapper.createRecord()\n *\n * @method Container#createRecord\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Object[]} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Promise} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n 'createRecord',\n\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~beforeDestroyListener} for how to listen for this event.\n *\n * @event Container#beforeDestroy\n * @see Container~beforeDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Container~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see Container#event:beforeDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~afterDestroyListener} for how to listen for this event.\n *\n * @event Container#afterDestroy\n * @see Container~afterDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Container~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see Container#event:afterDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}.\n *\n * @example\n * // Destroy a specific blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroy('post', 1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @fires Container#beforeDestroy\n * @fires Container#afterDestroy\n * @method Container#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#destroy}.\n * @param {Object} [opts] See {@link Mapper#destroy}.\n * @returns {Promise} See {@link Mapper#destroy}.\n * @see Mapper#destroy\n * @since 3.0.0\n */\n 'destroy',\n\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Container#beforeDestroyAll\n * @see Container~beforeDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Container~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see Container#event:beforeDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Container#afterDestroyAll\n * @see Container~afterDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Container~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see Container#event:afterDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}.\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroyAll('post', { status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @fires Container#beforeDestroyAll\n * @fires Container#afterDestroyAll\n * @method Container#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#destroyAll}.\n * @param {Object} [opts] See {@link Mapper#destroyAll}.\n * @returns {Promise} See {@link Mapper#destroyAll}.\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n 'destroyAll',\n\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~beforeFindListener} for how to listen for this event.\n *\n * @event Container#beforeFind\n * @see Container~beforeFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Container~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see Container#event:beforeFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~afterFindListener} for how to listen for this event.\n *\n * @event Container#afterFind\n * @see Container~afterFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Container~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see Container#event:afterFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.find('post', 1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @fires Container#beforeFind\n * @fires Container#afterFind\n * @method Container#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#find}.\n * @param {Object} [opts] See {@link Mapper#find}.\n * @returns {Promise} See {@link Mapper#find}.\n * @see Mapper#find\n * @since 3.0.0\n */\n 'find',\n\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~beforeFindAllListener} for how to listen for this event.\n *\n * @event Container#beforeFindAll\n * @see Container~beforeFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Container~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see Container#event:beforeFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~afterFindAllListener} for how to listen for this event.\n *\n * @event Container#afterFindAll\n * @see Container~afterFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Container~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see Container#event:afterFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * @example\n * // Find all \"published\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.findAll('post', { status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, ...}, ...]\n * })\n *\n * @fires Container#beforeFindAll\n * @fires Container#afterFindAll\n * @method Container#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#findAll}.\n * @param {Object} [opts] See {@link Mapper#findAll}.\n * @returns {Promise} See {@link Mapper#findAll}.\n * @see Mapper#findAll\n * @since 3.0.0\n */\n 'findAll',\n\n /**\n * Wrapper for {@link Mapper#getSchema}.\n *\n * @method Container#getSchema\n * @param {string} name Name of the {@link Mapper} to target.\n * @returns {Schema} See {@link Mapper#getSchema}.\n * @see Mapper#getSchema\n * @since 3.0.0\n */\n 'getSchema',\n\n /**\n * Wrapper for {@link Mapper#is}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = store.createRecord()\n *\n * console.log(store.is('post', post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof store.getMapper('post').recordClass) // true\n *\n * @method Container#is\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Record} record See {@link Mapper#is}.\n * @returns {boolean} See {@link Mapper#is}.\n * @see Mapper#is\n * @since 3.0.0\n */\n 'is',\n\n /**\n * Wrapper for {@link Mapper#sum}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('purchase_order')\n *\n * store.sum('purchase_order', 'amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Container#sum\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {string} field See {@link Mapper#sum}.\n * @param {Object} [query] See {@link Mapper#sum}.\n * @param {Object} [opts] See {@link Mapper#sum}.\n * @returns {Promise} See {@link Mapper#sum}.\n * @see Mapper#sum\n * @since 3.0.0\n */\n 'sum',\n\n /**\n * Wrapper for {@link Mapper#toJSON}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('person', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' })\n * console.log(store.toJSON('person', person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(store.toJSON('person', person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Container#toJSON\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record|Record[]} records See {@link Mapper#toJSON}.\n * @param {Object} [opts] See {@link Mapper#toJSON}.\n * @returns {Object|Object[]} See {@link Mapper#toJSON}.\n * @see Mapper#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~beforeUpdateListener} for how to listen for this event.\n *\n * @event Container#beforeUpdate\n * @see Container~beforeUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Container~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see Container#event:beforeUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~afterUpdateListener} for how to listen for this event.\n *\n * @event Container#afterUpdate\n * @see Container~afterUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Container~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see Container#event:afterUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.update('post', 1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Container#beforeUpdate\n * @fires Container#afterUpdate\n * @method Container#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#update}.\n * @param {Object} record See {@link Mapper#update}.\n * @param {Object} [opts] See {@link Mapper#update}.\n * @returns {Promise} See {@link Mapper#update}.\n * @see Mapper#update\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n 'update',\n\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateAll\n * @see Container~beforeUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Container~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Container#event:beforeUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Container#afterUpdateAll\n * @see Container~afterUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Container~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Container#event:afterUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * store.updateAll('post', update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateAll\n * @fires Container#afterUpdateAll\n * @method Container#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} update See {@link Mapper#updateAll}.\n * @param {Object} [query] See {@link Mapper#updateAll}.\n * @param {Object} [opts] See {@link Mapper#updateAll}.\n * @returns {Promise} See {@link Mapper#updateAll}.\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n 'updateAll',\n\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateMany\n * @see Container~beforeUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Container~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Container#event:beforeUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Container#afterUpdateMany\n * @see Container~afterUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Container~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Container#event:afterUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.updateMany('post', [\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateMany\n * @fires Container#afterUpdateMany\n * @method Container#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#updateMany}.\n * @param {Object} [opts] See {@link Mapper#updateMany}.\n * @returns {Promise} See {@link Mapper#updateMany}.\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n 'updateMany',\n\n /**\n * Wrapper for {@link Mapper#validate}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * let errors = store.validate('post', { name: 'John' })\n * console.log(errors) // undefined\n * errors = store.validate('post', { name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Container#validate\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#validate}.\n * @param {Object} [opts] See {@link Mapper#validate}.\n * @returns {Promise} See {@link Mapper#validate}.\n * @see Mapper#validate\n * @since 3.0.0\n */\n 'validate'\n]\n\n/**\n * The `Container` class is a place to define and store {@link Mapper} instances.\n *\n * `Container` makes it easy to manage your Mappers. Without a container, you\n * need to manage Mappers yourself, including resolving circular dependencies\n * among relations. All Mappers in a container share the same adapters, so you\n * don't have to register adapters for every single Mapper.\n *\n * @example Container#constructor\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n *\n * @class Container\n * @extends Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {Constructor} [opts.mapperClass] See {@link Container#mapperClass}.\n * @param {Object} [opts.mapperDefaults] See {@link Container#mapperDefaults}.\n * @since 3.0.0\n */\nexport function Container (opts) {\n utils.classCallCheck(this, Container)\n Component.call(this)\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * The adapters registered with this Container, which are also shared by all\n * Mappers in this Container.\n *\n * @name Container#_adapters\n * @see Container#registerAdapter\n * @since 3.0.0\n * @type {Object}\n */\n _adapters: {\n value: {}\n },\n\n /**\n * The the mappers in this container\n *\n * @name Container#_mappers\n * @see Mapper\n * @since 3.0.0\n * @type {Object}\n */\n _mappers: {\n value: {}\n },\n\n /**\n * Constructor function to use in {@link Container#defineMapper} to create new\n * {@link Mapper} instances. {@link Container#mapperClass} should extend\n * {@link Mapper}. By default {@link Mapper} is used to instantiate Mappers.\n *\n * @example Container#mapperClass\n * // import {Container, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const store = new Container({\n * mapperClass: MyMapperClass\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').foo())\n *\n * @name Container#mapperClass\n * @see Mapper\n * @since 3.0.0\n * @type {Constructor}\n */\n mapperClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply options provided by the user\n utils.fillIn(this, opts)\n\n /**\n * Defaults options to pass to {@link Container#mapperClass} when creating a\n * new {@link Mapper}.\n *\n * @example Container#mapperDefaults\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: {\n * idAttribute: '_id'\n * }\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').idAttribute)\n *\n * @default {}\n * @name Container#mapperDefaults\n * @since 3.0.0\n * @type {Object}\n */\n this.mapperDefaults = this.mapperDefaults || {}\n\n // Use the Mapper class if the user didn't provide a mapperClass\n this.mapperClass || (this.mapperClass = Mapper)\n}\n\nconst props = {\n constructor: Container,\n\n /**\n * Register a new event listener on this Container.\n *\n * Proxy for {@link Component#on}. If an event was emitted by a {@link Mapper}\n * in the Container, then the name of the {@link Mapper} will be prepended to\n * the arugments passed to the listener.\n *\n * @example Container#on\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.on('foo', function (...args) { console.log(args.join(':')) })\n * store.defineMapper('user')\n * store.emit('foo', 'arg1', 'arg2')\n * store.getMapper('user').emit('foo', 'arg1', 'arg2')\n *\n * @method Container#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n\n /**\n * Used to bind to events emitted by mappers in this container.\n *\n * @method Container#_onMapperEvent\n * @param {string} name Name of the mapper that emitted the event.\n * @param {...*} [args] Args See {@link Mapper#emit}.\n * @private\n * @since 3.0.0\n */\n _onMapperEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * Return a container scoped to a particular mapper.\n *\n * @example Container#as\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method Container#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} A container scoped to a particular mapper.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n proxiedMapperMethods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Create a new mapper and register it in this container.\n *\n * @example Container#defineMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: { foo: 'bar' }\n * })\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(UserMapper.foo)\n *\n * @method Container#defineMapper\n * @param {string} name Name under which to register the new {@link Mapper}.\n * {@link Mapper#name} will be set to this value.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Container#mapperClass} when creating the new {@link Mapper}.\n * @returns {Mapper} The newly created instance of {@link Mapper}.\n * @see Container#as\n * @since 3.0.0\n */\n defineMapper (name, opts) {\n // For backwards compatibility with defineResource\n if (utils.isObject(name)) {\n opts = name\n name = opts.name\n }\n if (!utils.isString(name)) {\n throw utils.err(`${DOMAIN}#defineMapper`, 'name')(400, 'string', name)\n }\n\n // Default values for arguments\n opts || (opts = {})\n // Set Mapper#name\n opts.name = name\n opts.relations || (opts.relations = {})\n\n // Check if the user is overriding the datastore's default mapperClass\n const mapperClass = opts.mapperClass || this.mapperClass\n delete opts.mapperClass\n\n // Apply the datastore's defaults to the options going into the mapper\n utils.fillIn(opts, this.mapperDefaults)\n\n // Instantiate a mapper\n const mapper = this._mappers[name] = new mapperClass(opts) // eslint-disable-line\n mapper.relations || (mapper.relations = {})\n // Make sure the mapper's name is set\n mapper.name = name\n // All mappers in this datastore will share adapters\n mapper._adapters = this.getAdapters()\n\n mapper.datastore = this\n\n mapper.on('all', (...args) => this._onMapperEvent(name, ...args))\n mapper.defineRelations()\n\n return mapper\n },\n\n defineResource (name, opts) {\n console.warn('DEPRECATED: defineResource is deprecated, use defineMapper instead')\n return this.defineMapper(name, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Container#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n */\n getAdapter (name) {\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Container#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || this.mapperDefaults.defaultAdapter\n },\n\n /**\n * Return the registered adapters of this container.\n *\n * @method Container#getAdapters\n * @returns {Adapter}\n * @since 3.0.0\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Return the mapper registered under the specified name.\n *\n * @example Container#getMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * store.getMapper('profile') // throws Error, there is no mapper with name \"profile\"\n *\n * @method Container#getMapper\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapper (name) {\n const mapper = this.getMapperByName(name)\n if (!mapper) {\n throw utils.err(`${DOMAIN}#getMapper`, name)(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Return the mapper registered under the specified name.\n * Doesn't throw error if mapper doesn't exist.\n *\n * @example Container#getMapperByName\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(store.getMapper('profile')) // Does NOT throw an error\n *\n * @method Container#getMapperByName\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapperByName (name) {\n return this._mappers[name]\n },\n\n /**\n * Register an adapter on this container under the given name. Adapters\n * registered on a container are shared by all mappers in the container.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n *\n * @method Container#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for all Mappers in this container.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.mapperDefaults.defaultAdapter = name\n utils.forOwn(this._mappers, function (mapper) {\n mapper.defaultAdapter = name\n })\n }\n }\n}\n\nproxiedMapperMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getMapper(name)[method](...args)\n }\n})\n\nComponent.extend(props)\n\n/**\n * Create a subclass of this Container:\n * @example Container.extend\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomContainerClass extends Container {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customContainer = new CustomContainerClass()\n * console.log(customContainer.foo())\n * console.log(CustomContainerClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherContainerClass = Container.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherContainer = new OtherContainerClass()\n * console.log(otherContainer.foo())\n * console.log(OtherContainerClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherContainerClass () {\n * Container.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Container.extend({\n * constructor: AnotherContainerClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherContainer = new AnotherContainerClass()\n * console.log(anotherContainer.created_at)\n * console.log(anotherContainer.foo())\n * console.log(AnotherContainerClass.beep())\n *\n * @method Container.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Container class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport './decorators'\nimport Collection from './Collection'\n\nconst DOMAIN = 'LinkedCollection'\n\n/**\n * Extends {@link Collection}. Used by a {@link DataStore} to implement an\n * Identity Map.\n *\n * ```javascript\n * import {LinkedCollection} from 'js-data'\n * ```\n *\n * @class LinkedCollection\n * @extends Collection\n * @param {Array} [records] Initial set of records to insert into the\n * collection. See {@link Collection}.\n * @param {Object} [opts] Configuration options. See {@link Collection}.\n * @returns {Mapper}\n */\nfunction LinkedCollection (records, opts) {\n utils.classCallCheck(this, LinkedCollection)\n // Make sure this collection has somewhere to store \"added\" timestamps\n Object.defineProperties(this, {\n _added: {\n value: {}\n },\n datastore: {\n writable: true,\n value: undefined\n }\n })\n\n Collection.call(this, records, opts)\n\n // Make sure this collection has a reference to a datastore\n if (!this.datastore) {\n throw utils.err(`new ${DOMAIN}`, 'opts.datastore')(400, 'DataStore', this.datastore)\n }\n}\n\nexport default Collection.extend({\n constructor: LinkedCollection,\n\n _addMeta (record, timestamp) {\n // Track when this record was added\n this._added[this.recordId(record)] = timestamp\n\n if (utils.isFunction(record._set)) {\n record._set('$', timestamp)\n }\n },\n\n _clearMeta (record) {\n delete this._added[this.recordId(record)]\n if (utils.isFunction(record._set)) {\n record._set('$') // unset\n }\n },\n\n _onRecordEvent (...args) {\n Collection.prototype._onRecordEvent.apply(this, args)\n const event = args[0]\n // This is a very brute force method\n // Lots of room for optimization\n if (utils.isString(event) && event.indexOf('change') === 0) {\n this.updateIndexes(args[1])\n }\n },\n\n add (records, opts) {\n const mapper = this.mapper\n const timestamp = new Date().getTime()\n const singular = utils.isObject(records) && !utils.isArray(records)\n\n if (singular) {\n records = [records]\n }\n records = Collection.prototype.add.call(this, records, opts)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.addLinkedRecords(records)\n })\n }\n\n records.forEach((record) => this._addMeta(record, timestamp))\n\n return singular ? records[0] : records\n },\n\n remove (idOrRecord, opts) {\n const mapper = this.mapper\n const record = Collection.prototype.remove.call(this, idOrRecord, opts)\n if (record) {\n this._clearMeta(record)\n }\n\n if (mapper.relationList.length && record) {\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, [record])\n })\n }\n\n return record\n },\n\n removeAll (query, opts) {\n const mapper = this.mapper\n const records = Collection.prototype.removeAll.call(this, query, opts)\n records.forEach(this._clearMeta, this)\n\n if (mapper.relationList.length && records.length) {\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, records)\n })\n }\n\n return records\n }\n})\n\n/**\n * Create a subclass of this LinkedCollection:\n *\n * @example LinkedCollection.extend\n * // Normally you would do: import {LinkedCollection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {LinkedCollection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomLinkedCollectionClass extends LinkedCollection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customLinkedCollection = new CustomLinkedCollectionClass()\n * console.log(customLinkedCollection.foo())\n * console.log(CustomLinkedCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherLinkedCollectionClass = LinkedCollection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherLinkedCollection = new OtherLinkedCollectionClass()\n * console.log(otherLinkedCollection.foo())\n * console.log(OtherLinkedCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherLinkedCollectionClass () {\n * LinkedCollection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * LinkedCollection.extend({\n * constructor: AnotherLinkedCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherLinkedCollection = new AnotherLinkedCollectionClass()\n * console.log(anotherLinkedCollection.created_at)\n * console.log(anotherLinkedCollection.foo())\n * console.log(AnotherLinkedCollectionClass.beep())\n *\n * @method LinkedCollection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this LinkedCollection class.\n * @since 3.0.0\n */\n","import utils, { safeSetLink, safeSetProp } from './utils'\n\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\nimport {proxiedMapperMethods, Container} from './Container'\nimport LinkedCollection from './LinkedCollection'\n\nconst DOMAIN = 'DataStore'\nconst proxiedCollectionMethods = [\n /**\n * Wrapper for {@link LinkedCollection#add}.\n *\n * @example DataStore#add\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n *\n * // Add one book to the in-memory store:\n * store.add('book', { id: 1, title: 'Respect your Data' })\n * // Add multiple books to the in-memory store:\n * store.add('book', [\n * { id: 2, title: 'Easy data recipes' },\n * { id: 3, title: 'Active Record 101' }\n * ])\n *\n * @fires DataStore#add\n * @method DataStore#add\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Object[]|Record|Record[])} data See {@link LinkedCollection#add}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#add}.\n * @returns {(Object|Object[]|Record|Record[])} See {@link LinkedCollection#add}.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n 'add',\n\n /**\n * Wrapper for {@link LinkedCollection#between}.\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = store.between('user', 18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = store.between('user', [18], [30], { index: 'age' })\n *\n * @method DataStore#between\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Array} leftKeys See {@link LinkedCollection#between}.\n * @param {Array} rightKeys See {@link LinkedCollection#between}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#between}.\n * @returns {Object[]|Record[]} See {@link LinkedCollection#between}.\n * @see LinkedCollection#between\n * @see Collection#between\n * @since 3.0.0\n */\n 'between',\n\n /**\n * Wrapper for {@link LinkedCollection#createIndex}.\n *\n * @example\n * // Index users by age\n * store.createIndex('user', 'age')\n *\n * @example\n * // Index users by status and role\n * store.createIndex('user', 'statusAndRole', ['status', 'role'])\n *\n * @method DataStore#createIndex\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {string} name See {@link LinkedCollection#createIndex}.\n * @param {string[]} [fieldList] See {@link LinkedCollection#createIndex}.\n * @see LinkedCollection#createIndex\n * @see Collection#createIndex\n * @since 3.0.0\n */\n 'createIndex',\n\n /**\n * Wrapper for {@link LinkedCollection#filter}.\n *\n * @example DataStore#filter\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = store.filter('post', function (post) { return post.id % 2 === 0 })\n *\n * @method DataStore#filter\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Function)} [queryOrFn={}] See {@link LinkedCollection#filter}.\n * @param {Object} [thisArg] See {@link LinkedCollection#filter}.\n * @returns {Array} See {@link LinkedCollection#filter}.\n * @see LinkedCollection#filter\n * @see Collection#filter\n * @since 3.0.0\n */\n 'filter',\n\n /**\n * Wrapper for {@link LinkedCollection#get}.\n *\n * @example DataStore#get\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * console.log(store.get('post', 1)) // {...}\n * console.log(store.get('post', 2)) // undefined\n *\n * @method DataStore#get\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link LinkedCollection#get}.\n * @returns {(Object|Record)} See {@link LinkedCollection#get}.\n * @see LinkedCollection#get\n * @see Collection#get\n * @since 3.0.0\n */\n 'get',\n\n /**\n * Wrapper for {@link LinkedCollection#getAll}.\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = store.getAll('post', 'draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = store.getAll('post', ['draft'], ['inReview'], { index: 'status' })\n *\n * @method DataStore#getAll\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {...Array} [keyList] See {@link LinkedCollection#getAll}.\n * @param {Object} [opts] See {@link LinkedCollection#getAll}.\n * @returns {Array} See {@link LinkedCollection#getAll}.\n * @see LinkedCollection#getAll\n * @see Collection#getAll\n * @since 3.0.0\n */\n 'getAll',\n\n /**\n * Wrapper for {@link LinkedCollection#prune}.\n *\n * @method DataStore#prune\n * @param {Object} [opts] See {@link LinkedCollection#prune}.\n * @returns {Array} See {@link LinkedCollection#prune}.\n * @see LinkedCollection#prune\n * @see Collection#prune\n * @since 3.0.0\n */\n 'prune',\n\n /**\n * Wrapper for {@link LinkedCollection#query}.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * store.query('user')\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method DataStore#query\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @returns {Query} See {@link LinkedCollection#query}.\n * @see LinkedCollection#query\n * @see Collection#query\n * @since 3.0.0\n */\n 'query',\n\n /**\n * Wrapper for {@link LinkedCollection#toJSON}.\n *\n * @example\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * title: { type: 'string' }\n * }\n * }\n * })\n * store.add('post', [\n * { id: 1, status: 'published', title: 'Respect your Data' },\n * { id: 2, status: 'draft', title: 'Connecting to a data source' }\n * ])\n * console.log(store.toJSON('post'))\n * const draftsJSON = store.query('post')\n * .filter({ status: 'draft' })\n * .mapCall('toJSON')\n * .run()\n *\n * @method DataStore#toJSON\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Object} [opts] See {@link LinkedCollection#toJSON}.\n * @returns {Array} See {@link LinkedCollection#toJSON}.\n * @see LinkedCollection#toJSON\n * @see Collection#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Wrapper for {@link LinkedCollection#unsaved}.\n *\n * @method DataStore#unsaved\n * @returns {Array} See {@link LinkedCollection#unsaved}.\n * @see LinkedCollection#unsaved\n * @see Collection#unsaved\n * @since 3.0.0\n */\n 'unsaved'\n]\nconst ownMethodsForScoping = [\n 'addToCache',\n 'cachedFind',\n 'cachedFindAll',\n 'cacheFind',\n 'cacheFindAll',\n 'hashQuery'\n]\n\nconst cachedFn = function (name, hashOrId, opts) {\n const cached = this._completedQueries[name][hashOrId]\n if (utils.isFunction(cached)) {\n return cached(name, hashOrId, opts)\n }\n return cached\n}\n\nconst DATASTORE_DEFAULTS = {\n /**\n * Whether in-memory relations should be unlinked from records after they are\n * destroyed.\n *\n * @default true\n * @name DataStore#unlinkOnDestroy\n * @since 3.0.0\n * @type {boolean}\n */\n unlinkOnDestroy: true,\n\n /**\n * Whether to use the pending query if a `find` request for the specified\n * record is currently underway. Can be set to `true`, `false`, or to a\n * function that returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFind\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFind: true,\n\n /**\n * Whether to use the pending query if a `findAll` request for the given query\n * is currently underway. Can be set to `true`, `false`, or to a function that\n * returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFindAll\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFindAll: true\n}\n\n/**\n * The `DataStore` class is an extension of {@link Container}. Not only does\n * `DataStore` manage mappers, but also collections. `DataStore` implements the\n * asynchronous {@link Mapper} methods, such as {@link Mapper#find} and\n * {@link Mapper#create}. If you use the asynchronous `DataStore` methods\n * instead of calling them directly on the mappers, then the results of the\n * method calls will be inserted into the store's collections. You can think of\n * a `DataStore` as an [Identity Map](https://en.wikipedia.org/wiki/Identity_map_pattern)\n * for the [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)\n * (the Mappers).\n *\n * ```javascript\n * import {DataStore} from 'js-data'\n * ```\n *\n * @example\n * import {DataStore} from 'js-data'\n * import HttpAdapter from 'js-data-http'\n * const store = new DataStore()\n *\n * // DataStore#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n *\n * // DataStore#as returns the store scoped to a particular Mapper.\n * const UserStore = store.as('user')\n *\n * // Call \"find\" on \"UserMapper\" (Stateless ORM)\n * UserMapper.find(1).then((user) => {\n * // retrieved a \"user\" record via the http adapter, but that's it\n *\n * // Call \"find\" on \"store\" targeting \"user\" (Stateful DataStore)\n * return store.find('user', 1) // same as \"UserStore.find(1)\"\n * }).then((user) => {\n * // not only was a \"user\" record retrieved, but it was added to the\n * // store's \"user\" collection\n * const cachedUser = store.getCollection('user').get(1)\n * console.log(user === cachedUser) // true\n * })\n *\n * @class DataStore\n * @extends Container\n * @param {Object} [opts] Configuration options. See {@link Container}.\n * @param {boolean} [opts.collectionClass={@link LinkedCollection}] See {@link DataStore#collectionClass}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {boolean} [opts.unlinkOnDestroy=true] See {@link DataStore#unlinkOnDestroy}.\n * @param {boolean|Function} [opts.usePendingFind=true] See {@link DataStore#usePendingFind}.\n * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link DataStore#usePendingFindAll}.\n * @returns {DataStore}\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/working-with-the-datastore\",\"Working with the DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/jsdata-and-the-browser\",\"Notes on using JSData in the Browser\"]\n */\nfunction DataStore (opts) {\n utils.classCallCheck(this, DataStore)\n\n opts || (opts = {})\n // Fill in any missing options with the defaults\n utils.fillIn(opts, DATASTORE_DEFAULTS)\n Container.call(this, opts)\n\n this.collectionClass = this.collectionClass || LinkedCollection\n this._collections = {}\n this._pendingQueries = {}\n this._completedQueries = {}\n}\n\nconst props = {\n constructor: DataStore,\n\n /**\n * Internal method used to handle Mapper responses.\n *\n * @method DataStore#_end\n * @private\n * @param {string} name Name of the {@link LinkedCollection} to which to\n * add the data.\n * @param {Object} result The result from a Mapper.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object|Array)} Result.\n */\n _end (name, result, opts) {\n let data = opts.raw ? result.data : result\n if (data && utils.isFunction(this.addToCache)) {\n data = this.addToCache(name, data, opts)\n if (opts.raw) {\n result.data = data\n } else {\n result = data\n }\n }\n return result\n },\n\n /**\n * Register a new event listener on this DataStore.\n *\n * Proxy for {@link Container#on}. If an event was emitted by a Mapper or\n * Collection in the DataStore, then the name of the Mapper or Collection will\n * be prepended to the arugments passed to the provided event handler.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * store.on('add', (mapperName, records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * store.on('change', (mapperName, record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method DataStore#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n */\n\n /**\n * Used to bind to events emitted by collections in this store.\n *\n * @method DataStore#_onCollectionEvent\n * @private\n * @param {string} name Name of the collection that emitted the event.\n * @param {...*} [args] Args passed to {@link Collection#emit}.\n */\n _onCollectionEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * This method takes the data received from {@link DataStore#find},\n * {@link DataStore#findAll}, {@link DataStore#update}, etc., and adds the\n * data to the store. _You don't need to call this method directly._\n *\n * If you're using the http adapter and your response data is in an unexpected\n * format, you may need to override this method so the right data gets added\n * to the store.\n *\n * @example\n * const store = new DataStore({\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return DataStore.prototype.addToCache.call(this, mapperName, data, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return super.addToCache(mapperName, data, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#addToCache\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {*} data Data from which data should be selected for add.\n * @param {Object} [opts] Configuration options.\n */\n addToCache (name, data, opts) {\n return this.getCollection(name).add(data, opts)\n },\n\n /**\n * Return the store scoped to a particular mapper/collection pair.\n *\n * @example DataStore.as\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method DataStore#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} The store, scoped to a particular Mapper/Collection pair.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n const methods = ownMethodsForScoping\n .concat(proxiedMapperMethods)\n .concat(proxiedCollectionMethods)\n\n methods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n props.getCollection = {\n writable: true,\n value () {\n return original.getCollection(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Retrieve a cached `find` result, if any. This method is called during\n * {@link DataStore#find} to determine if {@link Mapper#find} needs to be\n * called. If this method returns `undefined` then {@link Mapper#find} will\n * be called. Otherwise {@link DataStore#find} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFind.call(this, mapperName, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cachedFind(mapperName, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cachedFind: cachedFn,\n\n /**\n * Retrieve a cached `findAll` result, if any. This method is called during\n * {@link DataStore#findAll} to determine if {@link Mapper#findAll} needs to be\n * called. If this method returns `undefined` then {@link Mapper#findAll} will\n * be called. Otherwise {@link DataStore#findAll} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return super.cachedFindAll(mapperName, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cachedFindAll: cachedFn,\n\n /**\n * Mark a {@link Mapper#find} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `find` entry is\n * added it means subsequent calls to the same Resource with the same `id`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#get} instead of delegating to {@link Mapper#find}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cacheFind.call(this, mapperName, data, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cacheFind(mapperName, data, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {*} data The result to cache.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cacheFind (name, data, id, opts) {\n this._completedQueries[name][id] = (name, id, opts) => this.get(name, id)\n },\n\n /**\n * Mark a {@link Mapper#findAll} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `findAll` entry is\n * added it means subsequent calls to the same Resource with the same `query`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#filter} instead of delegating to {@link Mapper#findAll}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, data, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return super.cachedFindAll(mapperName, data, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {*} data The result to cache.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cacheFindAll (name, data, hash, opts) {\n this._completedQueries[name][hash] = (name, hash, opts) => this.filter(name, utils.fromJson(hash))\n },\n\n /**\n * Remove __all__ records from the in-memory store and reset\n * {@link DataStore#_completedQueries}.\n *\n * @method DataStore#clear\n * @returns {Object} Object containing all records that were in the store.\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n clear () {\n const removed = {}\n utils.forOwn(this._collections, (collection, name) => {\n removed[name] = collection.removeAll()\n this._completedQueries[name] = {}\n })\n return removed\n },\n\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~beforeCreateListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreate\n * @see DataStore~beforeCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback DataStore~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see DataStore#event:beforeCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~afterCreateListener} for how to listen for this event.\n *\n * @event DataStore#afterCreate\n * @see DataStore~afterCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback DataStore~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see DataStore#event:afterCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}. Adds the created record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book {\"author_id\":1234,...}\n * store.create('book', {\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }).then((book) => {\n * console.log(book.id) // 120392\n * console.log(book.title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreate\n * @fires DataStore#afterCreate\n * @fires DataStore#add\n * @method DataStore#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} record Passed to {@link Mapper#create}.\n * @param {Object} [opts] Passed to {@link Mapper#create}. See\n * {@link Mapper#create} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n create (name, record, opts) {\n opts || (opts = {})\n return Container.prototype.create.call(this, name, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~beforeCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreateMany\n * @see DataStore~beforeCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback DataStore~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see DataStore#event:beforeCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~afterCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterCreateMany\n * @see DataStore~afterCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback DataStore~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see DataStore#event:afterCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}. Adds the created records to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book [{\"author_id\":1234,...},{...}]\n * store.createMany('book', [{\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }, {\n * author_id: 1234,\n * edition: 'Second Edition',\n * title: 'Respect your Data'\n * }]).then((books) => {\n * console.log(books[0].id) // 142394\n * console.log(books[0].title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreateMany\n * @fires DataStore#afterCreateMany\n * @fires DataStore#add\n * @method DataStore#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Array} records Passed to {@link Mapper#createMany}.\n * @param {Object} [opts] Passed to {@link Mapper#createMany}. See\n * {@link Mapper#createMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n createMany (name, records, opts) {\n opts || (opts = {})\n return Container.prototype.createMany.call(this, name, records, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n defineMapper (name, opts) {\n // Complexity of this method is beyond simply using => functions to bind context\n const self = this\n const mapper = Container.prototype.defineMapper.call(self, name, opts)\n self._pendingQueries[name] = {}\n self._completedQueries[name] = {}\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n\n // The datastore uses a subclass of Collection that is \"datastore-aware\"\n const collection = self._collections[name] = new self.collectionClass(null, { // eslint-disable-line\n // Make sure the collection has somewhere to store \"added\" timestamps\n _added: {},\n // Give the collection a reference to this datastore\n datastore: self,\n // The mapper tied to the collection\n mapper\n })\n\n const schema = mapper.schema || {}\n const properties = schema.properties || {}\n // TODO: Make it possible index nested properties?\n utils.forOwn(properties, function (opts, prop) {\n if (opts.indexed) {\n collection.createIndex(prop)\n }\n })\n\n // Create a secondary index on the \"added\" timestamps of records in the\n // collection\n collection.createIndex('addedTimestamps', ['$'], {\n fieldGetter (obj) {\n return collection._added[collection.recordId(obj)]\n }\n })\n\n collection.on('all', function (...args) {\n self._onCollectionEvent(name, ...args)\n })\n\n const idAttribute = mapper.idAttribute\n\n mapper.relationList.forEach(function (def) {\n const relation = def.relation\n const localField = def.localField\n const path = `links.${localField}`\n const foreignKey = def.foreignKey\n const type = def.type\n const updateOpts = { index: foreignKey }\n let descriptor\n\n const getter = function () { return this._get(path) }\n\n if (type === belongsToType) {\n if (!collection.indexes[foreignKey]) {\n collection.createIndex(foreignKey)\n }\n\n descriptor = {\n get: getter,\n // e.g. profile.user = someUser\n // or comment.post = somePost\n set (record) {\n // e.g. const otherUser = profile.user\n const currentParent = this._get(path)\n // e.g. profile.user === someUser\n if (record === currentParent) {\n return currentParent\n }\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n\n // e.g. profile.user !== someUser\n // or comment.post !== somePost\n if (currentParent && inverseDef) {\n this.removeInverseRelation(currentParent, id, inverseDef, idAttribute)\n }\n if (record) {\n // e.g. profile.user = someUser\n const relatedIdAttribute = def.getRelation().idAttribute\n const relatedId = utils.get(record, relatedIdAttribute)\n\n // Prefer store record\n if (relatedId !== undefined && this._get('$')) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n // e.g. profile.user = someUser\n // or comment.post = somePost\n safeSetLink(this, localField, record)\n safeSetProp(this, foreignKey, relatedId)\n collection.updateIndex(this, updateOpts)\n\n if (inverseDef) {\n this.setupInverseRelation(record, id, inverseDef, idAttribute)\n }\n } else {\n // Unset in-memory link only\n // e.g. profile.user = undefined\n // or comment.post = undefined\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n\n let foreignKeyDescriptor = Object.getOwnPropertyDescriptor(mapper.recordClass.prototype, foreignKey)\n if (!foreignKeyDescriptor) {\n foreignKeyDescriptor = {\n enumerable: true\n }\n }\n const originalGet = foreignKeyDescriptor.get\n foreignKeyDescriptor.get = function () {\n if (originalGet) {\n return originalGet.call(this)\n }\n return this._get(`props.${foreignKey}`)\n }\n const originalSet = foreignKeyDescriptor.set\n foreignKeyDescriptor.set = function (value) {\n if (originalSet) {\n originalSet.call(this, value)\n }\n const currentParent = utils.get(this, localField)\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n const currentParentId = currentParent ? utils.get(currentParent, def.getRelation().idAttribute) : undefined\n\n if (currentParent && currentParentId !== undefined && currentParentId !== value) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n\n safeSetProp(this, foreignKey, value)\n collection.updateIndex(this, updateOpts)\n\n if ((value === undefined || value === null)) {\n if (currentParentId !== undefined) {\n // Unset locals\n utils.set(this, localField, undefined)\n }\n } else if (this._get('$')) {\n const storeRecord = self.get(relation, value)\n if (storeRecord) {\n utils.set(this, localField, storeRecord)\n }\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, foreignKey, foreignKeyDescriptor)\n } else if (type === hasManyType) {\n const localKeys = def.localKeys\n const foreignKeys = def.foreignKeys\n\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n\n descriptor = {\n get () {\n let current = getter.call(this)\n if (!current) {\n this._set(path, [])\n }\n return getter.call(this)\n },\n // e.g. post.comments = someComments\n // or user.groups = someGroups\n // or group.users = someUsers\n set (records) {\n if (records && !utils.isArray(records)) {\n records = [records]\n }\n const id = utils.get(this, idAttribute)\n const relatedIdAttribute = def.getRelation().idAttribute\n const inverseDef = def.getInverse(mapper)\n const inverseLocalField = inverseDef.localField\n const current = this._get(path) || []\n const toLink = []\n const toLinkIds = {}\n\n if (records) {\n records.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n const currentParent = utils.get(record, inverseLocalField)\n if (currentParent && currentParent !== this) {\n const currentChildrenOfParent = utils.get(currentParent, localField)\n // e.g. somePost.comments.remove(comment)\n if (relatedId === undefined) {\n utils.remove(currentChildrenOfParent, (child) => child === record)\n } else {\n utils.remove(currentChildrenOfParent, (child) => child === record || relatedId === utils.get(child, relatedIdAttribute))\n }\n }\n if (relatedId !== undefined) {\n if (this._get('$')) {\n // Prefer store record\n record = self.get(relation, relatedId) || record\n }\n // e.g. toLinkIds[comment.id] = comment\n toLinkIds[relatedId] = record\n }\n toLink.push(record)\n })\n }\n\n // e.g. post.comments = someComments\n if (foreignKey) {\n current.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(record) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update (unset) inverse relation\n if (records) {\n // e.g. comment.post_id = undefined\n safeSetProp(record, foreignKey, undefined)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n }\n // e.g. comment.post = undefined\n safeSetLink(record, inverseLocalField, undefined)\n }\n })\n toLink.forEach((record) => {\n // Update (set) inverse relation\n // e.g. comment.post_id = post.id\n safeSetProp(record, foreignKey, id)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n // e.g. comment.post = post\n safeSetLink(record, inverseLocalField, this)\n })\n } else if (localKeys) {\n // Update locals\n // e.g. group.users = someUsers\n // Update (set) inverse relation\n const ids = toLink.map((child) => utils.get(child, relatedIdAttribute)).filter((id) => id !== undefined)\n // e.g. group.user_ids = [1,2,3,...]\n utils.set(this, localKeys, ids)\n // Update (unset) inverse relation\n if (inverseDef.foreignKeys) {\n current.forEach((child) => {\n const relatedId = utils.get(child, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(child) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update inverse relation\n // safeSetLink(child, inverseLocalField, undefined)\n const parents = utils.get(child, inverseLocalField) || []\n // e.g. someUser.groups.remove(group)\n if (id === undefined) {\n utils.remove(parents, (parent) => parent === this)\n } else {\n utils.remove(parents, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n }\n })\n toLink.forEach((child) => {\n // Update (set) inverse relation\n const parents = utils.get(child, inverseLocalField)\n // e.g. someUser.groups.push(group)\n if (id === undefined) {\n utils.noDupeAdd(parents, this, (parent) => parent === this)\n } else {\n utils.noDupeAdd(parents, this, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n })\n }\n } else if (foreignKeys) {\n // e.g. user.groups = someGroups\n // Update (unset) inverse relation\n current.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n // e.g. someGroup.user_ids.remove(user.id)\n utils.remove(ids, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n // e.g. someGroup.users.remove(user)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n // Update (set) inverse relation\n toLink.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n utils.noDupeAdd(ids, id, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n }\n\n this._set(path, toLink)\n return toLink\n }\n }\n } else if (type === hasOneType) {\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n descriptor = {\n get: getter,\n // e.g. user.profile = someProfile\n set (record) {\n const current = this._get(path)\n if (record === current) {\n return current\n }\n const inverseLocalField = def.getInverse(mapper).localField\n // Update (unset) inverse relation\n if (current) {\n safeSetProp(current, foreignKey, undefined)\n self.getCollection(relation).updateIndex(current, updateOpts)\n safeSetLink(current, inverseLocalField, undefined)\n }\n if (record) {\n const relatedId = utils.get(record, def.getRelation().idAttribute)\n // Prefer store record\n if (relatedId !== undefined) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n safeSetLink(this, localField, record)\n\n // Update (set) inverse relation\n safeSetProp(record, foreignKey, utils.get(this, idAttribute))\n self.getCollection(relation).updateIndex(record, updateOpts)\n safeSetLink(record, inverseLocalField, this)\n } else {\n // Unset locals\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n }\n\n if (descriptor) {\n descriptor.enumerable = def.enumerable === undefined ? false : def.enumerable\n if (def.get) {\n let origGet = descriptor.get\n descriptor.get = function () {\n return def.get(def, this, (...args) => origGet.apply(this, args))\n }\n }\n if (def.set) {\n let origSet = descriptor.set\n descriptor.set = function (related) {\n return def.set(def, this, related, (value) => origSet.call(this, value === undefined ? related : value))\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, localField, descriptor)\n }\n })\n\n return mapper\n },\n\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~beforeDestroyListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroy\n * @see DataStore~beforeDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback DataStore~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see DataStore#event:beforeDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~afterDestroyListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroy\n * @see DataStore~afterDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback DataStore~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see DataStore#event:afterDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}. Removes any destroyed record from the\n * in-memory store. Clears out any {@link DataStore#_completedQueries} entries\n * associated with the provided `id`.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is no longer in the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n *\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroy\n * @fires DataStore#afterDestroy\n * @fires DataStore#remove\n * @method DataStore#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#destroy}.\n * @param {Object} [opts] Passed to {@link Mapper#destroy}. See\n * {@link Mapper#destroy} for more configuration options.\n * @returns {Promise} Resolves when the destroy operation completes.\n * @since 3.0.0\n */\n destroy (name, id, opts) {\n opts || (opts = {})\n return Container.prototype.destroy.call(this, name, id, opts).then((result) => {\n const record = this.getCollection(name).remove(id, opts)\n\n if (record && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n utils.set(record, def.localField, undefined)\n })\n }\n\n if (opts.raw) {\n result.data = record\n } else {\n result = record\n }\n delete this._pendingQueries[name][id]\n delete this._completedQueries[name][id]\n return result\n })\n },\n\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroyAll\n * @see DataStore~beforeDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback DataStore~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see DataStore#event:beforeDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~afterDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroyAll\n * @see DataStore~afterDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback DataStore~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see DataStore#event:afterDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}. Removes any destroyed records from\n * the in-memory store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is gone from the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroyAll\n * @fires DataStore#afterDestroyAll\n * @fires DataStore#remove\n * @method DataStore#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper#destroyAll}.\n * @param {Object} [opts] Passed to {@link Mapper#destroyAll}. See\n * {@link Mapper#destroyAll} for more configuration options.\n * @returns {Promise} Resolves when the delete completes.\n * @since 3.0.0\n */\n destroyAll (name, query, opts) {\n opts || (opts = {})\n return Container.prototype.destroyAll.call(this, name, query, opts).then((result) => {\n const records = this.getCollection(name).removeAll(query, opts)\n\n if (records && records.length && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n records.forEach((record) => {\n utils.set(record, def.localField, undefined)\n })\n })\n }\n\n if (opts.raw) {\n result.data = records\n } else {\n result = records\n }\n const hash = this.hashQuery(name, query, opts)\n delete this._pendingQueries[name][hash]\n delete this._completedQueries[name][hash]\n return result\n })\n },\n\n eject (name, id, opts) {\n console.warn('DEPRECATED: \"eject\" is deprecated, use \"remove\" instead')\n return this.remove(name, id, opts)\n },\n\n ejectAll (name, query, opts) {\n console.warn('DEPRECATED: \"ejectAll\" is deprecated, use \"removeAll\" instead')\n return this.removeAll(name, query, opts)\n },\n\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~beforeFindListener} for how to listen for this event.\n *\n * @event DataStore#beforeFind\n * @see DataStore~beforeFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback DataStore~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see DataStore#event:beforeFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~afterFindListener} for how to listen for this event.\n *\n * @event DataStore#afterFind\n * @see DataStore~afterFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback DataStore~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see DataStore#event:afterFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}. Adds any found record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /book/1234\n * store.find('book', 1234).then((book) => {\n * // The book record is now in the in-memory store\n * console.log(store.get('book', 1234) === book) // true\n * })\n *\n * @fires DataStore#beforeFind\n * @fires DataStore#afterFind\n * @fires DataStore#add\n * @method DataStore#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#find}.\n * @param {Object} [opts] Passed to {@link Mapper#find}.\n * @param {boolean|Function} [opts.usePendingFind] See {@link DataStore#usePendingFind}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n find (name, id, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const pendingQuery = this._pendingQueries[name][id]\n const usePendingFind = opts.usePendingFind === undefined ? this.usePendingFind : opts.usePendingFind\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFind) ? usePendingFind.call(this, name, id, opts) : usePendingFind)) {\n return pendingQuery\n }\n const item = this.cachedFind(name, id, opts)\n let promise\n\n if (opts.force || !item) {\n promise = this._pendingQueries[name][id] = Container.prototype.find.call(this, name, id, opts).then((result) => {\n delete this._pendingQueries[name][id]\n result = this._end(name, result, opts)\n this.cacheFind(name, result, id, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][id]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(item)\n }\n return promise\n },\n\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~beforeFindAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeFindAll\n * @see DataStore~beforeFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback DataStore~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see DataStore#event:beforeFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~afterFindAllListener} for how to listen for this event.\n *\n * @event DataStore#afterFindAll\n * @see DataStore~afterFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback DataStore~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see DataStore#event:afterFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#findAll}. Adds any found records to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('movie')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /movie?rating=PG\n * store.find('movie', { rating: 'PG' }).then((movies) => {\n * // The movie records are now in the in-memory store\n * console.log(store.filter('movie'))\n * })\n *\n * @fires DataStore#beforeFindAll\n * @fires DataStore#afterFindAll\n * @fires DataStore#add\n * @method DataStore#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper.findAll}.\n * @param {Object} [opts] Passed to {@link Mapper.findAll}.\n * @param {boolean|Function} [opts.usePendingFindAll] See {@link DataStore#usePendingFindAll}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n findAll (name, query, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const hash = this.hashQuery(name, query, opts)\n const pendingQuery = this._pendingQueries[name][hash]\n const usePendingFindAll = opts.usePendingFindAll === undefined ? this.usePendingFindAll : opts.usePendingFindAll\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFindAll) ? usePendingFindAll.call(this, name, query, opts) : usePendingFindAll)) {\n return pendingQuery\n }\n\n const items = this.cachedFindAll(name, hash, opts)\n let promise\n\n if (opts.force || !items) {\n promise = this._pendingQueries[name][hash] = Container.prototype.findAll.call(this, name, query, opts).then((result) => {\n delete this._pendingQueries[name][hash]\n result = this._end(name, result, opts)\n this.cacheFindAll(name, result, hash, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][hash]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(items)\n }\n return promise\n },\n\n /**\n * Return the {@link LinkedCollection} with the given name, if for some\n * reason you need a direct reference to the collection.\n *\n * @method DataStore#getCollection\n * @param {string} name Name of the {@link LinkedCollection} to retrieve.\n * @returns {LinkedCollection}\n * @since 3.0.0\n * @throws {Error} Thrown if the specified {@link LinkedCollection} does not\n * exist.\n */\n getCollection (name) {\n const collection = this._collections[name]\n if (!collection) {\n throw utils.err(`${DOMAIN}#getCollection`, name)(404, 'collection')\n }\n return collection\n },\n\n /**\n * Hashing function used to cache {@link DataStore#find} and\n * {@link DataStore#findAll} requests. This method simply JSONifies the\n * `query` argument passed to {@link DataStore#find} or\n * {@link DataStore#findAll}.\n *\n * Override this method for custom hashing behavior.\n * @method DataStore#hashQuery\n * @param {string} name The `name` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @param {Object} query The `query` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @returns {string} The JSONified `query`.\n * @since 3.0.0\n */\n hashQuery (name, query, opts) {\n return utils.toJson(query)\n },\n\n inject (name, records, opts) {\n console.warn('DEPRECATED: \"inject\" is deprecated, use \"add\" instead')\n return this.add(name, records, opts)\n },\n\n /**\n * Wrapper for {@link LinkedCollection#remove}. Removes the specified\n * {@link Record} from the store.\n *\n * @example DataStore#remove\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n * console.log(store.getAll('book').length)\n * store.add('book', { id: 1234 })\n * console.log(store.getAll('book').length)\n * store.remove('book', 1234)\n * console.log(store.getAll('book').length)\n *\n * @fires DataStore#remove\n * @method DataStore#remove\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {string|number} id The primary key of the {@link Record} to remove.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n remove (name, id, opts) {\n const record = this.getCollection(name).remove(id, opts)\n if (record) {\n this.removeRelated(name, [record], opts)\n }\n return record\n },\n\n /**\n * Wrapper for {@link LinkedCollection#removeAll}. Removes the selected\n * {@link Record}s from the store.\n *\n * @example DataStore#removeAll\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('movie')\n * console.log(store.getAll('movie').length)\n * store.add('movie', [{ id: 3, rating: 'R' }, { id: 4, rating: 'PG-13' })\n * console.log(store.getAll('movie').length)\n * store.removeAll('movie', { rating: 'R' })\n * console.log(store.getAll('movie').length)\n *\n * @fires DataStore#remove\n * @method DataStore#removeAll\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}s, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n removeAll (name, query, opts) {\n const records = this.getCollection(name).removeAll(query, opts)\n if (records.length) {\n this.removeRelated(name, records, opts)\n }\n return records\n },\n\n /**\n * Remove from the store {@link Record}s that are related to the provided\n * {@link Record}(s).\n *\n * @fires DataStore#remove\n * @method DataStore#removeRelated\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Record|Record[]} records {@link Record}s whose relations are to be\n * removed.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record}(s) to remove\n * from the store.\n * @since 3.0.0\n */\n removeRelated (name, records, opts) {\n if (!utils.isArray(records)) {\n records = [records]\n }\n utils.forEachRelation(this.getMapper(name), opts, (def, optsCopy) => {\n records.forEach((record) => {\n let relatedData\n let query\n if (def.foreignKey && (def.type === hasOneType || def.type === hasManyType)) {\n query = { [def.foreignKey]: def.getForeignKey(record) }\n } else if (def.type === hasManyType && def.localKeys) {\n query = {\n where: {\n [def.getRelation().idAttribute]: {\n 'in': utils.get(record, def.localKeys)\n }\n }\n }\n } else if (def.type === hasManyType && def.foreignKeys) {\n query = {\n where: {\n [def.foreignKeys]: {\n 'contains': def.getForeignKey(record)\n }\n }\n }\n } else if (def.type === belongsToType) {\n relatedData = this.remove(def.relation, def.getForeignKey(record), optsCopy)\n }\n if (query) {\n relatedData = this.removeAll(def.relation, query, optsCopy)\n }\n if (relatedData) {\n if (utils.isArray(relatedData) && !relatedData.length) {\n return\n }\n if (def.type === hasOneType) {\n relatedData = relatedData[0]\n }\n def.setLocalField(record, relatedData)\n }\n })\n })\n },\n\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~beforeUpdateListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdate\n * @see DataStore~beforeUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback DataStore~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see DataStore#event:beforeUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~afterUpdateListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdate\n * @see DataStore~afterUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback DataStore~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see DataStore#event:afterUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}. Adds the updated {@link Record} to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post/1234 {\"status\":\"published\"}\n * store.update('post', 1, { status: 'published' }).then((post) => {\n * // The post record has also been updated in the in-memory store\n * console.log(store.get('post', 1234))\n * })\n *\n * @fires DataStore#beforeUpdate\n * @fires DataStore#afterUpdate\n * @fires DataStore#add\n * @method DataStore#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#update}.\n * @param {Object} record Passed to {@link Mapper#update}.\n * @param {Object} [opts] Passed to {@link Mapper#update}. See\n * {@link Mapper#update} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n update (name, id, record, opts) {\n opts || (opts = {})\n return Container.prototype.update.call(this, name, id, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateAll\n * @see DataStore~beforeUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback DataStore~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see DataStore#event:beforeUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~afterUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateAll\n * @see DataStore~afterUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback DataStore~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see DataStore#event:afterUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post?author_id=1234 {\"status\":\"published\"}\n * store.updateAll('post', { author_id: 1234 }, { status: 'published' }).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.filter('posts', { author_id: 1234 }))\n * })\n *\n * @fires DataStore#beforeUpdateAll\n * @fires DataStore#afterUpdateAll\n * @fires DataStore#add\n * @method DataStore#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props Passed to {@link Mapper#updateAll}.\n * @param {Object} [query] Passed to {@link Mapper#updateAll}.\n * @param {Object} [opts] Passed to {@link Mapper#updateAll}. See\n * {@link Mapper#updateAll} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateAll (name, props, query, opts) {\n opts || (opts = {})\n return Container.prototype.updateAll.call(this, name, query, props, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateMany\n * @see DataStore~beforeUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback DataStore~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see DataStore#event:beforeUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~afterUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateMany\n * @see DataStore~afterUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback DataStore~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see DataStore#event:afterUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post [{\"id\":3,status\":\"published\"},{\"id\":4,status\":\"published\"}]\n * store.updateMany('post', [\n * { id: 3, status: 'published' },\n * { id: 4, status: 'published' }\n * ]).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.getAll('post', 3, 4))\n * })\n *\n * @fires DataStore#beforeUpdateMany\n * @fires DataStore#afterUpdateMany\n * @fires DataStore#add\n * @method DataStore#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records Passed to {@link Mapper#updateMany}.\n * @param {Object} [opts] Passed to {@link Mapper#updateMany}. See\n * {@link Mapper#updateMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateMany (name, records, opts) {\n opts || (opts = {})\n return Container.prototype.updateMany.call(this, name, records, opts)\n .then((result) => this._end(name, result, opts))\n }\n}\n\nproxiedCollectionMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getCollection(name)[method](...args)\n }\n})\n\nexport default Container.extend(props)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link DataStore~changeListener} on how to listen for this event.\n *\n * @event DataStore#change\n * @see DataStore~changeListener\n */\n\n/**\n * Callback signature for the {@link DataStore#event:change} event.\n *\n * @example\n * function onChange (mapperName, record, changes) {\n * // do something\n * }\n * store.on('change', onChange)\n *\n * @callback DataStore~changeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record} record The Record that changed.\n * @param {Object} changes The changes.\n * @see DataStore#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the in-memory store. See\n * {@link DataStore~addListener} on how to listen for this event.\n *\n * @event DataStore#add\n * @see DataStore~addListener\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n */\n\n/**\n * Callback signature for the {@link DataStore#event:add} event.\n *\n * @example\n * function onAdd (mapperName, recordOrRecords) {\n * // do something\n * }\n * store.on('add', onAdd)\n *\n * @callback DataStore~addListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} The Record or Records that were added.\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the in-memory store. See\n * {@link DataStore~removeListener} for how to listen for this event.\n *\n * @event DataStore#remove\n * @see DataStore~removeListener\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n */\n\n/**\n * Callback signature for the {@link DataStore#event:remove} event.\n *\n * @example\n * function onRemove (mapperName, recordsOrRecords) {\n * // do something\n * }\n * store.on('remove', onRemove)\n *\n * @callback DataStore~removeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} Record or Records that were removed.\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this DataStore:\n * @example DataStore.extend\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomDataStoreClass extends DataStore {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customDataStore = new CustomDataStoreClass()\n * console.log(customDataStore.foo())\n * console.log(CustomDataStoreClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherDataStoreClass = DataStore.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherDataStore = new OtherDataStoreClass()\n * console.log(otherDataStore.foo())\n * console.log(OtherDataStoreClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherDataStoreClass () {\n * DataStore.call(this)\n * this.created_at = new Date().getTime()\n * }\n * DataStore.extend({\n * constructor: AnotherDataStoreClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherDataStore = new AnotherDataStoreClass()\n * console.log(anotherDataStore.created_at)\n * console.log(anotherDataStore.foo())\n * console.log(AnotherDataStoreClass.beep())\n *\n * @method DataStore.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this DataStore class.\n * @since 3.0.0\n */\n","/**\n * Registered as `js-data` in NPM and Bower.\n *\n * Also available from CDN.JS and JSDelivr.\n *\n * @module js-data\n *\n * @example Install from NPM\n * npm i --save js-data@beta\n * @example Install from Bower\n * bower i --save js-data@3.0.0-beta.1\n * @example Install from CDN.JS\n * \n * @example Install from JSDelivr\n * \n * @example Load into your app via script tag\n * \n * \n * @example Load into your app via CommonJS\n * var JSData = require('js-data');\n * @example Load into your app via ES2015 Modules\n * import * as JSData from 'js-data';\n * @example Load into your app via AMD\n * define('myApp', ['js-data'], function (JSData) { ... })\n */\n\n/**\n * Describes the version of this `JSData` object.\n *\n * @example\n * console.log(JSData.version.full) // \"3.0.0-beta.1\"\n *\n * @name version\n * @memberof module:js-data\n * @property {string} full The full semver value.\n * @property {number} major The major version number.\n * @property {number} minor The minor version number.\n * @property {number} patch The patch version number.\n * @property {(string|boolean)} alpha The alpha version value, otherwise `false`\n * if the current version is not alpha.\n * @property {(string|boolean)} beta The beta version value, otherwise `false`\n * if the current version is not beta.\n * @since 2.0.0\n * @type {Object}\n */\nexport const version = '<%= version %>'\n\n/**\n * JSData's utility methods.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @name module:js-data.utils\n * @property {Function} Promise See {@link utils.Promise}.\n * @see utils\n * @since 3.0.0\n * @type {Object}\n */\nimport utils from './utils'\n\n/**\n * JSData's {@link Collection} class.\n *\n * @example\n * import {Collection} from 'js-data'\n * const collection = new Collection()\n *\n * @name module:js-data.Collection\n * @see Collection\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#collection\",\"Components of JSData: Collection\"]\n * @type {Constructor}\n */\nimport Collection from './Collection'\n\n/**\n * JSData's {@link Component} class. Most components in JSData extend this\n * class.\n *\n * @example\n * import {Component} from 'js-data'\n * // Make a custom component.\n * const MyComponent = Component.extend({\n * myMethod (someArg) { ... }\n * })\n *\n * @name module:js-data.Component\n * @see Component\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Component from './Component'\n\n/**\n * JSData's {@link Container} class. Defines and manages {@link Mapper}s. Used\n * in Node.js and in the browser, though in the browser you may want to use\n * {@link DataStore} instead.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n *\n * @name module:js-data.Container\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#container\",\"Components of JSData: Container\"]\n * @type {Constructor}\n */\nimport {Container} from './Container'\n\n/**\n * JSData's {@link DataStore} class. Primarily for use in the browser. In\n * Node.js you probably want to use {@link Container} instead.\n *\n * @example\n * import {DataStore} from 'js-data'\n * const store = new DataStore()\n *\n * @name module:js-data.DataStore\n * @see DataStore\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @type {Constructor}\n */\nimport DataStore from './DataStore'\n\n/**\n * JSData's {@link Index} class, based on [mindex]{@link https://github.com/internalfx/mindex}.\n *\n * @name module:js-data.Index\n * @see Index\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Index from '../lib/mindex/index'\n\n/**\n * JSData's {@link LinkedCollection} class. Used by the {@link DataStore}\n * component. If you need to create a collection manually, you should probably\n * use the {@link Collection} class.\n *\n * @name module:js-data.LinkedCollection\n * @see DataStore\n * @see LinkedCollection\n * @since 3.0.0\n * @type {Constructor}\n */\nimport LinkedCollection from './LinkedCollection'\n\n/**\n * JSData's {@link Mapper} class. The core of the ORM.\n *\n * @example Recommended use\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @example Create Mapper manually\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @name module:js-data.Mapper\n * @see Container\n * @see Mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @type {Constructor}\n */\nimport Mapper from './Mapper'\n\n/**\n * JSData's {@link Query} class. Used by the {@link Collection} component.\n *\n * @name module:js-data.Query\n * @see Query\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Query from './Query'\n\n/**\n * JSData's {@link Record} class.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n *\n * @name module:js-data.Record\n * @see Record\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#record\",\"Components of JSData: Record\"]\n * @type {Constructor}\n */\nimport Record from './Record'\n\n/**\n * JSData's {@link Schema} class. Implements http://json-schema.org/draft-04.\n *\n * @example\n * import {Container, Schema} from 'js-data'\n * const userSchema = new Schema({\n * properties: {\n * id: { type: 'string' },\n * name: { type: 'string' }\n * }\n * })\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: userSchema\n * })\n *\n * @name module:js-data.Schema\n * @see Schema\n * @see http://json-schema.org/\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#schema\",\"Components of JSData: schema\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/schemas\",\"JSData's Schema Syntax\"]\n * @type {Constructor}\n */\nimport Schema from './Schema'\n\n/**\n * JSData's {@link Settable} class.\n *\n * @example\n * import {Settable} from 'js-data'\n * const obj = new Settable()\n * obj.set('secret', 'value')\n * console.log(JSON.stringify(obj)) // {}\n *\n * @name module:js-data.Settable\n * @see Settable\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Settable from './Settable'\n\nexport * from './decorators'\n\nexport {\n Collection,\n Component,\n Container,\n DataStore,\n Index,\n LinkedCollection,\n Mapper,\n Query,\n Record,\n Schema,\n Settable,\n utils\n}\n"],"names":["DOMAIN","Component","Query","Schema","Record","_belongsTo","_hasMany","_hasOne","Mapper","Collection","LinkedCollection","props"],"mappings":"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"} \ No newline at end of file diff --git a/dist/js-data.js b/dist/js-data.js index 105935ae..e72d980e 100644 --- a/dist/js-data.js +++ b/dist/js-data.js @@ -1,6 +1,6 @@ /*! * js-data -* @version 3.0.0-rc.3 - Homepage +* @version 3.0.0-rc.4 - Homepage * @author js-data project authors * @copyright (c) 2014-2016 js-data project authors * @license MIT @@ -740,10 +740,10 @@ } else if (classProps.strictEs6Class) { _subClass.__proto__ = superClass; // eslint-disable-line } else { - utils.forOwn(superClass, function (value, key) { - _subClass[key] = value; - }); - } + utils.forOwn(superClass, function (value, key) { + _subClass[key] = value; + }); + } if (!_subClass.hasOwnProperty('__super__')) { Object.defineProperty(_subClass, '__super__', { configurable: true, @@ -1698,6 +1698,22 @@ } }; + var safeSetProp = function safeSetProp(record, field, value) { + if (record && record._set) { + record._set('props.' + field, value); + } else { + utils.set(record, field, value); + } + }; + + var safeSetLink = function safeSetLink(record, field, value) { + if (record && record._set) { + record._set('links.' + field, value); + } else { + utils.set(record, field, value); + } + }; + /** * A base class which gives instances private properties. * @@ -4513,1307 +4529,1406 @@ * @since 3.0.0 */ - var DOMAIN$5 = 'Record'; + // TODO: remove this when the rest of the project is cleaned + var belongsToType = 'belongsTo'; + var hasManyType = 'hasMany'; + var hasOneType = 'hasOne'; - var superMethod = function superMethod(mapper, name) { - var store = mapper.datastore; - if (store && store[name]) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } + var DOMAIN$6 = 'Relation'; - return store[name].apply(store, [mapper.name].concat(args)); - }; - } - return mapper[name].bind(mapper); - }; + function Relation(relatedMapper) { + var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - /** - * js-data's Record class. An instance of `Record` corresponds to an in-memory - * representation of a single row or document in a database, Firebase, - * localstorage, etc. Basically, a `Record` instance represents whatever kind of - * entity in your persistence layer that has a primary key. - * - * ```javascript - * import {Record} from 'js-data' - * ``` - * - * @example Record#constructor - * // Normally you would do: import {Record} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Record} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * // Instantiate a plain record - * let record = new Record() - * console.log('record: ' + JSON.stringify(record)) - * - * // You can supply properties on instantiation - * record = new Record({ name: 'John' }) - * console.log('record: ' + JSON.stringify(record)) - * - * @example Record#constructor2 - * // Normally you would do: import {Mapper} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Mapper} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * // Instantiate a record that's associated with a Mapper: - * const UserMapper = new Mapper({ name: 'user' }) - * const User = UserMapper.recordClass - * const user = UserMapper.createRecord({ name: 'John' }) - * const user2 = new User({ name: 'Sally' }) - * console.log('user: ' + JSON.stringify(user)) - * console.log('user2: ' + JSON.stringify(user2)) - * - * @example Record#constructor3 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * - * // Instantiate a record that's associated with a store's Mapper - * const user = store.createRecord('user', { name: 'John' }) - * console.log('user: ' + JSON.stringify(user)) - * - * @example Record#constructor4 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * // Validate on instantiation - * const user = store.createRecord('user', { name: 1234 }) - * console.log('user: ' + JSON.stringify(user)) - * - * @example Record#constructor5 - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * // Skip validation on instantiation - * const user = store.createRecord('user', { name: 1234 }, { noValidate: true }) - * console.log('user: ' + JSON.stringify(user)) - * console.log('user.isValid(): ' + user.isValid()) - * - * @class Record - * @extends Component - * @param {Object} [props] The initial properties of the new Record instance. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.noValidate=false] Whether to skip validation on the - * initial properties. - * @since 3.0.0 - */ - function Record(props, opts) { - utils.classCallCheck(this, Record); - Settable.call(this); - props || (props = {}); - opts || (opts = {}); - var _set = this._set; - // TODO: Optimize these strings - _set('creating', true); - if (opts.noValidate) { - _set('noValidate', true); - } - // Set the idAttribute value first, if it exists. - var mapper = this.constructor.mapper; - var id = mapper ? utils.get(props, mapper.idAttribute) : undefined; - if (id !== undefined) { - utils.set(this, mapper.idAttribute, id); + utils.classCallCheck(this, Relation); + + options.type = this.constructor.TYPE_NAME; + this.validateOptions(relatedMapper, options); + + if ((typeof relatedMapper === 'undefined' ? 'undefined' : _typeof(relatedMapper)) === 'object') { + Object.defineProperty(this, 'relatedMapper', { value: relatedMapper }); } - utils.fillIn(this, props); - _set('creating', false); - _set('noValidate', false); - _set('previous', utils.plainCopy(props)); + + Object.defineProperty(this, 'inverse', { writable: true }); + utils.fillIn(this, options); } - var Record$1 = Component$1.extend({ - constructor: Record, + Relation.extend = utils.extend; - /** - * Returns the {@link Mapper} paired with this record's class, if any. - * - * @method Record#_mapper - * @returns {Mapper} The {@link Mapper} paired with this record's class, if any. - * @since 3.0.0 - */ - _mapper: function _mapper() { - var mapper = this.constructor.mapper; - if (!mapper) { - throw utils.err(DOMAIN$5 + '#_mapper', '')(404, 'mapper'); - } - return mapper; + utils.addHiddenPropsToTarget(Relation.prototype, { + get canAutoAddLinks() { + return this.add === undefined || !!this.add; }, + get relatedCollection() { + return this.mapper.datastore.getCollection(this.relation); + }, - /** - * Lifecycle hook. - * - * @method Record#afterLoadRelations - * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. - * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. - * @since 3.0.0 - */ - afterLoadRelations: function afterLoadRelations() {}, + validateOptions: function validateOptions(related, opts) { + var DOMAIN_ERR = 'new ' + DOMAIN$6; + var localField = opts.localField; + if (!localField) { + throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField); + } - /** - * Lifecycle hook. - * - * @method Record#beforeLoadRelations - * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. - * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. - * @since 3.0.0 - */ - beforeLoadRelations: function beforeLoadRelations() {}, + var foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey; + if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) { + throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey); + } + if (utils.isString(related)) { + opts.relation = related; + if (!utils.isFunction(opts.getRelation)) { + throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation); + } + } else if (related) { + opts.relation = related.name; + } else { + throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related); + } + }, + assignTo: function assignTo(mapper) { + this.name = mapper.name; + Object.defineProperty(this, 'mapper', { value: mapper }); - /** - * Return the change history of this record since it was instantiated or - * {@link Record#commit} was called. - * - * @method Record#changeHistory - * @since 3.0.0 - */ - changeHistory: function changeHistory() { - return (this._get('history') || []).slice(); + mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] }); + mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] }); + mapper.relationList.push(this); + mapper.relationFields.push(this.localField); + }, + canFindLinkFor: function canFindLinkFor() { + return !!(this.foreignKey || this.localKey); + }, + getRelation: function getRelation() { + return this.relatedMapper; + }, + getForeignKey: function getForeignKey(record) { + return utils.get(record, this.mapper.idAttribute); }, + setForeignKey: function setForeignKey(record, relatedRecord) { + if (!record || !relatedRecord) { + return; + } - - /** - * Return changes to this record since it was instantiated or - * {@link Record#commit} was called. - * - * @example Record#changes - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user changes: ' + JSON.stringify(user.changes())) - * user.name = 'John' - * console.log('user changes: ' + JSON.stringify(user.changes())) - * - * @method Record#changes - * @param [opts] Configuration options. - * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. - * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. - * @returns {Object} Object describing the changes to this record since it was - * instantiated or its {@link Record#commit} method was last called. - * @since 3.0.0 - */ - changes: function changes(opts) { - opts || (opts = {}); - return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); + this._setForeignKey(record, relatedRecord); }, + _setForeignKey: function _setForeignKey(record, relatedRecords) { + var _this = this; + var idAttribute = this.mapper.idAttribute; - /** - * Make the record's current in-memory state it's only state, with any - * previous property values being set to current values. - * - * @example Record#commit - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user hasChanges: ' + user.hasChanges()) - * user.name = 'John' - * console.log('user hasChanges: ' + user.hasChanges()) - * user.commit() - * console.log('user hasChanges: ' + user.hasChanges()) - * - * @method Record#commit - * @since 3.0.0 - */ - commit: function commit() { - this._set('changed'); // unset - this._set('history', []); // clear history - this._set('previous', utils.plainCopy(this)); + if (!utils.isArray(relatedRecords)) { + relatedRecords = [relatedRecords]; + } + + relatedRecords.forEach(function (relatedRecord) { + utils.set(relatedRecord, _this.foreignKey, utils.get(record, idAttribute)); + }); + }, + getLocalField: function getLocalField(record) { + return utils.get(record, this.localField); + }, + setLocalField: function setLocalField(record, relatedData) { + return utils.set(record, this.localField, relatedData); }, + getInverse: function getInverse(mapper) { + if (!this.inverse) { + this.findInverseRelation(mapper); + } + return this.inverse; + }, + findInverseRelation: function findInverseRelation(mapper) { + var _this2 = this; - /** - * Call {@link Mapper#destroy} using this record's primary key. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('user') - * store.find('user', 1234).then((user) => { - * console.log(user.id) // 1234 - * - * // Destroy this user from the database - * return user.destroy() - * }) - * - * @method Record#destroy - * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}. - * @returns {Promise} The result of calling {@link Mapper#destroy} with the - * primary key of this record. - * @since 3.0.0 - */ - destroy: function destroy(opts) { - opts || (opts = {}); - var mapper = this._mapper(); - return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts); + this.getRelation().relationList.forEach(function (def) { + if (def.getRelation() === mapper && _this2.isInversedTo(def)) { + _this2.inverse = def; + return true; + } + }); + }, + isInversedTo: function isInversedTo(def) { + return !def.foreignKey || def.foreignKey === this.foreignKey; }, + addLinkedRecords: function addLinkedRecords(records) { + var _this3 = this; + var datastore = this.mapper.datastore; - /** - * Return the value at the given path for this instance. - * - * @example Record#get - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * - * const user = store.createRecord('user', { name: 'Bob' }) - * console.log('user.get("name"): ' + user.get('name')) - * - * @method Record#get - * @param {string} key Path of value to retrieve. - * @returns {*} Value at path. - * @since 3.0.0 - */ - 'get': function get(key) { - return utils.get(this, key); - }, + records.forEach(function (record) { + var relatedData = _this3.getLocalField(record); + if (utils.isFunction(_this3.add)) { + relatedData = _this3.add(datastore, _this3, record); + } else if (relatedData) { + relatedData = _this3.linkRecord(record, relatedData); + } - /** - * Return whether this record has changed since it was instantiated or - * {@link Record#commit} was called. - * - * @example Record#hasChanges - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user') - * console.log('user hasChanges: ' + user.hasChanges()) - * user.name = 'John' - * console.log('user hasChanges: ' + user.hasChanges()) - * user.commit() - * console.log('user hasChanges: ' + user.hasChanges()) - * - * @method Record#hasChanges - * @param [opts] Configuration options. - * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. - * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. - * @returns {boolean} Return whether the record has changed since it was - * instantiated or since its {@link Record#commit} method was called. - * @since 3.0.0 - */ - hasChanges: function hasChanges(opts) { - var quickHasChanges = !!(this._get('changed') || []).length; - return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); + var isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length; + + if (isEmptyLinks && _this3.canFindLinkFor(record)) { + relatedData = _this3.findExistingLinksFor(record); + } + + if (relatedData) { + _this3.setLocalField(record, relatedData); + } + }); + }, + removeLinkedRecords: function removeLinkedRecords(relatedMapper, records) { + var localField = this.localField; + records.forEach(function (record) { + utils.set(record, localField, undefined); + }); }, + linkRecord: function linkRecord(record, relatedRecord) { + var relatedId = utils.get(relatedRecord, this.mapper.idAttribute); + if (relatedId === undefined) { + var unsaved = this.relatedCollection.unsaved(); + if (unsaved.indexOf(relatedRecord) === -1) { + if (this.canAutoAddLinks) { + relatedRecord = this.relatedCollection.add(relatedRecord); + } + } + } else { + if (relatedRecord !== this.relatedCollection.get(relatedId)) { + this.setForeignKey(record, relatedRecord); - /** - * Return whether the record is unsaved. Records that have primary keys are - * considered "saved". Records without primary keys are considered "unsaved". - * - * @example Record#isNew - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * id: 1234 - * }) - * const user2 = store.createRecord('user') - * console.log('user isNew: ' + user.isNew()) // false - * console.log('user2 isNew: ' + user2.isNew()) // true - * - * @method Record#isNew - * @returns {boolean} Whether the record is unsaved. - * @since 3.0.0 - */ - isNew: function isNew(opts) { - return utils.get(this, this._mapper().idAttribute) === undefined; + if (this.canAutoAddLinks) { + relatedRecord = this.relatedCollection.add(relatedRecord); + } + } + } + + return relatedRecord; }, - /** - * Return whether the record in its current state passes validation. - * - * @example Record#isValid - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * const user = store.createRecord('user', { - * name: 1234 - * }, { - * noValidate: true // this allows us to put the record into an invalid state - * }) - * console.log('user isValid: ' + user.isValid()) - * user.name = 'John' - * console.log('user isValid: ' + user.isValid()) - * - * @method Record#isValid - * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. - * @returns {boolean} Whether the record in its current state passes - * validation. - * @since 3.0.0 - */ - isValid: function isValid(opts) { - return !this._mapper().validate(this, opts); + // e.g. user hasMany post via "foreignKey", so find all posts of user + findExistingLinksByForeignKey: function findExistingLinksByForeignKey(id) { + if (id === undefined || id === null) { + return; + } + return this.relatedCollection.filter(defineProperty({}, this.foreignKey, id)); + } + }); + + var BelongsToRelation = Relation.extend({ + getForeignKey: function getForeignKey(record) { + return utils.get(record, this.foreignKey); }, + _setForeignKey: function _setForeignKey(record, relatedRecord) { + utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute)); + }, + findExistingLinksFor: function findExistingLinksFor(record) { + // console.log('\tBelongsTo#findExistingLinksFor', record) + if (!record) { + return; + } + var relatedId = utils.get(record, this.foreignKey); + if (relatedId !== undefined && relatedId !== null) { + return this.relatedCollection.get(relatedId); + } + } + }, { + TYPE_NAME: 'belongsTo' + }); + var HasManyRelation = Relation.extend({ + validateOptions: function validateOptions(related, opts) { + Relation.prototype.validateOptions.call(this, related, opts); - /** - * Lazy load relations of this record, to be attached to the record once their - * loaded. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('user', { - * relations: { - * hasMany: { - * post: { - * localField: 'posts', - * foreignKey: 'user_id' - * } - * } - * } - * }) - * store.defineMapper('post', { - * relations: { - * belongsTo: { - * user: { - * localField: 'user', - * foreignKey: 'user_id' - * } - * } - * } - * }) - * store.find('user', 1234).then((user) => { - * console.log(user.id) // 1234 - * - * // Load the user's post relations - * return user.loadRelations(['post']) - * }).then((user) => { - * console.log(user.posts) // [{...}, {...}, ...] - * }) - * - * @method Record#loadRelations - * @param {string[]} [relations] List of relations to load. Can use localField - * names or Mapper names to pick relations. - * @param {Object} [opts] Configuration options. - * @returns {Promise} Resolves with the record, with the loaded relations now - * attached. - * @since 3.0.0 - */ - loadRelations: function loadRelations(relations, opts) { - var _this = this; + var localKeys = opts.localKeys; + var foreignKeys = opts.foreignKeys; + var foreignKey = opts.foreignKey; - var op = void 0; - var mapper = this._mapper(); - // Default values for arguments - relations || (relations = []); - if (utils.isString(relations)) { - relations = [relations]; + if (!foreignKey && !localKeys && !foreignKeys) { + throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey); } - opts || (opts = {}); - opts.with = relations; + }, + canFindLinkFor: function canFindLinkFor(record) { + var hasForeignKeys = this.foreignKey || this.foreignKeys; + return !!(hasForeignKeys || this.localKeys && utils.get(record, this.localKeys)); + }, + linkRecord: function linkRecord(record, relatedRecords) { + var _this = this; - // Fill in "opts" with the Model's configuration - utils._(opts, mapper); - opts.adapter = mapper.getAdapterName(opts); + var relatedCollection = this.relatedCollection; + var canAutoAddLinks = this.canAutoAddLinks; + var foreignKey = this.foreignKey; + var unsaved = this.relatedCollection.unsaved(); - // beforeLoadRelations lifecycle hook - op = opts.op = 'beforeLoadRelations'; - return utils.resolve(this[op](relations, opts)).then(function () { - // Now delegate to the adapter - op = opts.op = 'loadRelations'; - mapper.dbg(op, _this, relations, opts); - var tasks = []; - var task = void 0; - utils.forEachRelation(mapper, opts, function (def, optsCopy) { - var relatedMapper = def.getRelation(); - optsCopy.raw = false; - if (utils.isFunction(def.load)) { - task = def.load(mapper, def, _this, opts); - } else if (def.type === 'hasMany' || def.type === 'hasOne') { - if (def.foreignKey) { - task = superMethod(relatedMapper, 'findAll')(defineProperty({}, def.foreignKey, utils.get(_this, mapper.idAttribute)), optsCopy).then(function (relatedData) { - if (def.type === 'hasOne') { - return relatedData.length ? relatedData[0] : undefined; - } - return relatedData; - }); - } else if (def.localKeys) { - task = superMethod(relatedMapper, 'findAll')({ - where: defineProperty({}, relatedMapper.idAttribute, { - 'in': utils.get(_this, def.localKeys) - }) - }); - } else if (def.foreignKeys) { - task = superMethod(relatedMapper, 'findAll')({ - where: defineProperty({}, def.foreignKeys, { - 'contains': utils.get(_this, mapper.idAttribute) - }) - }, opts); - } - } else if (def.type === 'belongsTo') { - var key = utils.get(_this, def.foreignKey); - if (utils.isSorN(key)) { - task = superMethod(relatedMapper, 'find')(key, optsCopy); - } + return relatedRecords.map(function (relatedRecord) { + var relatedId = relatedCollection.recordId(relatedRecord); + + if (relatedId === undefined && unsaved.indexOf(relatedRecord) === -1 || relatedRecord !== relatedCollection.get(relatedId)) { + if (foreignKey) { + // TODO: slow, could be optimized? But user loses hook + _this.setForeignKey(record, relatedRecord); } - if (task) { - task = task.then(function (relatedData) { - def.setLocalField(_this, relatedData); - }); - tasks.push(task); + if (canAutoAddLinks) { + relatedRecord = relatedCollection.add(relatedRecord); } - }); - return Promise.all(tasks); - }).then(function () { - // afterLoadRelations lifecycle hook - op = opts.op = 'afterLoadRelations'; - return utils.resolve(_this[op](relations, opts)).then(function () { - return _this; - }); + } + + return relatedRecord; }); }, + findExistingLinksFor: function findExistingLinksFor(record) { + var id = utils.get(record, this.mapper.idAttribute); + var ids = this.localKeys ? utils.get(record, this.localKeys) : null; + var records = void 0; + if (id !== undefined && this.foreignKey) { + records = this.findExistingLinksByForeignKey(id); + } else if (this.localKeys && ids) { + records = this.findExistingLinksByLocalKeys(ids); + } else if (id !== undefined && this.foreignKeys) { + records = this.findExistingLinksByForeignKeys(id); + } - /** - * Return the properties with which this record was instantiated. - * - * @example Record#previous - * // import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * name: 'William' - * }) - * console.log('user previous: ' + JSON.stringify(user.previous())) - * user.name = 'Bob' - * console.log('user previous: ' + JSON.stringify(user.previous())) - * user.commit() - * console.log('user previous: ' + JSON.stringify(user.previous())) - * - * @method Record#previous - * @param {string} [key] If specified, return just the initial value of the - * given key. - * @returns {Object} The initial properties of this record. - * @since 3.0.0 - */ - previous: function previous(key) { - if (key) { - return this._get('previous.' + key); + if (records && records.length) { + return records; } - return this._get('previous'); }, - /** - * Revert changes to this record back to the properties it had when it was - * instantiated. - * - * @example Record#revert - * // import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * const user = store.createRecord('user', { - * name: 'William' - * }) - * console.log('user: ' + JSON.stringify(user)) - * user.name = 'Bob' - * console.log('user: ' + JSON.stringify(user)) - * user.revert() - * console.log('user: ' + JSON.stringify(user)) - * - * @method Record#revert - * @param {Object} [opts] Configuration options. - * @param {string[]} [opts.preserve] Array of strings or Regular Expressions - * denoting properties that should not be reverted. - * @since 3.0.0 - */ - revert: function revert(opts) { - var _this2 = this; - - var previous = this._get('previous'); - opts || (opts = {}); - opts.preserve || (opts.preserve = []); - utils.forOwn(this, function (value, key) { - if (key !== _this2._mapper().idAttribute && !previous.hasOwnProperty(key) && _this2.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) { - delete _this2[key]; - } + // e.g. user hasMany group via "foreignKeys", so find all users of a group + findExistingLinksByLocalKeys: function findExistingLinksByLocalKeys(ids) { + return this.relatedCollection.filter({ + where: defineProperty({}, this.mapper.idAttribute, { + 'in': ids + }) }); - utils.forOwn(previous, function (value, key) { - if (opts.preserve.indexOf(key) === -1) { - _this2[key] = value; - } - }); - this.commit(); }, - /** - * Delegates to {@link Mapper#create} or {@link Mapper#update}. - * - * @example - * import {Container} from 'js-data' - * import {RethinkDBAdapter} from 'js-data-rethinkdb' - * - * const store = new Container() - * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) - * store.defineMapper('session') - * const session = store.createRecord('session', { topic: 'Node.js' }) - * - * // Create a new record in the database - * session.save().then(() => { - * console.log(session.id) // 1234 - * - * session.skill_level = 'beginner' - * - * // Update the record in the database - * return user.save() - * }) - * - * @method Record#save - * @param {Object} [opts] Configuration options. See {@link Mapper#create} and - * {@link Mapper#update}. - * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`. - * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when - * `opts.changesOnly` is `true`. - * @param {Array} [opts.ignore] Passed to {@link Record#changes} when - * `opts.changesOnly` is `true`. - * @returns {Promise} The result of calling {@link Mapper#create} or - * {@link Mapper#update}. - * @since 3.0.0 - */ - save: function save(opts) { - var _this3 = this; - - opts || (opts = {}); - var mapper = this._mapper(); - var id = utils.get(this, mapper.idAttribute); - var props = this; + // e.g. group hasMany user via "localKeys", so find all groups that own a user + findExistingLinksByForeignKeys: function findExistingLinksByForeignKeys(id) { + return this.relatedCollection.filter({ + where: defineProperty({}, this.foreignKeys, { + 'contains': id + }) + }); + } + }, { + TYPE_NAME: 'hasMany' + }); - var postProcess = function postProcess(result) { - var record = opts.raw ? result.data : result; - if (record) { - utils.deepMixIn(_this3, record); - _this3.commit(); - } - return result; - }; + var HasOneRelation = Relation.extend({ + findExistingLinksFor: function findExistingLinksFor(relatedMapper, record) { + var recordId = utils.get(record, relatedMapper.idAttribute); + var records = this.findExistingLinksByForeignKey(recordId); - if (id === undefined) { - return superMethod(mapper, 'create')(props, opts).then(postProcess); - } - if (opts.changesOnly) { - var changes = this.changes(opts); - props = {}; - utils.fillIn(props, changes.added); - utils.fillIn(props, changes.changed); + if (records && records.length) { + return records[0]; } - return superMethod(mapper, 'update')(id, props, opts).then(postProcess); - }, + } + }, { + TYPE_NAME: 'hasOne' + }); + [BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) { + Relation[RelationType.TYPE_NAME] = function (related, options) { + return new RelationType(related, options); + }; + }); - /** - * Set the value for a given key, or the values for the given keys if "key" is - * an object. Triggers change events on those properties that have `track: true` - * in {@link Mapper#schema}. - * - * @example Record#set - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user') - * - * const user = store.createRecord('user') - * console.log('user: ' + JSON.stringify(user)) - * - * user.set('name', 'Bob') - * console.log('user: ' + JSON.stringify(user)) - * - * user.set({ age: 30, role: 'admin' }) - * console.log('user: ' + JSON.stringify(user)) - * - * @fires Record#change - * @method Record#set - * @param {(string|Object)} key Key to set or hash of key-value pairs to set. - * @param {*} [value] Value to set for the given key. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.silent=false] Whether to trigger change events. - * @since 3.0.0 - */ - 'set': function set(key, value, opts) { - if (utils.isObject(key)) { - opts = value; - } - opts || (opts = {}); - if (opts.silent) { - this._set('silent', true); - } - utils.set(this, key, value); - if (!this._get('eventId')) { - this._set('silent'); // unset - } - }, + /** + * BelongsTo relation decorator. You probably won't use this directly. + * + * @name module:js-data.belongsTo + * @method + * @param {Mapper} related The relation the target belongs to. + * @param {Object} opts Configuration options. + * @param {string} opts.foreignKey The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ + var belongsTo = function belongsTo(related, opts) { + return function (mapper) { + Relation.belongsTo(related, opts).assignTo(mapper); + }; + }; + /** + * HasMany relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasMany + * @method + * @param {Mapper} related The relation of which the target has many. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ + var hasMany = function hasMany(related, opts) { + return function (mapper) { + Relation.hasMany(related, opts).assignTo(mapper); + }; + }; - /** - * Return a plain object representation of this record. If the class from - * which this record was created has a Mapper, then {@link Mapper#toJSON} will - * be called with this record instead. - * - * @example Record#toJSON - * // Normally you would do: import {Container} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Container} = JSData - * console.log('Using JSData v' + JSData.version.full) - * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * - * const user = store.createRecord('user', { - * name: 'John', - * $$hashKey: '1234' - * }) - * console.log('user: ' + JSON.stringify(user.toJSON())) - * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true }))) - * - * @method Record#toJSON - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.strict] Whether to exclude properties that are not - * defined in {@link Mapper#schema}. - * @param {string[]} [opts.with] Array of relation names or relation fields - * to include in the representation. Only available as an option if the class - * from which this record was created has a Mapper and this record resides in - * an instance of {@link DataStore}. - * @returns {Object} Plain object representation of this record. - * @since 3.0.0 - */ - toJSON: function toJSON(opts) { - var _this4 = this; + /** + * HasOne relation decorator. You probably won't use this directly. + * + * @name module:js-data.hasOne + * @method + * @param {Mapper} related The relation of which the target has one. + * @param {Object} opts Configuration options. + * @param {string} [opts.foreignKey] The field that holds the primary key of the + * related record. + * @param {string} opts.localField The field that holds a reference to the + * related record object. + * @returns {Function} Invocation function, which accepts the target as the only + * parameter. + */ + var hasOne = function hasOne(related, opts) { + return function (mapper) { + Relation.hasOne(related, opts).assignTo(mapper); + }; + }; - var mapper = this.constructor.mapper; - if (mapper) { - return mapper.toJSON(this, opts); - } else { - var _ret = function () { - var json = {}; - utils.forOwn(_this4, function (prop, key) { - json[key] = utils.plainCopy(prop); - }); - return { - v: json - }; - }(); + var DOMAIN$5 = 'Record'; - if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; - } - }, + var superMethod = function superMethod(mapper, name) { + var store = mapper.datastore; + if (store && store[name]) { + return function () { + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + return store[name].apply(store, [mapper.name].concat(args)); + }; + } + return mapper[name].bind(mapper); + }; - /** - * Unset the value for a given key. Triggers change events on those properties - * that have `track: true` in {@link Mapper#schema}. + /** + * js-data's Record class. An instance of `Record` corresponds to an in-memory + * representation of a single row or document in a database, Firebase, + * localstorage, etc. Basically, a `Record` instance represents whatever kind of + * entity in your persistence layer that has a primary key. + * + * ```javascript + * import {Record} from 'js-data' + * ``` + * + * @example Record#constructor + * // Normally you would do: import {Record} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Record} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a plain record + * let record = new Record() + * console.log('record: ' + JSON.stringify(record)) + * + * // You can supply properties on instantiation + * record = new Record({ name: 'John' }) + * console.log('record: ' + JSON.stringify(record)) + * + * @example Record#constructor2 + * // Normally you would do: import {Mapper} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Mapper} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * // Instantiate a record that's associated with a Mapper: + * const UserMapper = new Mapper({ name: 'user' }) + * const User = UserMapper.recordClass + * const user = UserMapper.createRecord({ name: 'John' }) + * const user2 = new User({ name: 'Sally' }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user2: ' + JSON.stringify(user2)) + * + * @example Record#constructor3 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user') + * + * // Instantiate a record that's associated with a store's Mapper + * const user = store.createRecord('user', { name: 'John' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor4 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Validate on instantiation + * const user = store.createRecord('user', { name: 1234 }) + * console.log('user: ' + JSON.stringify(user)) + * + * @example Record#constructor5 + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * // Skip validation on instantiation + * const user = store.createRecord('user', { name: 1234 }, { noValidate: true }) + * console.log('user: ' + JSON.stringify(user)) + * console.log('user.isValid(): ' + user.isValid()) + * + * @class Record + * @extends Component + * @param {Object} [props] The initial properties of the new Record instance. + * @param {Object} [opts] Configuration options. + * @param {boolean} [opts.noValidate=false] Whether to skip validation on the + * initial properties. + * @since 3.0.0 + */ + function Record(props, opts) { + utils.classCallCheck(this, Record); + Settable.call(this); + props || (props = {}); + opts || (opts = {}); + var _set = this._set; + // TODO: Optimize these strings + _set('creating', true); + if (opts.noValidate) { + _set('noValidate', true); + } + // Set the idAttribute value first, if it exists. + var mapper = this.constructor.mapper; + var id = mapper ? utils.get(props, mapper.idAttribute) : undefined; + if (id !== undefined) { + utils.set(this, mapper.idAttribute, id); + } + utils.fillIn(this, props); + _set('creating', false); + _set('noValidate', false); + _set('previous', utils.plainCopy(props)); + } + + var Record$1 = Component$1.extend({ + constructor: Record, + + /** + * Returns the {@link Mapper} paired with this record's class, if any. * - * @example Record#unset + * @method Record#_mapper + * @returns {Mapper} The {@link Mapper} paired with this record's class, if any. + * @since 3.0.0 + */ + _mapper: function _mapper() { + var mapper = this.constructor.mapper; + if (!mapper) { + throw utils.err(DOMAIN$5 + '#_mapper', '')(404, 'mapper'); + } + return mapper; + }, + + + /** + * Lifecycle hook. + * + * @method Record#afterLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */ + afterLoadRelations: function afterLoadRelations() {}, + + + /** + * Lifecycle hook. + * + * @method Record#beforeLoadRelations + * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}. + * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}. + * @since 3.0.0 + */ + beforeLoadRelations: function beforeLoadRelations() {}, + + + /** + * Return the change history of this record since it was instantiated or + * {@link Record#commit} was called. + * + * @method Record#changeHistory + * @since 3.0.0 + */ + changeHistory: function changeHistory() { + return (this._get('history') || []).slice(); + }, + + + /** + * Return changes to this record since it was instantiated or + * {@link Record#commit} was called. + * + * @example Record#changes * // Normally you would do: import {Container} from 'js-data' * const JSData = require('js-data@3.0.0-beta.10') * const {Container} = JSData * console.log('Using JSData v' + JSData.version.full) + * * const store = new Container() * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user changes: ' + JSON.stringify(user.changes())) + * user.name = 'John' + * console.log('user changes: ' + JSON.stringify(user.changes())) * - * const user = store.createRecord('user', { - * name: 'John' - * }) - * console.log('user: ' + JSON.stringify(user)) - * - * user.unset('name') - * console.log('user: ' + JSON.stringify(user)) - * - * @method Record#unset - * @param {string} key Key to unset. - * @param {Object} [opts] Configuration options. - * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @method Record#changes + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {Object} Object describing the changes to this record since it was + * instantiated or its {@link Record#commit} method was last called. * @since 3.0.0 */ - unset: function unset(key, opts) { - this.set(key, undefined, opts); + changes: function changes(opts) { + opts || (opts = {}); + return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); }, /** - * Validate this record based on its current properties. + * Make the record's current in-memory state it's only state, with any + * previous property values being set to current values. * - * @example Record#validate + * @example Record#commit * // Normally you would do: import {Container} from 'js-data' * const JSData = require('js-data@3.0.0-beta.10') * const {Container} = JSData * console.log('Using JSData v' + JSData.version.full) + * * const store = new Container() - * store.defineMapper('user', { - * schema: { - * properties: { - * name: { type: 'string' } - * } - * } - * }) - * const user = store.createRecord('user', { - * name: 1234 - * }, { - * noValidate: true // this allows us to put the record into an invalid state - * }) - * console.log('user validation: ' + JSON.stringify(user.validate())) + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) * user.name = 'John' - * console.log('user validation: ' + user.validate()) + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) * - * @method Record#validate - * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. - * @returns {*} Array of errors or `undefined` if no errors. + * @method Record#commit * @since 3.0.0 */ - validate: function validate(opts) { - return this._mapper().validate(this, opts); - } - }); + commit: function commit() { + this._set('changed'); // unset + this._set('history', []); // clear history + this._set('previous', utils.plainCopy(this)); + }, - /** - * Allow records to emit events. - * - * An record's registered listeners are stored in the record's private data. - */ - utils.eventify(Record.prototype, function () { - return this._get('events'); - }, function (value) { - this._set('events', value); - }); - - var DOMAIN$6 = 'Schema'; - - /** - * A function map for each of the seven primitive JSON types defined by the core specification. - * Each function will check a given value and return true or false if the value is an instance of that type. - * ``` - * types.integer(1) // returns true - * types.string({}) // returns false - * ``` - * http://json-schema.org/latest/json-schema-core.html#anchor8 - * @name Schema.types - * @type {Object} - */ - var types = { - array: utils.isArray, - boolean: utils.isBoolean, - integer: utils.isInteger, - 'null': utils.isNull, - number: utils.isNumber, - object: utils.isObject, - string: utils.isString - }; - - /** - * @ignore - */ - var segmentToString = function segmentToString(segment, prev) { - var str = ''; - if (segment) { - if (utils.isNumber(segment)) { - str += '[' + segment + ']'; - } else if (prev) { - str += '.' + segment; - } else { - str += '' + segment; - } - } - return str; - }; - - /** - * @ignore - */ - var makePath = function makePath(opts) { - opts || (opts = {}); - var path = ''; - var segments = opts.path || []; - segments.forEach(function (segment) { - path += segmentToString(segment, path); - }); - path += segmentToString(opts.prop, path); - return path; - }; - - /** - * @ignore - */ - var makeError = function makeError(actual, expected, opts) { - return { - expected: expected, - actual: '' + actual, - path: makePath(opts) - }; - }; - - /** - * @ignore - */ - var addError = function addError(actual, expected, opts, errors) { - errors.push(makeError(actual, expected, opts)); - }; - - /** - * @ignore - */ - var maxLengthCommon = function maxLengthCommon(keyword, value, schema, opts) { - var max = schema[keyword]; - if (value.length > max) { - return makeError(value.length, 'length no more than ' + max, opts); - } - }; - - /** - * @ignore - */ - var minLengthCommon = function minLengthCommon(keyword, value, schema, opts) { - var min = schema[keyword]; - if (value.length < min) { - return makeError(value.length, 'length no less than ' + min, opts); - } - }; - /** - * A map of all object member validation functions for each keyword defined in the JSON Schema. - * @name Schema.validationKeywords - * @type {Object} - */ - var validationKeywords = { /** - * Validates the provided value against all schemas defined in the Schemas `allOf` keyword. - * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value. + * Call {@link Mapper#destroy} using this record's primary key. * - * The value of this keyword MUST be an array. This array MUST have at least one element. - * Each element of this array MUST be a valid JSON Schema. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' * - * see http://json-schema.org/latest/json-schema-validation.html#anchor82 + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user') + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 * - * @name Schema.validationKeywords.allOf - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `allOf` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * // Destroy this user from the database + * return user.destroy() + * }) + * + * @method Record#destroy + * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}. + * @returns {Promise} The result of calling {@link Mapper#destroy} with the + * primary key of this record. + * @since 3.0.0 */ - - allOf: function allOf(value, schema, opts) { - var allErrors = []; - schema.allOf.forEach(function (_schema) { - allErrors = allErrors.concat(_validate(value, _schema, opts) || []); - }); - return allErrors.length ? undefined : allErrors; + destroy: function destroy(opts) { + opts || (opts = {}); + var mapper = this._mapper(); + return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts); }, /** - * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword. - * The instance is valid against this keyword if and only if it is valid against - * at least one of the schemas in this keyword's value. + * Return the value at the given path for this instance. * - * The value of this keyword MUST be an array. This array MUST have at least one element. - * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema. - * see http://json-schema.org/latest/json-schema-validation.html#anchor85 + * @example Record#get + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') * - * @name Schema.validationKeywords.anyOf - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `anyOf` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * const user = store.createRecord('user', { name: 'Bob' }) + * console.log('user.get("name"): ' + user.get('name')) + * + * @method Record#get + * @param {string} key Path of value to retrieve. + * @returns {*} Value at path. + * @since 3.0.0 */ - anyOf: function anyOf(value, schema, opts) { - var validated = false; - var allErrors = []; - schema.anyOf.forEach(function (_schema) { - var errors = _validate(value, _schema, opts); - if (errors) { - allErrors = allErrors.concat(errors); - } else { - validated = true; - } - }); - return validated ? undefined : allErrors; + 'get': function get(key) { + return utils.get(this, key); }, /** - * http://json-schema.org/latest/json-schema-validation.html#anchor70 + * Return whether this record has changed since it was instantiated or + * {@link Record#commit} was called. * - * @name Schema.validationKeywords.dependencies - * @method - * @param {*} value TODO - * @param {Object} schema TODO - * @param {Object} opts TODO + * @example Record#hasChanges + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user') + * console.log('user hasChanges: ' + user.hasChanges()) + * user.name = 'John' + * console.log('user hasChanges: ' + user.hasChanges()) + * user.commit() + * console.log('user hasChanges: ' + user.hasChanges()) + * + * @method Record#hasChanges + * @param [opts] Configuration options. + * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function. + * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore. + * @returns {boolean} Return whether the record has changed since it was + * instantiated or since its {@link Record#commit} method was called. + * @since 3.0.0 */ - dependencies: function dependencies(value, schema, opts) { - // TODO + hasChanges: function hasChanges(opts) { + var quickHasChanges = !!(this._get('changed') || []).length; + return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts); }, /** - * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword - * Validation succeeds if the value is deeply equal to one of the values in the array. - * see http://json-schema.org/latest/json-schema-validation.html#anchor76 + * Return whether the record is unsaved. Records that have primary keys are + * considered "saved". Records without primary keys are considered "unsaved". * - * @name Schema.validationKeywords.enum - * @method - * @param {*} value Value to validate - * @param {Object} schema Schema containing the `enum` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#isNew + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * id: 1234 + * }) + * const user2 = store.createRecord('user') + * console.log('user isNew: ' + user.isNew()) // false + * console.log('user2 isNew: ' + user2.isNew()) // true + * + * @method Record#isNew + * @returns {boolean} Whether the record is unsaved. + * @since 3.0.0 */ - enum: function _enum(value, schema, opts) { - var possibleValues = schema['enum']; - if (utils.findIndex(possibleValues, function (item) { - return utils.deepEqual(item, value); - }) === -1) { - return makeError(value, 'one of (' + possibleValues.join(', ') + ')', opts); - } + isNew: function isNew(opts) { + return utils.get(this, this._mapper().idAttribute) === undefined; }, /** - * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword - * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules. + * Return whether the record in its current state passes validation. * - * @name Schema.validationKeywords.items - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the items keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#isValid + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user isValid: ' + user.isValid()) + * user.name = 'John' + * console.log('user isValid: ' + user.isValid()) + * + * @method Record#isValid + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {boolean} Whether the record in its current state passes + * validation. + * @since 3.0.0 */ - items: function items(value, schema, opts) { - opts || (opts = {}); - // TODO: additionalItems - var items = schema.items; - var errors = []; - var checkingTuple = utils.isArray(items); - var length = value.length; - for (var prop = 0; prop < length; prop++) { - if (checkingTuple) { - // Validating a tuple, instead of just checking each item against the - // same schema - items = schema.items[prop]; + isValid: function isValid(opts) { + return !this._mapper().validate(this, opts); + }, + removeInverseRelation: function removeInverseRelation(currentParent, id, inverseDef, idAttribute) { + var _this = this; + + if (inverseDef.type === hasOneType) { + safeSetLink(currentParent, inverseDef.localField, undefined); + } else if (inverseDef.type === hasManyType) { + // e.g. remove comment from otherPost.comments + var children = utils.get(currentParent, inverseDef.localField); + if (id === undefined) { + utils.remove(children, function (child) { + return child === _this; + }); + } else { + utils.remove(children, function (child) { + return child === _this || id === utils.get(child, idAttribute); + }); } - opts.prop = prop; - errors = errors.concat(_validate(value[prop], items, opts) || []); } - return errors.length ? errors : undefined; }, + setupInverseRelation: function setupInverseRelation(record, id, inverseDef, idAttribute) { + var _this2 = this; - - /** - * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword - * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword. - * http://json-schema.org/latest/json-schema-validation.html#anchor17 - * - * @name Schema.validationKeywords.maximum - * @method - * @param {*} value Number to validate against the keyword. - * @param {Object} schema Schema containing the `maximum` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - maximum: function maximum(value, schema, opts) { - // Must be a number - var maximum = schema.maximum; - // Must be a boolean - // Depends on maximum - // default: false - var exclusiveMaximum = schema.exclusiveMaximum; - if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof maximum === 'undefined' ? 'undefined' : _typeof(maximum)) && !(exclusiveMaximum ? maximum > value : maximum >= value)) { - return exclusiveMaximum ? makeError(value, 'no more than nor equal to ' + maximum, opts) : makeError(value, 'no more than ' + maximum, opts); + // Update (set) inverse relation + if (inverseDef.type === hasOneType) { + // e.g. someUser.profile = profile + safeSetLink(record, inverseDef.localField, this); + } else if (inverseDef.type === hasManyType) { + // e.g. add comment to somePost.comments + var children = utils.get(record, inverseDef.localField); + if (id === undefined) { + utils.noDupeAdd(children, this, function (child) { + return child === _this2; + }); + } else { + utils.noDupeAdd(children, this, function (child) { + return child === _this2 || id === utils.get(child, idAttribute); + }); + } } }, /** - * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword. - * Validation succeeds if the length of the array is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor42 + * Lazy load relations of this record, to be attached to the record once their + * loaded. * - * @name Schema.validationKeywords.maxItems - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `maxItems` keyword. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('user', { + * relations: { + * hasMany: { + * post: { + * localField: 'posts', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.defineMapper('post', { + * relations: { + * belongsTo: { + * user: { + * localField: 'user', + * foreignKey: 'user_id' + * } + * } + * } + * }) + * store.find('user', 1234).then((user) => { + * console.log(user.id) // 1234 + * + * // Load the user's post relations + * return user.loadRelations(['post']) + * }).then((user) => { + * console.log(user.posts) // [{...}, {...}, ...] + * }) + * + * @method Record#loadRelations + * @param {string[]} [relations] List of relations to load. Can use localField + * names or Mapper names to pick relations. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @returns {Promise} Resolves with the record, with the loaded relations now + * attached. + * @since 3.0.0 */ - maxItems: function maxItems(value, schema, opts) { - if (utils.isArray(value)) { - return maxLengthCommon('maxItems', value, schema, opts); + loadRelations: function loadRelations(relations, opts) { + var _this3 = this; + + var op = void 0; + var mapper = this._mapper(); + + // Default values for arguments + relations || (relations = []); + if (utils.isString(relations)) { + relations = [relations]; } - }, + opts || (opts = {}); + opts.with = relations; + // Fill in "opts" with the Model's configuration + utils._(opts, mapper); + opts.adapter = mapper.getAdapterName(opts); - /** - * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword. - * Validation succeeds if the length of the string is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor26 - * - * @name Schema.validationKeywords.maxLength - * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `maxLength` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - maxLength: function maxLength(value, schema, opts) { - return maxLengthCommon('maxLength', value, schema, opts); + // beforeLoadRelations lifecycle hook + op = opts.op = 'beforeLoadRelations'; + return utils.resolve(this[op](relations, opts)).then(function () { + // Now delegate to the adapter + op = opts.op = 'loadRelations'; + mapper.dbg(op, _this3, relations, opts); + var tasks = []; + var task = void 0; + utils.forEachRelation(mapper, opts, function (def, optsCopy) { + var relatedMapper = def.getRelation(); + optsCopy.raw = false; + if (utils.isFunction(def.load)) { + task = def.load(mapper, def, _this3, opts); + } else if (def.type === 'hasMany' || def.type === 'hasOne') { + if (def.foreignKey) { + task = superMethod(relatedMapper, 'findAll')(defineProperty({}, def.foreignKey, utils.get(_this3, mapper.idAttribute)), optsCopy).then(function (relatedData) { + if (def.type === 'hasOne') { + return relatedData.length ? relatedData[0] : undefined; + } + return relatedData; + }); + } else if (def.localKeys) { + task = superMethod(relatedMapper, 'findAll')({ + where: defineProperty({}, relatedMapper.idAttribute, { + 'in': utils.get(_this3, def.localKeys) + }) + }); + } else if (def.foreignKeys) { + task = superMethod(relatedMapper, 'findAll')({ + where: defineProperty({}, def.foreignKeys, { + 'contains': utils.get(_this3, mapper.idAttribute) + }) + }, opts); + } + } else if (def.type === 'belongsTo') { + var key = utils.get(_this3, def.foreignKey); + if (utils.isSorN(key)) { + task = superMethod(relatedMapper, 'find')(key, optsCopy); + } + } + if (task) { + task = task.then(function (relatedData) { + def.setLocalField(_this3, relatedData); + }); + tasks.push(task); + } + }); + return Promise.all(tasks); + }).then(function () { + // afterLoadRelations lifecycle hook + op = opts.op = 'afterLoadRelations'; + return utils.resolve(_this3[op](relations, opts)).then(function () { + return _this3; + }); + }); }, /** - * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword. - * Validation succeeds if the object's property count is less than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor54 + * Return the properties with which this record was instantiated. * - * @name Schema.validationKeywords.maxProperties - * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `maxProperties` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example Record#previous + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.name = 'Bob' + * console.log('user previous: ' + JSON.stringify(user.previous())) + * user.commit() + * console.log('user previous: ' + JSON.stringify(user.previous())) + * + * @method Record#previous + * @param {string} [key] If specified, return just the initial value of the + * given key. + * @returns {Object} The initial properties of this record. + * @since 3.0.0 */ - maxProperties: function maxProperties(value, schema, opts) { - // validate only objects - if (!utils.isObject(value)) return; - var maxProperties = schema.maxProperties; - var length = Object.keys(value).length; - if (length > maxProperties) { - return makeError(length, 'no more than ' + maxProperties + ' properties', opts); + previous: function previous(key) { + if (key) { + return this._get('previous.' + key); } + return this._get('previous'); }, /** - * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword - * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword. - * http://json-schema.org/latest/json-schema-validation.html#anchor21 + * Revert changes to this record back to the properties it had when it was + * instantiated. * - * @name Schema.validationKeywords.minimum - * @method - * @param {*} value Number to validate against the keyword. - * @param {Object} schema Schema containing the `minimum` keyword. + * @example Record#revert + * // import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * const user = store.createRecord('user', { + * name: 'William' + * }) + * console.log('user: ' + JSON.stringify(user)) + * user.name = 'Bob' + * console.log('user: ' + JSON.stringify(user)) + * user.revert() + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#revert * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {string[]} [opts.preserve] Array of strings or Regular Expressions + * denoting properties that should not be reverted. + * @since 3.0.0 */ - minimum: function minimum(value, schema, opts) { - // Must be a number - var minimum = schema.minimum; - // Must be a boolean - // Depends on minimum - // default: false - var exclusiveMinimum = schema.exclusiveMinimum; - if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof minimum === 'undefined' ? 'undefined' : _typeof(minimum)) && !(exclusiveMinimum ? value > minimum : value >= minimum)) { - return exclusiveMinimum ? makeError(value, 'no less than nor equal to ' + minimum, opts) : makeError(value, 'no less than ' + minimum, opts); - } + revert: function revert(opts) { + var _this4 = this; + + var previous = this._get('previous'); + opts || (opts = {}); + opts.preserve || (opts.preserve = []); + utils.forOwn(this, function (value, key) { + if (key !== _this4._mapper().idAttribute && !previous.hasOwnProperty(key) && _this4.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) { + delete _this4[key]; + } + }); + utils.forOwn(previous, function (value, key) { + if (opts.preserve.indexOf(key) === -1) { + _this4[key] = value; + } + }); + this.commit(); }, /** - * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword. - * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor45 + * Delegates to {@link Mapper#create} or {@link Mapper#update}. * - * @name Schema.validationKeywords.minItems - * @method - * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `minItems` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @example + * import {Container} from 'js-data' + * import {RethinkDBAdapter} from 'js-data-rethinkdb' + * + * const store = new Container() + * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true }) + * store.defineMapper('session') + * const session = store.createRecord('session', { topic: 'Node.js' }) + * + * // Create a new record in the database + * session.save().then(() => { + * console.log(session.id) // 1234 + * + * session.skill_level = 'beginner' + * + * // Update the record in the database + * return user.save() + * }) + * + * @method Record#save + * @param {Object} [opts] Configuration options. See {@link Mapper#create} and + * {@link Mapper#update}. + * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`. + * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @param {Array} [opts.ignore] Passed to {@link Record#changes} when + * `opts.changesOnly` is `true`. + * @returns {Promise} The result of calling {@link Mapper#create} or + * {@link Mapper#update}. + * @since 3.0.0 */ - minItems: function minItems(value, schema, opts) { - if (utils.isArray(value)) { - return minLengthCommon('minItems', value, schema, opts); - } - }, + save: function save(opts) { + var _this5 = this; + opts || (opts = {}); + var mapper = this._mapper(); + var id = utils.get(this, mapper.idAttribute); + var props = this; - /** - * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword. - * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor29 - * - * @name Schema.validationKeywords.minLength - * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `minLength` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - minLength: function minLength(value, schema, opts) { - return minLengthCommon('minLength', value, schema, opts); + var postProcess = function postProcess(result) { + var record = opts.raw ? result.data : result; + if (record) { + utils.deepMixIn(_this5, record); + _this5.commit(); + } + return result; + }; + + if (id === undefined) { + return superMethod(mapper, 'create')(props, opts).then(postProcess); + } + if (opts.changesOnly) { + var changes = this.changes(opts); + props = {}; + utils.fillIn(props, changes.added); + utils.fillIn(props, changes.changed); + } + return superMethod(mapper, 'update')(id, props, opts).then(postProcess); }, /** - * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword. - * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor57 + * Set the value for a given key, or the values for the given keys if "key" is + * an object. Triggers change events on those properties that have `track: true` + * in {@link Mapper#schema}. * - * @name Schema.validationKeywords.minProperties - * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `minProperties` keyword. + * @example Record#set + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set('name', 'Bob') + * console.log('user: ' + JSON.stringify(user)) + * + * user.set({ age: 30, role: 'admin' }) + * console.log('user: ' + JSON.stringify(user)) + * + * @fires Record#change + * @method Record#set + * @param {(string|Object)} key Key to set or hash of key-value pairs to set. + * @param {*} [value] Value to set for the given key. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 */ - minProperties: function minProperties(value, schema, opts) { - // validate only objects - if (!utils.isObject(value)) return; - var minProperties = schema.minProperties; - var length = Object.keys(value).length; - if (length < minProperties) { - return makeError(length, 'no more than ' + minProperties + ' properties', opts); + 'set': function set(key, value, opts) { + if (utils.isObject(key)) { + opts = value; + } + opts || (opts = {}); + if (opts.silent) { + this._set('silent', true); + } + utils.set(this, key, value); + if (!this._get('eventId')) { + this._set('silent'); // unset } }, /** - * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword. - * Validation succeeds if the number can be divided equally into the value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor14 + * Return a plain object representation of this record. If the class from + * which this record was created has a Mapper, then {@link Mapper#toJSON} will + * be called with this record instead. * - * @name Schema.validationKeywords.multipleOf - * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing the `multipleOf` keyword. + * @example Record#toJSON + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * + * const user = store.createRecord('user', { + * name: 'John', + * $$hashKey: '1234' + * }) + * console.log('user: ' + JSON.stringify(user.toJSON())) + * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true }))) + * + * @method Record#toJSON * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.strict] Whether to exclude properties that are not + * defined in {@link Mapper#schema}. + * @param {string[]} [opts.with] Array of relation names or relation fields + * to include in the representation. Only available as an option if the class + * from which this record was created has a Mapper and this record resides in + * an instance of {@link DataStore}. + * @returns {Object} Plain object representation of this record. + * @since 3.0.0 */ - multipleOf: function multipleOf(value, schema, opts) { - var multipleOf = schema.multipleOf; - if (utils.isNumber(value)) { - if (value / multipleOf % 1 !== 0) { - return makeError(value, 'multipleOf ' + multipleOf, opts); - } + toJSON: function toJSON(opts) { + var _this6 = this; + + var mapper = this.constructor.mapper; + if (mapper) { + return mapper.toJSON(this, opts); + } else { + var _ret = function () { + var json = {}; + utils.forOwn(_this6, function (prop, key) { + json[key] = utils.plainCopy(prop); + }); + return { + v: json + }; + }(); + + if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; } }, /** - * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword. - * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value. + * Unset the value for a given key. Triggers change events on those properties + * that have `track: true` in {@link Mapper#schema}. * - * see http://json-schema.org/latest/json-schema-validation.html#anchor91 - * @name Schema.validationKeywords.not - * @method - * @param {*} value to be checked. - * @param {Object} schema Schema containing the not keyword. + * @example Record#unset + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user') + * + * const user = store.createRecord('user', { + * name: 'John' + * }) + * console.log('user: ' + JSON.stringify(user)) + * + * user.unset('name') + * console.log('user: ' + JSON.stringify(user)) + * + * @method Record#unset + * @param {string} key Key to unset. * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {boolean} [opts.silent=false] Whether to trigger change events. + * @since 3.0.0 */ - not: function not(value, schema, opts) { - if (!_validate(value, schema.not, opts)) { - // TODO: better messaging - return makeError('succeeded', 'should have failed', opts); + unset: function unset(key, opts) { + this.set(key, undefined, opts); + }, + + + /** + * Validate this record based on its current properties. + * + * @example Record#validate + * // Normally you would do: import {Container} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Container} = JSData + * console.log('Using JSData v' + JSData.version.full) + * const store = new Container() + * store.defineMapper('user', { + * schema: { + * properties: { + * name: { type: 'string' } + * } + * } + * }) + * const user = store.createRecord('user', { + * name: 1234 + * }, { + * noValidate: true // this allows us to put the record into an invalid state + * }) + * console.log('user validation: ' + JSON.stringify(user.validate())) + * user.name = 'John' + * console.log('user validation: ' + user.validate()) + * + * @method Record#validate + * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}. + * @returns {*} Array of errors or `undefined` if no errors. + * @since 3.0.0 + */ + validate: function validate(opts) { + return this._mapper().validate(this, opts); + } + }); + + /** + * Allow records to emit events. + * + * An record's registered listeners are stored in the record's private data. + */ + utils.eventify(Record.prototype, function () { + return this._get('events'); + }, function (value) { + this._set('events', value); + }); + + var DOMAIN$7 = 'Schema'; + + /** + * A function map for each of the seven primitive JSON types defined by the core specification. + * Each function will check a given value and return true or false if the value is an instance of that type. + * ``` + * types.integer(1) // returns true + * types.string({}) // returns false + * ``` + * http://json-schema.org/latest/json-schema-core.html#anchor8 + * @name Schema.types + * @type {Object} + */ + var types = { + array: utils.isArray, + boolean: utils.isBoolean, + integer: utils.isInteger, + 'null': utils.isNull, + number: utils.isNumber, + object: utils.isObject, + string: utils.isString + }; + + /** + * @ignore + */ + var segmentToString = function segmentToString(segment, prev) { + var str = ''; + if (segment) { + if (utils.isNumber(segment)) { + str += '[' + segment + ']'; + } else if (prev) { + str += '.' + segment; + } else { + str += '' + segment; } + } + return str; + }; + + /** + * @ignore + */ + var makePath = function makePath(opts) { + opts || (opts = {}); + var path = ''; + var segments = opts.path || []; + segments.forEach(function (segment) { + path += segmentToString(segment, path); + }); + path += segmentToString(opts.prop, path); + return path; + }; + + /** + * @ignore + */ + var makeError = function makeError(actual, expected, opts) { + return { + expected: expected, + actual: '' + actual, + path: makePath(opts) + }; + }; + + /** + * @ignore + */ + var addError = function addError(actual, expected, opts, errors) { + errors.push(makeError(actual, expected, opts)); + }; + + /** + * @ignore + */ + var maxLengthCommon = function maxLengthCommon(keyword, value, schema, opts) { + var max = schema[keyword]; + if (value.length > max) { + return makeError(value.length, 'length no more than ' + max, opts); + } + }; + + /** + * @ignore + */ + var minLengthCommon = function minLengthCommon(keyword, value, schema, opts) { + var min = schema[keyword]; + if (value.length < min) { + return makeError(value.length, 'length no less than ' + min, opts); + } + }; + + /** + * A map of all object member validation functions for each keyword defined in the JSON Schema. + * @name Schema.validationKeywords + * @type {Object} + */ + var validationKeywords = { + /** + * Validates the provided value against all schemas defined in the Schemas `allOf` keyword. + * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value. + * + * The value of this keyword MUST be an array. This array MUST have at least one element. + * Each element of this array MUST be a valid JSON Schema. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor82 + * + * @name Schema.validationKeywords.allOf + * @method + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `allOf` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + allOf: function allOf(value, schema, opts) { + var allErrors = []; + schema.allOf.forEach(function (_schema) { + allErrors = allErrors.concat(_validate(value, _schema, opts) || []); + }); + return allErrors.length ? undefined : allErrors; }, /** - * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword. - * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value. + * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword. + * The instance is valid against this keyword if and only if it is valid against + * at least one of the schemas in this keyword's value. * - * see http://json-schema.org/latest/json-schema-validation.html#anchor88 - * @name Schema.validationKeywords.oneOf + * The value of this keyword MUST be an array. This array MUST have at least one element. + * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema. + * see http://json-schema.org/latest/json-schema-validation.html#anchor85 + * + * @name Schema.validationKeywords.anyOf * @method - * @param {*} value to be checked. - * @param {Object} schema Schema containing the `oneOf` keyword. + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `anyOf` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - oneOf: function oneOf(value, schema, opts) { + anyOf: function anyOf(value, schema, opts) { var validated = false; var allErrors = []; - schema.oneOf.forEach(function (_schema) { + schema.anyOf.forEach(function (_schema) { var errors = _validate(value, _schema, opts); if (errors) { allErrors = allErrors.concat(errors); - } else if (validated) { - allErrors = [makeError('valid against more than one', 'valid against only one', opts)]; - validated = false; - return false; } else { validated = true; } @@ -5823,1087 +5938,1011 @@ /** - * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword. - * Validation succeeds if the string is a match of the regex value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor70 * - * see http://json-schema.org/latest/json-schema-validation.html#anchor33 - * @name Schema.validationKeywords.pattern + * @name Schema.validationKeywords.dependencies * @method - * @param {*} value String to be validated. - * @param {Object} schema Schema containing the `pattern` keyword. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. + * @param {*} value TODO + * @param {Object} schema TODO + * @param {Object} opts TODO */ - pattern: function pattern(value, schema, opts) { - var pattern = schema.pattern; - if (utils.isString(value) && !value.match(pattern)) { - return makeError(value, pattern, opts); - } + dependencies: function dependencies(value, schema, opts) { + // TODO }, /** - * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword. - * Validation succeeds if the object's property are valid with each of the schema's in the provided map. - * Validation also depends on the additionalProperties and or patternProperties. - * - * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info. + * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword + * Validation succeeds if the value is deeply equal to one of the values in the array. + * see http://json-schema.org/latest/json-schema-validation.html#anchor76 * - * @name Schema.validationKeywords.properties + * @name Schema.validationKeywords.enum * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `properties` keyword. + * @param {*} value Value to validate + * @param {Object} schema Schema containing the `enum` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - properties: function properties(value, schema, opts) { - opts || (opts = {}); - // Can be a boolean or an object - // Technically the default is an "empty schema", but here "true" is - // functionally the same - var additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties; - // "s": The property set of the instance to validate. - var toValidate = {}; - // "p": The property set from "properties". - // Default is an object - var properties = schema.properties || {}; - // "pp": The property set from "patternProperties". - // Default is an object - var patternProperties = schema.patternProperties || {}; - var errors = []; - - // Collect set "s" - utils.forOwn(value, function (_value, prop) { - toValidate[prop] = undefined; - }); - // Remove from "s" all elements of "p", if any. - utils.forOwn(properties || {}, function (_schema, prop) { - // if (value[prop] === undefined && _schema['default'] !== undefined) { - // value[prop] = utils.copy(_schema['default']) - // } - opts.prop = prop; - errors = errors.concat(_validate(value[prop], _schema, opts) || []); - delete toValidate[prop]; - }); - // For each regex in "pp", remove all elements of "s" which this regex - // matches. - utils.forOwn(patternProperties, function (_schema, pattern) { - utils.forOwn(toValidate, function (undef, prop) { - if (prop.match(pattern)) { - opts.prop = prop; - errors = errors.concat(_validate(value[prop], _schema, opts) || []); - delete toValidate[prop]; - } - }); - }); - var keys = Object.keys(toValidate); - // If "s" is not empty, validation fails - if (additionalProperties === false) { - if (keys.length) { - addError('extra fields: ' + keys.join(', '), 'no extra fields', opts, errors); - } - } else if (utils.isObject(additionalProperties)) { - // Otherwise, validate according to provided schema - keys.forEach(function (prop) { - opts.prop = prop; - errors = errors.concat(_validate(value[prop], additionalProperties, opts) || []); - }); + enum: function _enum(value, schema, opts) { + var possibleValues = schema['enum']; + if (utils.findIndex(possibleValues, function (item) { + return utils.deepEqual(item, value); + }) === -1) { + return makeError(value, 'one of (' + possibleValues.join(', ') + ')', opts); } - return errors.length ? errors : undefined; }, /** - * Validates the provided object's has all properties listed in the Schema's `properties` keyword array. - * Validation succeeds if the object contains all properties provided in the array value of this keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor61 + * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword + * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules. * - * @name Schema.validationKeywords.required + * @name Schema.validationKeywords.items * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing the `required` keyword. + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the items keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - required: function required(value, schema, opts) { + items: function items(value, schema, opts) { opts || (opts = {}); - var required = schema.required; + // TODO: additionalItems + var items = schema.items; var errors = []; - if (!opts.existingOnly) { - required.forEach(function (prop) { - if (utils.get(value, prop) === undefined) { - var prevProp = opts.prop; - opts.prop = prop; - addError(undefined, 'a value', opts, errors); - opts.prop = prevProp; - } - }); + var checkingTuple = utils.isArray(items); + var length = value.length; + for (var prop = 0; prop < length; prop++) { + if (checkingTuple) { + // Validating a tuple, instead of just checking each item against the + // same schema + items = schema.items[prop]; + } + opts.prop = prop; + errors = errors.concat(_validate(value[prop], items, opts) || []); } return errors.length ? errors : undefined; }, /** - * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword. - * see http://json-schema.org/latest/json-schema-validation.html#anchor79 + * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword + * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor17 * - * @name Schema.validationKeywords.type + * @name Schema.validationKeywords.maximum * @method - * @param {*} value Value to be validated. - * @param {Object} schema Schema containing the `type` keyword. + * @param {*} value Number to validate against the keyword. + * @param {Object} schema Schema containing the `maximum` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - type: function type(value, schema, opts) { - var type = schema.type; - var validType = void 0; - // Can be one of several types - if (utils.isString(type)) { - type = [type]; - } - // Try to match the value against an expected type - type.forEach(function (_type) { - // TODO: throw an error if type is not defined - if (types[_type](value, schema, opts)) { - // Matched a type - validType = _type; - return false; - } - }); - // Value did not match any expected type - if (!validType) { - return makeError(value !== undefined && value !== null ? typeof value === 'undefined' ? 'undefined' : _typeof(value) : '' + value, 'one of (' + type.join(', ') + ')', opts); - } - // Run keyword validators for matched type - // http://json-schema.org/latest/json-schema-validation.html#anchor12 - var validator = typeGroupValidators[validType]; - if (validator) { - return validator(value, schema, opts); + maximum: function maximum(value, schema, opts) { + // Must be a number + var maximum = schema.maximum; + // Must be a boolean + // Depends on maximum + // default: false + var exclusiveMaximum = schema.exclusiveMaximum; + if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof maximum === 'undefined' ? 'undefined' : _typeof(maximum)) && !(exclusiveMaximum ? maximum > value : maximum >= value)) { + return exclusiveMaximum ? makeError(value, 'no more than nor equal to ' + maximum, opts) : makeError(value, 'no more than ' + maximum, opts); } }, /** - * Validates the provided array values are unique. - * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true - * see http://json-schema.org/latest/json-schema-validation.html#anchor49 + * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword. + * Validation succeeds if the length of the array is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor42 * - * @name Schema.validationKeywords.uniqueItems + * @name Schema.validationKeywords.maxItems * @method * @param {*} value Array to be validated. - * @param {Object} schema Schema containing the `uniqueItems` keyword. + * @param {Object} schema Schema containing the `maxItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - uniqueItems: function uniqueItems(value, schema, opts) { - if (value && value.length && schema.uniqueItems) { - var length = value.length; - var item = void 0, - i = void 0, - j = void 0; - // Check n - 1 items - for (i = length - 1; i > 0; i--) { - item = value[i]; - // Only compare against unchecked items - for (j = i - 1; j >= 0; j--) { - // Found a duplicate - if (utils.deepEqual(item, value[j])) { - return makeError(item, 'no duplicates', opts); - } - } - } - } - } - }; - - /** - * @ignore - */ - var validateKeyword = function validateKeyword(op, value, schema, opts) { - return schema[op] !== undefined && validationKeywords[op](value, schema, opts); - }; - - /** - * @ignore - */ - var runOps = function runOps(ops, value, schema, opts) { - var errors = []; - ops.forEach(function (op) { - errors = errors.concat(validateKeyword(op, value, schema, opts) || []); - }); - return errors.length ? errors : undefined; - }; - - var ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']; - var ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']; - var NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']; - var OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']; - var STRING_OPS = ['maxLength', 'minLength', 'pattern']; - - /** - * http://json-schema.org/latest/json-schema-validation.html#anchor75 - * @ignore - */ - var validateAny = function validateAny(value, schema, opts) { - return runOps(ANY_OPS, value, schema, opts); - }; - - /** - * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification. - * - * @name Schema.validate - * @method - * @param {*} value Value to be validated. - * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification. - * @param {Object} [opts] Configuration options. - * @returns {(array|undefined)} Array of errors or `undefined` if valid. - */ - var _validate = function _validate(value, schema, opts) { - var errors = []; - opts || (opts = {}); - opts.ctx || (opts.ctx = { value: value, schema: schema }); - var shouldPop = void 0; - var prevProp = opts.prop; - if (schema === undefined) { - return; - } - if (!utils.isObject(schema)) { - throw utils.err(DOMAIN$6 + '#validate')(500, 'Invalid schema at path: "' + opts.path + '"'); - } - if (opts.path === undefined) { - opts.path = []; - } - // Track our location as we recurse - if (opts.prop !== undefined) { - shouldPop = true; - opts.path.push(opts.prop); - opts.prop = undefined; - } - // Validate against parent schema - if (schema['extends']) { - // opts.path = path - // opts.prop = prop - if (utils.isFunction(schema['extends'].validate)) { - errors = errors.concat(schema['extends'].validate(value, opts) || []); - } else { - errors = errors.concat(_validate(value, schema['extends'], opts) || []); - } - } - if (value === undefined) { - // Check if property is required - if (schema.required === true && !opts.existingOnly) { - addError(value, 'a value', opts, errors); - } - if (shouldPop) { - opts.path.pop(); - opts.prop = prevProp; + maxItems: function maxItems(value, schema, opts) { + if (utils.isArray(value)) { + return maxLengthCommon('maxItems', value, schema, opts); } - return errors.length ? errors : undefined; - } - - errors = errors.concat(validateAny(value, schema, opts) || []); - if (shouldPop) { - opts.path.pop(); - opts.prop = prevProp; - } - return errors.length ? errors : undefined; - }; - - // These strings are cached for optimal performance of the change detection - // boolean - Whether a Record is changing in the current execution frame - var changingPath = 'changing'; - // string[] - Properties that have changed in the current execution frame - var changedPath = 'changed'; - // Object[] - History of change records - var changeHistoryPath = 'history'; - // boolean - Whether a Record is currently being instantiated - var creatingPath = 'creating'; - // number - The setTimeout change event id of a Record, if any - var eventIdPath = 'eventId'; - // boolean - Whether to skip validation for a Record's currently changing property - var noValidatePath = 'noValidate'; - // boolean - Whether to skip change notification for a Record's currently - // changing property - var silentPath = 'silent'; - var validationFailureMsg = 'validation failed'; - - /** - * Assemble a property descriptor which will be added to the prototype of - * {@link Mapper#recordClass}. This method is called when - * {@link Mapper#applySchema} is set to `true`. - * - * @ignore - */ - var makeDescriptor = function makeDescriptor(prop, schema, opts) { - var descriptor = { - // Better to allow configurability, but at the user's own risk - configurable: true, - // These properties are enumerable by default, but regardless of their - // enumerability, they won't be "own" properties of individual records - enumerable: schema.enumerable === undefined ? true : !!schema.enumerable - }; - // Cache a few strings for optimal performance - var keyPath = 'props.' + prop; - var previousPath = 'previous.' + prop; - var getter = opts.getter; - var setter = opts.setter; - var unsetter = opts.unsetter; - var track = utils.isBoolean(opts.track) ? opts.track : schema.track; + }, - descriptor.get = function () { - return this._get(keyPath); - }; - if (utils.isFunction(schema.get)) { - (function () { - var originalGet = descriptor.get; - descriptor.get = function () { - return schema.get.call(this, originalGet); - }; - })(); - } - - descriptor.set = function (value) { - var _this = this; + /** + * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword. + * Validation succeeds if the length of the string is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor26 + * + * @name Schema.validationKeywords.maxLength + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `maxLength` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + maxLength: function maxLength(value, schema, opts) { + return maxLengthCommon('maxLength', value, schema, opts); + }, - // These are accessed a lot - var _get = this[getter]; - var _set = this[setter]; - var _unset = this[unsetter]; - // Optionally check that the new value passes validation - if (!_get(noValidatePath)) { - var errors = schema.validate(value, { path: [prop] }); - if (errors) { - // Immediately throw an error, preventing the record from getting into - // an invalid state - var error = new Error(validationFailureMsg); - error.errors = errors; - throw error; - } + /** + * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword. + * Validation succeeds if the object's property count is less than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor54 + * + * @name Schema.validationKeywords.maxProperties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `maxProperties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + maxProperties: function maxProperties(value, schema, opts) { + // validate only objects + if (!utils.isObject(value)) return; + var maxProperties = schema.maxProperties; + var length = Object.keys(value).length; + if (length > maxProperties) { + return makeError(length, 'no more than ' + maxProperties + ' properties', opts); } - // TODO: Make it so tracking can be turned on for all properties instead of - // only per-property - if (track && !_get(creatingPath)) { - (function () { - var previous = _get(previousPath); - var current = _get(keyPath); - var changing = _get(changingPath); - var changed = _get(changedPath); - - if (!changing) { - // Track properties that are changing in the current event loop - changed = []; - } + }, - // Add changing properties to this array once at most - var index = changed.indexOf(prop); - if (current !== value && index === -1) { - changed.push(prop); - } - if (previous === value) { - if (index >= 0) { - changed.splice(index, 1); - } - } - // No changes in current event loop - if (!changed.length) { - changing = false; - _unset(changingPath); - _unset(changedPath); - // Cancel pending change event - if (_get(eventIdPath)) { - clearTimeout(_get(eventIdPath)); - _unset(eventIdPath); - } - } - // Changes detected in current event loop - if (!changing && changed.length) { - _set(changedPath, changed); - _set(changingPath, true); - // Saving the timeout id allows us to batch all changes in the same - // event loop into a single "change" - // TODO: Optimize - _set(eventIdPath, setTimeout(function () { - // Previous event loop where changes were gathered has ended, so - // notify any listeners of those changes and prepare for any new - // changes - _unset(changedPath); - _unset(eventIdPath); - _unset(changingPath); - // TODO: Optimize - if (!_get(silentPath)) { - var i = void 0; - for (i = 0; i < changed.length; i++) { - _this.emit('change:' + changed[i], _this, utils.get(_this, changed[i])); - } - var changes = _this.changes(); - var changeRecord = utils.plainCopy(changes); - changeRecord.timestamp = new Date().getTime(); - var changeHistory = _get(changeHistoryPath) || []; - _set(changeHistoryPath, changeHistory); - changeHistory.push(changeRecord); - _this.emit('change', _this, changes); - } - _unset(silentPath); - }, 0)); - } - })(); - } - _set(keyPath, value); - return value; - }; - if (utils.isFunction(schema.set)) { - (function () { - var originalSet = descriptor.set; - descriptor.set = function (value) { - return schema.set.call(this, value, originalSet); - }; - })(); - } + /** + * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword + * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword. + * http://json-schema.org/latest/json-schema-validation.html#anchor21 + * + * @name Schema.validationKeywords.minimum + * @method + * @param {*} value Number to validate against the keyword. + * @param {Object} schema Schema containing the `minimum` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + minimum: function minimum(value, schema, opts) { + // Must be a number + var minimum = schema.minimum; + // Must be a boolean + // Depends on minimum + // default: false + var exclusiveMinimum = schema.exclusiveMinimum; + if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === (typeof minimum === 'undefined' ? 'undefined' : _typeof(minimum)) && !(exclusiveMinimum ? value > minimum : value >= minimum)) { + return exclusiveMinimum ? makeError(value, 'no less than nor equal to ' + minimum, opts) : makeError(value, 'no less than ' + minimum, opts); + } + }, - return descriptor; - }; - /** - * A map of validation functions grouped by type. - * - * @name Schema.typeGroupValidators - * @type {Object} - */ - var typeGroupValidators = { /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an array. - * The validation keywords for the type `array` are: - *``` - * ['items', 'maxItems', 'minItems', 'uniqueItems'] - *``` - * see http://json-schema.org/latest/json-schema-validation.html#anchor25 + * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword. + * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor45 * - * @name Schema.typeGroupValidators.array + * @name Schema.validationKeywords.minItems * @method * @param {*} value Array to be validated. - * @param {Object} schema Schema containing at least one array keyword. + * @param {Object} schema Schema containing the `minItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - array: function array(value, schema, opts) { - return runOps(ARRAY_OPS, value, schema, opts); + minItems: function minItems(value, schema, opts) { + if (utils.isArray(value)) { + return minLengthCommon('minItems', value, schema, opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer. - * The validation keywords for the type `integer` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * @name Schema.typeGroupValidators.integer + * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword. + * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor29 + * + * @name Schema.validationKeywords.minLength * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `integer` keyword. + * @param {*} value String to be validated. + * @param {Object} schema Schema containing the `minLength` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - integer: function integer(value, schema, opts) { - // Additional validations for numerics are the same - return typeGroupValidators.numeric(value, schema, opts); + minLength: function minLength(value, schema, opts) { + return minLengthCommon('minLength', value, schema, opts); }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an number. - * The validation keywords for the type `number` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * @name Schema.typeGroupValidators.number + * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword. + * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor57 + * + * @name Schema.validationKeywords.minProperties * @method - * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `number` keyword. + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `minProperties` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - number: function number(value, schema, opts) { - // Additional validations for numerics are the same - return typeGroupValidators.numeric(value, schema, opts); + minProperties: function minProperties(value, schema, opts) { + // validate only objects + if (!utils.isObject(value)) return; + var minProperties = schema.minProperties; + var length = Object.keys(value).length; + if (length < minProperties) { + return makeError(length, 'no more than ' + minProperties + ' properties', opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer. - * The validation keywords for the type `numeric` are: - *``` - * ['multipleOf', 'maximum', 'minimum'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor13. + * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword. + * Validation succeeds if the number can be divided equally into the value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor14 * - * @name Schema.typeGroupValidators.numeric + * @name Schema.validationKeywords.multipleOf * @method * @param {*} value Number to be validated. - * @param {Object} schema Schema containing at least one `numeric` keyword. + * @param {Object} schema Schema containing the `multipleOf` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - numeric: function numeric(value, schema, opts) { - return runOps(NUMERIC_OPS, value, schema, opts); + multipleOf: function multipleOf(value, schema, opts) { + var multipleOf = schema.multipleOf; + if (utils.isNumber(value)) { + if (value / multipleOf % 1 !== 0) { + return makeError(value, 'multipleOf ' + multipleOf, opts); + } + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an object. - * The validation keywords for the type `object` are: - *``` - * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor53. + * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword. + * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value. * - * @name Schema.typeGroupValidators.object + * see http://json-schema.org/latest/json-schema-validation.html#anchor91 + * @name Schema.validationKeywords.not * @method - * @param {*} value Object to be validated. - * @param {Object} schema Schema containing at least one `object` keyword. + * @param {*} value to be checked. + * @param {Object} schema Schema containing the not keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - object: function object(value, schema, opts) { - return runOps(OBJECT_OPS, value, schema, opts); + not: function not(value, schema, opts) { + if (!_validate(value, schema.not, opts)) { + // TODO: better messaging + return makeError('succeeded', 'should have failed', opts); + } }, + /** - * Validates the provided value against the schema using all of the validation keywords specific to instances of an string. - * The validation keywords for the type `string` are: - *``` - * ['maxLength', 'minLength', 'pattern'] - *``` - * See http://json-schema.org/latest/json-schema-validation.html#anchor25. + * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword. + * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value. * - * @name Schema.typeGroupValidators.string + * see http://json-schema.org/latest/json-schema-validation.html#anchor88 + * @name Schema.validationKeywords.oneOf + * @method + * @param {*} value to be checked. + * @param {Object} schema Schema containing the `oneOf` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + oneOf: function oneOf(value, schema, opts) { + var validated = false; + var allErrors = []; + schema.oneOf.forEach(function (_schema) { + var errors = _validate(value, _schema, opts); + if (errors) { + allErrors = allErrors.concat(errors); + } else if (validated) { + allErrors = [makeError('valid against more than one', 'valid against only one', opts)]; + validated = false; + return false; + } else { + validated = true; + } + }); + return validated ? undefined : allErrors; + }, + + + /** + * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword. + * Validation succeeds if the string is a match of the regex value of this keyword. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor33 + * @name Schema.validationKeywords.pattern * @method * @param {*} value String to be validated. - * @param {Object} schema Schema containing at least one `string` keyword. + * @param {Object} schema Schema containing the `pattern` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - string: function string(value, schema, opts) { - return runOps(STRING_OPS, value, schema, opts); - } - }; + pattern: function pattern(value, schema, opts) { + var pattern = schema.pattern; + if (utils.isString(value) && !value.match(pattern)) { + return makeError(value, pattern, opts); + } + }, - /** - * js-data's Schema class. - * - * @example Schema#constructor - * // Normally you would do: import {Schema} from 'js-data' - * const JSData = require('js-data@3.0.0-beta.10') - * const {Schema} = JSData - * console.log('Using JSData v' + JSData.version.full) - * - * const PostSchema = new Schema({ - * type: 'object', - * properties: { - * title: { type: 'string' } - * } - * }) - * PostSchema.validate({ title: 1234 }) - * - * @class Schema - * @extends Component - * @param {Object} definition Schema definition according to json-schema.org - */ - function Schema(definition) { - var _this2 = this; - definition || (definition = {}); - // TODO: schema validation - utils.fillIn(this, definition); + /** + * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword. + * Validation succeeds if the object's property are valid with each of the schema's in the provided map. + * Validation also depends on the additionalProperties and or patternProperties. + * + * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info. + * + * @name Schema.validationKeywords.properties + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `properties` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + properties: function properties(value, schema, opts) { + opts || (opts = {}); + // Can be a boolean or an object + // Technically the default is an "empty schema", but here "true" is + // functionally the same + var additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties; + // "s": The property set of the instance to validate. + var toValidate = {}; + // "p": The property set from "properties". + // Default is an object + var properties = schema.properties || {}; + // "pp": The property set from "patternProperties". + // Default is an object + var patternProperties = schema.patternProperties || {}; + var errors = []; - if (this.type === 'object' && this.properties) { - utils.forOwn(this.properties, function (_definition, prop) { - if (!(_definition instanceof Schema)) { - _this2.properties[prop] = new Schema(_definition); - } + // Collect set "s" + utils.forOwn(value, function (_value, prop) { + toValidate[prop] = undefined; + }); + // Remove from "s" all elements of "p", if any. + utils.forOwn(properties || {}, function (_schema, prop) { + // if (value[prop] === undefined && _schema['default'] !== undefined) { + // value[prop] = utils.copy(_schema['default']) + // } + opts.prop = prop; + errors = errors.concat(_validate(value[prop], _schema, opts) || []); + delete toValidate[prop]; }); - } - if (this.type === 'array' && this.items && !(this.items instanceof Schema)) { - this.items = new Schema(this.items); - } - ['allOf', 'anyOf', 'oneOf'].forEach(function (validationKeyword) { - if (_this2[validationKeyword]) { - _this2[validationKeyword].forEach(function (_definition, i) { - if (!(_definition instanceof Schema)) { - _this2[validationKeyword][i] = new Schema(_definition); + // For each regex in "pp", remove all elements of "s" which this regex + // matches. + utils.forOwn(patternProperties, function (_schema, pattern) { + utils.forOwn(toValidate, function (undef, prop) { + if (prop.match(pattern)) { + opts.prop = prop; + errors = errors.concat(_validate(value[prop], _schema, opts) || []); + delete toValidate[prop]; } }); + }); + var keys = Object.keys(toValidate); + // If "s" is not empty, validation fails + if (additionalProperties === false) { + if (keys.length) { + addError('extra fields: ' + keys.join(', '), 'no extra fields', opts, errors); + } + } else if (utils.isObject(additionalProperties)) { + // Otherwise, validate according to provided schema + keys.forEach(function (prop) { + opts.prop = prop; + errors = errors.concat(_validate(value[prop], additionalProperties, opts) || []); + }); } - }); - } + return errors.length ? errors : undefined; + }, - var Schema$1 = Component$1.extend({ - constructor: Schema, /** - * This adds ES5 getters/setters to the target based on the "properties" in - * this Schema, which makes possible change tracking and validation on - * property assignment. + * Validates the provided object's has all properties listed in the Schema's `properties` keyword array. + * Validation succeeds if the object contains all properties provided in the array value of this keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor61 * - * @name Schema#validate + * @name Schema.validationKeywords.required * @method - * @param {Object} target The prototype to which to apply this schema. + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing the `required` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - apply: function apply(target, opts) { + required: function required(value, schema, opts) { opts || (opts = {}); - opts.getter || (opts.getter = '_get'); - opts.setter || (opts.setter = '_set'); - opts.unsetter || (opts.unsetter = '_unset'); - opts.track || (opts.track = this.track); - var properties = this.properties || {}; - utils.forOwn(properties, function (schema, prop) { - Object.defineProperty(target, prop, makeDescriptor(prop, schema, opts)); - }); + var required = schema.required; + var errors = []; + if (!opts.existingOnly) { + required.forEach(function (prop) { + if (utils.get(value, prop) === undefined) { + var prevProp = opts.prop; + opts.prop = prop; + addError(undefined, 'a value', opts, errors); + opts.prop = prevProp; + } + }); + } + return errors.length ? errors : undefined; }, /** - * Apply default values to the target object for missing values. + * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword. + * see http://json-schema.org/latest/json-schema-validation.html#anchor79 * - * @name Schema#applyDefaults + * @name Schema.validationKeywords.type * @method - * @param {Object} target The target to which to apply values for missing values. + * @param {*} value Value to be validated. + * @param {Object} schema Schema containing the `type` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - applyDefaults: function applyDefaults(target) { - if (!target) { - return; + type: function type(value, schema, opts) { + var type = schema.type; + var validType = void 0; + // Can be one of several types + if (utils.isString(type)) { + type = [type]; } - var properties = this.properties || {}; - var hasSet = utils.isFunction(target.set) || utils.isFunction(target._set); - utils.forOwn(properties, function (schema, prop) { - if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) { - if (hasSet) { - target.set(prop, utils.plainCopy(schema['default']), { silent: true }); - } else { - utils.set(target, prop, utils.plainCopy(schema['default'])); - } - } - if (schema.type === 'object' && schema.properties) { - if (hasSet) { - var orig = target._get('noValidate'); - target._set('noValidate', true); - utils.set(target, prop, utils.get(target, prop) || {}, { silent: true }); - target._set('noValidate', orig); - } else { - utils.set(target, prop, utils.get(target, prop) || {}); - } - schema.applyDefaults(utils.get(target, prop)); + // Try to match the value against an expected type + type.forEach(function (_type) { + // TODO: throw an error if type is not defined + if (types[_type](value, schema, opts)) { + // Matched a type + validType = _type; + return false; } }); + // Value did not match any expected type + if (!validType) { + return makeError(value !== undefined && value !== null ? typeof value === 'undefined' ? 'undefined' : _typeof(value) : '' + value, 'one of (' + type.join(', ') + ')', opts); + } + // Run keyword validators for matched type + // http://json-schema.org/latest/json-schema-validation.html#anchor12 + var validator = typeGroupValidators[validType]; + if (validator) { + return validator(value, schema, opts); + } }, /** - * Validate the provided value against this schema. + * Validates the provided array values are unique. + * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true + * see http://json-schema.org/latest/json-schema-validation.html#anchor49 * - * @name Schema#validate + * @name Schema.validationKeywords.uniqueItems * @method - * @param {*} value Value to validate. + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing the `uniqueItems` keyword. * @param {Object} [opts] Configuration options. * @returns {(array|undefined)} Array of errors or `undefined` if valid. */ - validate: function validate(value, opts) { - return _validate(value, this, opts); + uniqueItems: function uniqueItems(value, schema, opts) { + if (value && value.length && schema.uniqueItems) { + var length = value.length; + var item = void 0, + i = void 0, + j = void 0; + // Check n - 1 items + for (i = length - 1; i > 0; i--) { + item = value[i]; + // Only compare against unchecked items + for (j = i - 1; j >= 0; j--) { + // Found a duplicate + if (utils.deepEqual(item, value[j])) { + return makeError(item, 'no duplicates', opts); + } + } + } + } } - }, { - ANY_OPS: ANY_OPS, - ARRAY_OPS: ARRAY_OPS, - NUMERIC_OPS: NUMERIC_OPS, - OBJECT_OPS: OBJECT_OPS, - STRING_OPS: STRING_OPS, - typeGroupValidators: typeGroupValidators, - types: types, - validate: _validate, - validationKeywords: validationKeywords - }); - - // TODO: remove this when the rest of the project is cleaned - var belongsToType = 'belongsTo'; - var hasManyType = 'hasMany'; - var hasOneType = 'hasOne'; + }; - var DOMAIN$7 = 'Relation'; + /** + * @ignore + */ + var validateKeyword = function validateKeyword(op, value, schema, opts) { + return schema[op] !== undefined && validationKeywords[op](value, schema, opts); + }; - function Relation(relatedMapper) { - var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; + /** + * @ignore + */ + var runOps = function runOps(ops, value, schema, opts) { + var errors = []; + ops.forEach(function (op) { + errors = errors.concat(validateKeyword(op, value, schema, opts) || []); + }); + return errors.length ? errors : undefined; + }; - utils.classCallCheck(this, Relation); + var ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']; + var ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']; + var NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']; + var OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']; + var STRING_OPS = ['maxLength', 'minLength', 'pattern']; - options.type = this.constructor.TYPE_NAME; - this.validateOptions(relatedMapper, options); + /** + * http://json-schema.org/latest/json-schema-validation.html#anchor75 + * @ignore + */ + var validateAny = function validateAny(value, schema, opts) { + return runOps(ANY_OPS, value, schema, opts); + }; - if ((typeof relatedMapper === 'undefined' ? 'undefined' : _typeof(relatedMapper)) === 'object') { - Object.defineProperty(this, 'relatedMapper', { value: relatedMapper }); + /** + * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification. + * + * @name Schema.validate + * @method + * @param {*} value Value to be validated. + * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + var _validate = function _validate(value, schema, opts) { + var errors = []; + opts || (opts = {}); + opts.ctx || (opts.ctx = { value: value, schema: schema }); + var shouldPop = void 0; + var prevProp = opts.prop; + if (schema === undefined) { + return; + } + if (!utils.isObject(schema)) { + throw utils.err(DOMAIN$7 + '#validate')(500, 'Invalid schema at path: "' + opts.path + '"'); + } + if (opts.path === undefined) { + opts.path = []; + } + // Track our location as we recurse + if (opts.prop !== undefined) { + shouldPop = true; + opts.path.push(opts.prop); + opts.prop = undefined; + } + // Validate against parent schema + if (schema['extends']) { + // opts.path = path + // opts.prop = prop + if (utils.isFunction(schema['extends'].validate)) { + errors = errors.concat(schema['extends'].validate(value, opts) || []); + } else { + errors = errors.concat(_validate(value, schema['extends'], opts) || []); + } + } + if (value === undefined) { + // Check if property is required + if (schema.required === true && !opts.existingOnly) { + addError(value, 'a value', opts, errors); + } + if (shouldPop) { + opts.path.pop(); + opts.prop = prevProp; + } + return errors.length ? errors : undefined; } - Object.defineProperty(this, 'inverse', { writable: true }); - utils.fillIn(this, options); - } + errors = errors.concat(validateAny(value, schema, opts) || []); + if (shouldPop) { + opts.path.pop(); + opts.prop = prevProp; + } + return errors.length ? errors : undefined; + }; - Relation.extend = utils.extend; + // These strings are cached for optimal performance of the change detection + // boolean - Whether a Record is changing in the current execution frame + var changingPath = 'changing'; + // string[] - Properties that have changed in the current execution frame + var changedPath = 'changed'; + // Object[] - History of change records + var changeHistoryPath = 'history'; + // boolean - Whether a Record is currently being instantiated + var creatingPath = 'creating'; + // number - The setTimeout change event id of a Record, if any + var eventIdPath = 'eventId'; + // boolean - Whether to skip validation for a Record's currently changing property + var noValidatePath = 'noValidate'; + // boolean - Whether to skip change notification for a Record's currently + // changing property + var silentPath = 'silent'; + var validationFailureMsg = 'validation failed'; - utils.addHiddenPropsToTarget(Relation.prototype, { - get canAutoAddLinks() { - return this.add === undefined || !!this.add; - }, + /** + * Assemble a property descriptor which will be added to the prototype of + * {@link Mapper#recordClass}. This method is called when + * {@link Mapper#applySchema} is set to `true`. + * + * @ignore + */ + var makeDescriptor = function makeDescriptor(prop, schema, opts) { + var descriptor = { + // Better to allow configurability, but at the user's own risk + configurable: true, + // These properties are enumerable by default, but regardless of their + // enumerability, they won't be "own" properties of individual records + enumerable: schema.enumerable === undefined ? true : !!schema.enumerable + }; + // Cache a few strings for optimal performance + var keyPath = 'props.' + prop; + var previousPath = 'previous.' + prop; + var getter = opts.getter; + var setter = opts.setter; + var unsetter = opts.unsetter; + var track = utils.isBoolean(opts.track) ? opts.track : schema.track; - get relatedCollection() { - return this.mapper.datastore.getCollection(this.relation); - }, + descriptor.get = function () { + return this._get(keyPath); + }; - validateOptions: function validateOptions(related, opts) { - var DOMAIN_ERR = 'new ' + DOMAIN$7; + if (utils.isFunction(schema.get)) { + (function () { + var originalGet = descriptor.get; + descriptor.get = function () { + return schema.get.call(this, originalGet); + }; + })(); + } - var localField = opts.localField; - if (!localField) { - throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField); - } + descriptor.set = function (value) { + var _this = this; - var foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey; - if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) { - throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey); - } + // These are accessed a lot + var _get = this[getter]; + var _set = this[setter]; + var _unset = this[unsetter]; - if (utils.isString(related)) { - opts.relation = related; - if (!utils.isFunction(opts.getRelation)) { - throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation); + // Optionally check that the new value passes validation + if (!_get(noValidatePath)) { + var errors = schema.validate(value, { path: [prop] }); + if (errors) { + // Immediately throw an error, preventing the record from getting into + // an invalid state + var error = new Error(validationFailureMsg); + error.errors = errors; + throw error; } - } else if (related) { - opts.relation = related.name; - } else { - throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related); - } - }, - assignTo: function assignTo(mapper) { - this.name = mapper.name; - Object.defineProperty(this, 'mapper', { value: mapper }); - - mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] }); - mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] }); - mapper.relationList.push(this); - mapper.relationFields.push(this.localField); - }, - canFindLinkFor: function canFindLinkFor() { - return !!(this.foreignKey || this.localKey); - }, - getRelation: function getRelation() { - return this.relatedMapper; - }, - getForeignKey: function getForeignKey(record) { - return utils.get(record, this.mapper.idAttribute); - }, - setForeignKey: function setForeignKey(record, relatedRecord) { - if (!record || !relatedRecord) { - return; } + // TODO: Make it so tracking can be turned on for all properties instead of + // only per-property + if (track && !_get(creatingPath)) { + (function () { + var previous = _get(previousPath); + var current = _get(keyPath); + var changing = _get(changingPath); + var changed = _get(changedPath); - this._setForeignKey(record, relatedRecord); - }, - _setForeignKey: function _setForeignKey(record, relatedRecords) { - var _this = this; - - var idAttribute = this.mapper.idAttribute; - - if (!utils.isArray(relatedRecords)) { - relatedRecords = [relatedRecords]; - } + if (!changing) { + // Track properties that are changing in the current event loop + changed = []; + } - relatedRecords.forEach(function (relatedRecord) { - utils.set(relatedRecord, _this.foreignKey, utils.get(record, idAttribute)); - }); - }, - getLocalField: function getLocalField(record) { - return utils.get(record, this.localField); - }, - setLocalField: function setLocalField(record, relatedData) { - return utils.set(record, this.localField, relatedData); - }, - getInverse: function getInverse(mapper) { - if (!this.inverse) { - this.findInverseRelation(mapper); + // Add changing properties to this array once at most + var index = changed.indexOf(prop); + if (current !== value && index === -1) { + changed.push(prop); + } + if (previous === value) { + if (index >= 0) { + changed.splice(index, 1); + } + } + // No changes in current event loop + if (!changed.length) { + changing = false; + _unset(changingPath); + _unset(changedPath); + // Cancel pending change event + if (_get(eventIdPath)) { + clearTimeout(_get(eventIdPath)); + _unset(eventIdPath); + } + } + // Changes detected in current event loop + if (!changing && changed.length) { + _set(changedPath, changed); + _set(changingPath, true); + // Saving the timeout id allows us to batch all changes in the same + // event loop into a single "change" + // TODO: Optimize + _set(eventIdPath, setTimeout(function () { + // Previous event loop where changes were gathered has ended, so + // notify any listeners of those changes and prepare for any new + // changes + _unset(changedPath); + _unset(eventIdPath); + _unset(changingPath); + // TODO: Optimize + if (!_get(silentPath)) { + var i = void 0; + for (i = 0; i < changed.length; i++) { + _this.emit('change:' + changed[i], _this, utils.get(_this, changed[i])); + } + var changes = _this.changes(); + var changeRecord = utils.plainCopy(changes); + changeRecord.timestamp = new Date().getTime(); + var changeHistory = _get(changeHistoryPath) || []; + _set(changeHistoryPath, changeHistory); + changeHistory.push(changeRecord); + _this.emit('change', _this, changes); + } + _unset(silentPath); + }, 0)); + } + })(); } + _set(keyPath, value); + return value; + }; - return this.inverse; - }, - findInverseRelation: function findInverseRelation(mapper) { - var _this2 = this; - - this.getRelation().relationList.forEach(function (def) { - if (def.getRelation() === mapper && _this2.isInversedTo(def)) { - _this2.inverse = def; - return true; - } - }); - }, - isInversedTo: function isInversedTo(def) { - return !def.foreignKey || def.foreignKey === this.foreignKey; - }, - addLinkedRecords: function addLinkedRecords(records) { - var _this3 = this; - - var datastore = this.mapper.datastore; - - records.forEach(function (record) { - var relatedData = _this3.getLocalField(record); - - if (utils.isFunction(_this3.add)) { - relatedData = _this3.add(datastore, _this3, record); - } else if (relatedData) { - relatedData = _this3.linkRecord(record, relatedData); - } - - var isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length; + if (utils.isFunction(schema.set)) { + (function () { + var originalSet = descriptor.set; + descriptor.set = function (value) { + return schema.set.call(this, value, originalSet); + }; + })(); + } - if (isEmptyLinks && _this3.canFindLinkFor(record)) { - relatedData = _this3.findExistingLinksFor(record); - } + return descriptor; + }; - if (relatedData) { - _this3.setLocalField(record, relatedData); - } - }); + /** + * A map of validation functions grouped by type. + * + * @name Schema.typeGroupValidators + * @type {Object} + */ + var typeGroupValidators = { + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an array. + * The validation keywords for the type `array` are: + *``` + * ['items', 'maxItems', 'minItems', 'uniqueItems'] + *``` + * see http://json-schema.org/latest/json-schema-validation.html#anchor25 + * + * @name Schema.typeGroupValidators.array + * @method + * @param {*} value Array to be validated. + * @param {Object} schema Schema containing at least one array keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + array: function array(value, schema, opts) { + return runOps(ARRAY_OPS, value, schema, opts); }, - removeLinkedRecords: function removeLinkedRecords(relatedMapper, records) { - var _this4 = this; - var localField = this.localField; - records.forEach(function (record) { - var relatedData = utils.get(record, localField); - _this4.unlinkInverseRecords(relatedData); - utils.set(record, localField, undefined); - }); - }, - unlinkInverseRecords: function unlinkInverseRecords(record) { - if (!record) { - return; - } - utils.set(record, this.getInverse(this.mapper).localField, undefined); + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer. + * The validation keywords for the type `integer` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * @name Schema.typeGroupValidators.integer + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `integer` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + integer: function integer(value, schema, opts) { + // Additional validations for numerics are the same + return typeGroupValidators.numeric(value, schema, opts); }, - linkRecord: function linkRecord(record, relatedRecord) { - var relatedId = utils.get(relatedRecord, this.mapper.idAttribute); - if (relatedId === undefined) { - var unsaved = this.relatedCollection.unsaved(); - if (unsaved.indexOf(relatedRecord) === -1) { - if (this.canAutoAddLinks) { - relatedRecord = this.relatedCollection.add(relatedRecord); - } - } - } else { - if (relatedRecord !== this.relatedCollection.get(relatedId)) { - this.setForeignKey(record, relatedRecord); - - if (this.canAutoAddLinks) { - relatedRecord = this.relatedCollection.add(relatedRecord); - } - } - } + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an number. + * The validation keywords for the type `number` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * @name Schema.typeGroupValidators.number + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `number` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + number: function number(value, schema, opts) { + // Additional validations for numerics are the same + return typeGroupValidators.numeric(value, schema, opts); + }, - return relatedRecord; + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer. + * The validation keywords for the type `numeric` are: + *``` + * ['multipleOf', 'maximum', 'minimum'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor13. + * + * @name Schema.typeGroupValidators.numeric + * @method + * @param {*} value Number to be validated. + * @param {Object} schema Schema containing at least one `numeric` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + numeric: function numeric(value, schema, opts) { + return runOps(NUMERIC_OPS, value, schema, opts); }, + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an object. + * The validation keywords for the type `object` are: + *``` + * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor53. + * + * @name Schema.typeGroupValidators.object + * @method + * @param {*} value Object to be validated. + * @param {Object} schema Schema containing at least one `object` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + object: function object(value, schema, opts) { + return runOps(OBJECT_OPS, value, schema, opts); + }, - // e.g. user hasMany post via "foreignKey", so find all posts of user - findExistingLinksByForeignKey: function findExistingLinksByForeignKey(id) { - return this.relatedCollection.filter(defineProperty({}, this.foreignKey, id)); + /** + * Validates the provided value against the schema using all of the validation keywords specific to instances of an string. + * The validation keywords for the type `string` are: + *``` + * ['maxLength', 'minLength', 'pattern'] + *``` + * See http://json-schema.org/latest/json-schema-validation.html#anchor25. + * + * @name Schema.typeGroupValidators.string + * @method + * @param {*} value String to be validated. + * @param {Object} schema Schema containing at least one `string` keyword. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + string: function string(value, schema, opts) { + return runOps(STRING_OPS, value, schema, opts); } - }); + }; - var BelongsToRelation = Relation.extend({ - getForeignKey: function getForeignKey(record) { - return utils.get(record, this.foreignKey); - }, - _setForeignKey: function _setForeignKey(record, relatedRecord) { - utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute)); - }, - findExistingLinksFor: function findExistingLinksFor(record) { - // console.log('\tBelongsTo#findExistingLinksFor', record) - if (!record) { - return; - } - var relatedId = utils.get(record, this.foreignKey); - if (relatedId !== undefined && relatedId !== null) { - return this.relatedCollection.get(relatedId); - } - } - }, { - TYPE_NAME: 'belongsTo' - }); + /** + * js-data's Schema class. + * + * @example Schema#constructor + * // Normally you would do: import {Schema} from 'js-data' + * const JSData = require('js-data@3.0.0-beta.10') + * const {Schema} = JSData + * console.log('Using JSData v' + JSData.version.full) + * + * const PostSchema = new Schema({ + * type: 'object', + * properties: { + * title: { type: 'string' } + * } + * }) + * PostSchema.validate({ title: 1234 }) + * + * @class Schema + * @extends Component + * @param {Object} definition Schema definition according to json-schema.org + */ + function Schema(definition) { + var _this2 = this; - var HasManyRelation = Relation.extend({ - validateOptions: function validateOptions(related, opts) { - Relation.prototype.validateOptions.call(this, related, opts); + definition || (definition = {}); + // TODO: schema validation + utils.fillIn(this, definition); - var localKeys = opts.localKeys; - var foreignKeys = opts.foreignKeys; - var foreignKey = opts.foreignKey; + if (this.type === 'object' && this.properties) { + utils.forOwn(this.properties, function (_definition, prop) { + if (!(_definition instanceof Schema)) { + _this2.properties[prop] = new Schema(_definition); + } + }); + } + if (this.type === 'array' && this.items && !(this.items instanceof Schema)) { + this.items = new Schema(this.items); + } + ['allOf', 'anyOf', 'oneOf'].forEach(function (validationKeyword) { + if (_this2[validationKeyword]) { + _this2[validationKeyword].forEach(function (_definition, i) { + if (!(_definition instanceof Schema)) { + _this2[validationKeyword][i] = new Schema(_definition); + } + }); + } + }); + } + var Schema$1 = Component$1.extend({ + constructor: Schema, - if (!foreignKey && !localKeys && !foreignKeys) { - throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey); - } - }, - canFindLinkFor: function canFindLinkFor(record) { - var hasForeignKeys = this.foreignKey || this.foreignKeys; - return !!(hasForeignKeys || this.localKeys && utils.get(record, this.localKeys)); - }, - unlinkInverseRecords: function unlinkInverseRecords(records) { - if (!records) { - return; - } - var localField = this.getInverse(this.mapper).localField; - records.forEach(function (record) { - utils.set(record, localField, undefined); + /** + * This adds ES5 getters/setters to the target based on the "properties" in + * this Schema, which makes possible change tracking and validation on + * property assignment. + * + * @name Schema#validate + * @method + * @param {Object} target The prototype to which to apply this schema. + */ + apply: function apply(target, opts) { + opts || (opts = {}); + opts.getter || (opts.getter = '_get'); + opts.setter || (opts.setter = '_set'); + opts.unsetter || (opts.unsetter = '_unset'); + opts.track || (opts.track = this.track); + var properties = this.properties || {}; + utils.forOwn(properties, function (schema, prop) { + Object.defineProperty(target, prop, makeDescriptor(prop, schema, opts)); }); }, - linkRecord: function linkRecord(record, relatedRecords) { - var _this = this; - - var relatedCollection = this.relatedCollection; - var canAutoAddLinks = this.canAutoAddLinks; - var foreignKey = this.foreignKey; - var unsaved = this.relatedCollection.unsaved(); - return relatedRecords.map(function (relatedRecord) { - var relatedId = relatedCollection.recordId(relatedRecord); - if (relatedId === undefined && unsaved.indexOf(relatedRecord) === -1 || relatedRecord !== relatedCollection.get(relatedId)) { - if (foreignKey) { - // TODO: slow, could be optimized? But user loses hook - _this.setForeignKey(record, relatedRecord); + /** + * Apply default values to the target object for missing values. + * + * @name Schema#applyDefaults + * @method + * @param {Object} target The target to which to apply values for missing values. + */ + applyDefaults: function applyDefaults(target) { + if (!target) { + return; + } + var properties = this.properties || {}; + var hasSet = utils.isFunction(target.set) || utils.isFunction(target._set); + utils.forOwn(properties, function (schema, prop) { + if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) { + if (hasSet) { + target.set(prop, utils.plainCopy(schema['default']), { silent: true }); + } else { + utils.set(target, prop, utils.plainCopy(schema['default'])); } - if (canAutoAddLinks) { - relatedRecord = relatedCollection.add(relatedRecord); + } + if (schema.type === 'object' && schema.properties) { + if (hasSet) { + var orig = target._get('noValidate'); + target._set('noValidate', true); + utils.set(target, prop, utils.get(target, prop) || {}, { silent: true }); + target._set('noValidate', orig); + } else { + utils.set(target, prop, utils.get(target, prop) || {}); } + schema.applyDefaults(utils.get(target, prop)); } - - return relatedRecord; - }); - }, - findExistingLinksFor: function findExistingLinksFor(record) { - var id = utils.get(record, this.mapper.idAttribute); - var ids = this.localKeys ? utils.get(record, this.localKeys) : null; - var records = void 0; - - if (id !== undefined && this.foreignKey) { - records = this.findExistingLinksByForeignKey(id); - } else if (this.localKeys && ids) { - records = this.findExistingLinksByLocalKeys(ids); - } else if (id !== undefined && this.foreignKeys) { - records = this.findExistingLinksByForeignKeys(id); - } - - if (records && records.length) { - return records; - } - }, - - - // e.g. user hasMany group via "foreignKeys", so find all users of a group - findExistingLinksByLocalKeys: function findExistingLinksByLocalKeys(ids) { - return this.relatedCollection.filter({ - where: defineProperty({}, this.mapper.idAttribute, { - 'in': ids - }) }); }, - // e.g. group hasMany user via "localKeys", so find all groups that own a user - findExistingLinksByForeignKeys: function findExistingLinksByForeignKeys(id) { - return this.relatedCollection.filter({ - where: defineProperty({}, this.foreignKeys, { - 'contains': id - }) - }); - } - }, { - TYPE_NAME: 'hasMany' - }); - - var HasOneRelation = Relation.extend({ - findExistingLinksFor: function findExistingLinksFor(relatedMapper, record) { - var recordId = utils.get(record, relatedMapper.idAttribute); - var records = this.findExistingLinksByForeignKey(recordId); - - if (records.length) { - return records[0]; - } + /** + * Validate the provided value against this schema. + * + * @name Schema#validate + * @method + * @param {*} value Value to validate. + * @param {Object} [opts] Configuration options. + * @returns {(array|undefined)} Array of errors or `undefined` if valid. + */ + validate: function validate(value, opts) { + return _validate(value, this, opts); } }, { - TYPE_NAME: 'hasOne' - }); - - [BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) { - Relation[RelationType.TYPE_NAME] = function (related, options) { - return new RelationType(related, options); - }; + ANY_OPS: ANY_OPS, + ARRAY_OPS: ARRAY_OPS, + NUMERIC_OPS: NUMERIC_OPS, + OBJECT_OPS: OBJECT_OPS, + STRING_OPS: STRING_OPS, + typeGroupValidators: typeGroupValidators, + types: types, + validate: _validate, + validationKeywords: validationKeywords }); - /** - * BelongsTo relation decorator. You probably won't use this directly. - * - * @name module:js-data.belongsTo - * @method - * @param {Mapper} related The relation the target belongs to. - * @param {Object} opts Configuration options. - * @param {string} opts.foreignKey The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ - var belongsTo = function belongsTo(related, opts) { - return function (mapper) { - Relation.belongsTo(related, opts).assignTo(mapper); - }; - }; - - /** - * HasMany relation decorator. You probably won't use this directly. - * - * @name module:js-data.hasMany - * @method - * @param {Mapper} related The relation of which the target has many. - * @param {Object} opts Configuration options. - * @param {string} [opts.foreignKey] The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ - var hasMany = function hasMany(related, opts) { - return function (mapper) { - Relation.hasMany(related, opts).assignTo(mapper); - }; - }; - - /** - * HasOne relation decorator. You probably won't use this directly. - * - * @name module:js-data.hasOne - * @method - * @param {Mapper} related The relation of which the target has one. - * @param {Object} opts Configuration options. - * @param {string} [opts.foreignKey] The field that holds the primary key of the - * related record. - * @param {string} opts.localField The field that holds a reference to the - * related record object. - * @returns {Function} Invocation function, which accepts the target as the only - * parameter. - */ - var hasOne = function hasOne(related, opts) { - return function (mapper) { - Relation.hasOne(related, opts).assignTo(mapper); - }; - }; - var DOMAIN$4 = 'Mapper'; var applyDefaultsHooks = ['beforeCreate', 'beforeCreateMany']; var validatingHooks = ['beforeCreate', 'beforeCreateMany', 'beforeUpdate', 'beforeUpdateAll', 'beforeUpdateMany']; @@ -10893,8 +10932,6 @@ } if (mapper.relationList.length && record) { - // Check the currently visited record for relations that need to be - // inserted into their respective collections. mapper.relationList.forEach(function (def) { def.removeLinkedRecords(mapper, [record]); }); @@ -10908,8 +10945,6 @@ records.forEach(this._clearMeta, this); if (mapper.relationList.length && records.length) { - // Check the currently visited record for relations that need to be - // inserted into their respective collections. mapper.relationList.forEach(function (def) { def.removeLinkedRecords(mapper, records); }); @@ -11219,22 +11254,6 @@ 'unsaved']; var ownMethodsForScoping = ['addToCache', 'cachedFind', 'cachedFindAll', 'cacheFind', 'cacheFindAll', 'hashQuery']; - var safeSetProp = function safeSetProp(record, field, value) { - if (record && record._set) { - record._set('props.' + field, value); - } else { - utils.set(record, field, value); - } - }; - - var safeSetLink = function safeSetLink(record, field, value) { - if (record && record._set) { - record._set('links.' + field, value); - } else { - utils.set(record, field, value); - } - }; - var cachedFn = function cachedFn(name, hashOrId, opts) { var cached = this._completedQueries[name][hashOrId]; if (utils.isFunction(cached)) { @@ -11352,15 +11371,6 @@ var props$1 = { constructor: DataStore, - _callSuper: function _callSuper(method) { - for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) { - args[_key2 - 1] = arguments[_key2]; - } - - return this.constructor.__super__.prototype[method].apply(this, args); - }, - - /** * Internal method used to handle Mapper responses. * @@ -11432,8 +11442,8 @@ * @param {...*} [args] Args passed to {@link Collection#emit}. */ _onCollectionEvent: function _onCollectionEvent(name) { - for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key3 = 1; _key3 < _len2; _key3++) { - args[_key3 - 1] = arguments[_key3]; + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key2 = 1; _key2 < _len; _key2++) { + args[_key2 - 1] = arguments[_key2]; } var type = args.shift(); @@ -11522,8 +11532,8 @@ props[method] = { writable: true, value: function value() { - for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { - args[_key4] = arguments[_key4]; + for (var _len2 = arguments.length, args = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) { + args[_key3] = arguments[_key3]; } return original[method].apply(original, [name].concat(args)); @@ -11860,7 +11870,7 @@ var _this4 = this; opts || (opts = {}); - return this._callSuper('create', name, record, opts).then(function (result) { + return Container.prototype.create.call(this, name, record, opts).then(function (result) { return _this4._end(name, result, opts); }); }, @@ -11961,7 +11971,7 @@ var _this5 = this; opts || (opts = {}); - return this._callSuper('createMany', name, records, opts).then(function (result) { + return Container.prototype.createMany.call(this, name, records, opts).then(function (result) { return _this5._end(name, result, opts); }); }, @@ -12001,8 +12011,8 @@ }); collection.on('all', function () { - for (var _len4 = arguments.length, args = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) { - args[_key5] = arguments[_key5]; + for (var _len3 = arguments.length, args = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) { + args[_key4] = arguments[_key4]; } self._onCollectionEvent.apply(self, [name].concat(args)); @@ -12034,8 +12044,6 @@ // e.g. profile.user = someUser // or comment.post = somePost set: function set(record) { - var _this6 = this; - // e.g. const otherUser = profile.user var currentParent = this._get(path); // e.g. profile.user === someUser @@ -12047,23 +12055,8 @@ // e.g. profile.user !== someUser // or comment.post !== somePost - if (currentParent) { - // e.g. otherUser.profile = undefined - if (inverseDef.type === hasOneType) { - safeSetLink(currentParent, inverseDef.localField, undefined); - } else if (inverseDef.type === hasManyType) { - // e.g. remove comment from otherPost.comments - var children = utils.get(currentParent, inverseDef.localField); - if (id === undefined) { - utils.remove(children, function (child) { - return child === _this6; - }); - } else { - utils.remove(children, function (child) { - return child === _this6 || id === utils.get(child, idAttribute); - }); - } - } + if (currentParent && inverseDef) { + this.removeInverseRelation(currentParent, id, inverseDef, idAttribute); } if (record) { // e.g. profile.user = someUser @@ -12082,22 +12075,8 @@ safeSetProp(this, foreignKey, relatedId); collection.updateIndex(this, updateOpts); - // Update (set) inverse relation - if (inverseDef.type === hasOneType) { - // e.g. someUser.profile = profile - safeSetLink(record, inverseDef.localField, this); - } else if (inverseDef.type === hasManyType) { - // e.g. add comment to somePost.comments - var _children = utils.get(record, inverseDef.localField); - if (id === undefined) { - utils.noDupeAdd(_children, this, function (child) { - return child === _this6; - }); - } else { - utils.noDupeAdd(_children, this, function (child) { - return child === _this6 || id === utils.get(child, idAttribute); - }); - } + if (inverseDef) { + this.setupInverseRelation(record, id, inverseDef, idAttribute); } } else { // Unset in-memory link only @@ -12124,7 +12103,7 @@ }; var originalSet = foreignKeyDescriptor.set; foreignKeyDescriptor.set = function (value) { - var _this7 = this; + var _this6 = this; if (originalSet) { originalSet.call(this, value); @@ -12141,11 +12120,11 @@ var children = utils.get(currentParent, inverseDef.localField); if (id === undefined) { utils.remove(children, function (child) { - return child === _this7; + return child === _this6; }); } else { utils.remove(children, function (child) { - return child === _this7 || id === utils.get(child, idAttribute); + return child === _this6 || id === utils.get(child, idAttribute); }); } } @@ -12191,7 +12170,7 @@ // or user.groups = someGroups // or group.users = someUsers set: function set(records) { - var _this8 = this; + var _this7 = this; if (records && !utils.isArray(records)) { records = [records]; @@ -12209,7 +12188,7 @@ // e.g. comment.id var relatedId = utils.get(record, relatedIdAttribute); var currentParent = utils.get(record, inverseLocalField); - if (currentParent && currentParent !== _this8) { + if (currentParent && currentParent !== _this7) { var currentChildrenOfParent = utils.get(currentParent, localField); // e.g. somePost.comments.remove(comment) if (relatedId === undefined) { @@ -12223,7 +12202,7 @@ } } if (relatedId !== undefined) { - if (_this8._get('$')) { + if (_this7._get('$')) { // Prefer store record record = self.get(relation, relatedId) || record; } @@ -12258,7 +12237,7 @@ // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' }) self.getCollection(relation).updateIndex(record, updateOpts); // e.g. comment.post = post - safeSetLink(record, inverseLocalField, _this8); + safeSetLink(record, inverseLocalField, _this7); }); } else if (localKeys) { // Update locals @@ -12282,11 +12261,11 @@ // e.g. someUser.groups.remove(group) if (id === undefined) { utils.remove(parents, function (parent) { - return parent === _this8; + return parent === _this7; }); } else { utils.remove(parents, function (parent) { - return parent === _this8 || id === utils.get(parent, idAttribute); + return parent === _this7 || id === utils.get(parent, idAttribute); }); } } @@ -12296,12 +12275,12 @@ var parents = utils.get(child, inverseLocalField); // e.g. someUser.groups.push(group) if (id === undefined) { - utils.noDupeAdd(parents, _this8, function (parent) { - return parent === _this8; + utils.noDupeAdd(parents, _this7, function (parent) { + return parent === _this7; }); } else { - utils.noDupeAdd(parents, _this8, function (parent) { - return parent === _this8 || id === utils.get(parent, idAttribute); + utils.noDupeAdd(parents, _this7, function (parent) { + return parent === _this7 || id === utils.get(parent, idAttribute); }); } }); @@ -12319,11 +12298,11 @@ // e.g. someGroup.users.remove(user) if (id === undefined) { utils.remove(children, function (child) { - return child === _this8; + return child === _this7; }); } else { utils.remove(children, function (child) { - return child === _this8 || id === utils.get(child, idAttribute); + return child === _this7 || id === utils.get(child, idAttribute); }); } }); @@ -12335,12 +12314,12 @@ }); var children = utils.get(parent, inverseLocalField); if (id === undefined) { - utils.noDupeAdd(children, _this8, function (child) { - return child === _this8; + utils.noDupeAdd(children, _this7, function (child) { + return child === _this7; }); } else { - utils.noDupeAdd(children, _this8, function (child) { - return child === _this8 || id === utils.get(child, idAttribute); + utils.noDupeAdd(children, _this7, function (child) { + return child === _this7 || id === utils.get(child, idAttribute); }); } }); @@ -12365,13 +12344,13 @@ return current; } var inverseLocalField = def.getInverse(mapper).localField; + // Update (unset) inverse relation + if (current) { + safeSetProp(current, foreignKey, undefined); + self.getCollection(relation).updateIndex(current, updateOpts); + safeSetLink(current, inverseLocalField, undefined); + } if (record) { - // Update (unset) inverse relation - if (current) { - safeSetProp(current, foreignKey, undefined); - self.getCollection(relation).updateIndex(current, updateOpts); - safeSetLink(current, inverseLocalField, undefined); - } var relatedId = utils.get(record, def.getRelation().idAttribute); // Prefer store record if (relatedId !== undefined) { @@ -12400,14 +12379,14 @@ (function () { var origGet = descriptor.get; descriptor.get = function () { - var _this9 = this; + var _this8 = this; return def.get(def, this, function () { - for (var _len5 = arguments.length, args = Array(_len5), _key6 = 0; _key6 < _len5; _key6++) { - args[_key6] = arguments[_key6]; + for (var _len4 = arguments.length, args = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) { + args[_key5] = arguments[_key5]; } - return origGet.apply(_this9, args); + return origGet.apply(_this8, args); }); }; })(); @@ -12416,10 +12395,10 @@ (function () { var origSet = descriptor.set; descriptor.set = function (related) { - var _this10 = this; + var _this9 = this; return def.set(def, this, related, function (value) { - return origSet.call(_this10, value === undefined ? related : value); + return origSet.call(_this9, value === undefined ? related : value); }); }; })(); @@ -12524,16 +12503,16 @@ * @since 3.0.0 */ destroy: function destroy(name, id, opts) { - var _this11 = this; + var _this10 = this; opts || (opts = {}); - return this._callSuper('destroy', name, id, opts).then(function (result) { - var record = _this11.getCollection(name).remove(id, opts); + return Container.prototype.destroy.call(this, name, id, opts).then(function (result) { + var record = _this10.getCollection(name).remove(id, opts); - if (record && _this11.unlinkOnDestroy) { + if (record && _this10.unlinkOnDestroy) { var _opts = utils.plainCopy(opts); _opts.withAll = true; - utils.forEachRelation(_this11.getMapper(name), _opts, function (def) { + utils.forEachRelation(_this10.getMapper(name), _opts, function (def) { utils.set(record, def.localField, undefined); }); } @@ -12543,8 +12522,8 @@ } else { result = record; } - delete _this11._pendingQueries[name][id]; - delete _this11._completedQueries[name][id]; + delete _this10._pendingQueries[name][id]; + delete _this10._completedQueries[name][id]; return result; }); }, @@ -12640,16 +12619,16 @@ * @since 3.0.0 */ destroyAll: function destroyAll(name, query, opts) { - var _this12 = this; + var _this11 = this; opts || (opts = {}); - return this._callSuper('destroyAll', name, query, opts).then(function (result) { - var records = _this12.getCollection(name).removeAll(query, opts); + return Container.prototype.destroyAll.call(this, name, query, opts).then(function (result) { + var records = _this11.getCollection(name).removeAll(query, opts); - if (records && records.length && _this12.unlinkOnDestroy) { + if (records && records.length && _this11.unlinkOnDestroy) { var _opts = utils.plainCopy(opts); _opts.withAll = true; - utils.forEachRelation(_this12.getMapper(name), _opts, function (def) { + utils.forEachRelation(_this11.getMapper(name), _opts, function (def) { records.forEach(function (record) { utils.set(record, def.localField, undefined); }); @@ -12661,9 +12640,9 @@ } else { result = records; } - var hash = _this12.hashQuery(name, query, opts); - delete _this12._pendingQueries[name][hash]; - delete _this12._completedQueries[name][hash]; + var hash = _this11.hashQuery(name, query, opts); + delete _this11._pendingQueries[name][hash]; + delete _this11._completedQueries[name][hash]; return result; }); }, @@ -12760,7 +12739,7 @@ * @since 3.0.0 */ find: function find(name, id, opts) { - var _this13 = this; + var _this12 = this; opts || (opts = {}); var mapper = this.getMapper(name); @@ -12775,13 +12754,13 @@ var promise = void 0; if (opts.force || !item) { - promise = this._pendingQueries[name][id] = this._callSuper('find', name, id, opts).then(function (result) { - delete _this13._pendingQueries[name][id]; - result = _this13._end(name, result, opts); - _this13.cacheFind(name, result, id, opts); + promise = this._pendingQueries[name][id] = Container.prototype.find.call(this, name, id, opts).then(function (result) { + delete _this12._pendingQueries[name][id]; + result = _this12._end(name, result, opts); + _this12.cacheFind(name, result, id, opts); return result; }, function (err) { - delete _this13._pendingQueries[name][id]; + delete _this12._pendingQueries[name][id]; return utils.reject(err); }); } else { @@ -12874,7 +12853,7 @@ * @since 3.0.0 */ findAll: function findAll(name, query, opts) { - var _this14 = this; + var _this13 = this; opts || (opts = {}); var mapper = this.getMapper(name); @@ -12891,13 +12870,13 @@ var promise = void 0; if (opts.force || !items) { - promise = this._pendingQueries[name][hash] = this._callSuper('findAll', name, query, opts).then(function (result) { - delete _this14._pendingQueries[name][hash]; - result = _this14._end(name, result, opts); - _this14.cacheFindAll(name, result, hash, opts); + promise = this._pendingQueries[name][hash] = Container.prototype.findAll.call(this, name, query, opts).then(function (result) { + delete _this13._pendingQueries[name][hash]; + result = _this13._end(name, result, opts); + _this13.cacheFindAll(name, result, hash, opts); return result; }, function (err) { - delete _this14._pendingQueries[name][hash]; + delete _this13._pendingQueries[name][hash]; return utils.reject(err); }); } else { @@ -13048,7 +13027,7 @@ * @since 3.0.0 */ removeRelated: function removeRelated(name, records, opts) { - var _this15 = this; + var _this14 = this; if (!utils.isArray(records)) { records = [records]; @@ -13072,10 +13051,10 @@ }) }; } else if (def.type === belongsToType) { - relatedData = _this15.remove(def.relation, def.getForeignKey(record), optsCopy); + relatedData = _this14.remove(def.relation, def.getForeignKey(record), optsCopy); } if (query) { - relatedData = _this15.removeAll(def.relation, query, optsCopy); + relatedData = _this14.removeAll(def.relation, query, optsCopy); } if (relatedData) { if (utils.isArray(relatedData) && !relatedData.length) { @@ -13178,11 +13157,11 @@ * @since 3.0.0 */ update: function update(name, id, record, opts) { - var _this16 = this; + var _this15 = this; opts || (opts = {}); - return this._callSuper('update', name, id, record, opts).then(function (result) { - return _this16._end(name, result, opts); + return Container.prototype.update.call(this, name, id, record, opts).then(function (result) { + return _this15._end(name, result, opts); }); }, @@ -13274,11 +13253,11 @@ * @since 3.0.0 */ updateAll: function updateAll(name, props, query, opts) { - var _this17 = this; + var _this16 = this; opts || (opts = {}); - return this._callSuper('updateAll', name, query, props, opts).then(function (result) { - return _this17._end(name, result, opts); + return Container.prototype.updateAll.call(this, name, query, props, opts).then(function (result) { + return _this16._end(name, result, opts); }); }, @@ -13370,11 +13349,11 @@ * @since 3.0.0 */ updateMany: function updateMany(name, records, opts) { - var _this18 = this; + var _this17 = this; opts || (opts = {}); - return this._callSuper('updateMany', name, records, opts).then(function (result) { - return _this18._end(name, result, opts); + return Container.prototype.updateMany.call(this, name, records, opts).then(function (result) { + return _this17._end(name, result, opts); }); } }; @@ -13383,8 +13362,8 @@ props$1[method] = function (name) { var _getCollection; - for (var _len6 = arguments.length, args = Array(_len6 > 1 ? _len6 - 1 : 0), _key7 = 1; _key7 < _len6; _key7++) { - args[_key7 - 1] = arguments[_key7]; + for (var _len5 = arguments.length, args = Array(_len5 > 1 ? _len5 - 1 : 0), _key6 = 1; _key6 < _len5; _key6++) { + args[_key6 - 1] = arguments[_key6]; } return (_getCollection = this.getCollection(name))[method].apply(_getCollection, args); @@ -13441,7 +13420,7 @@ * @type {Object} */ var version = { - full: '3.0.0-rc.3', + full: '3.0.0-rc.4', major: 3, minor: 0, patch: 0 diff --git a/dist/js-data.js.map b/dist/js-data.js.map index 961383c0..a4b20d35 100644 --- a/dist/js-data.js.map +++ b/dist/js-data.js.map @@ -1 +1 @@ -{"version":3,"file":null,"sources":["../src/utils.js","../src/Settable.js","../src/Component.js","../src/Query.js","../lib/mindex/_utils.js","../lib/mindex/index.js","../src/Collection.js","../src/Record.js","../src/Schema.js","../src/Relation.js","../src/Relation/BelongsTo.js","../src/Relation/HasMany.js","../src/Relation/HasOne.js","../src/relations.js","../src/decorators.js","../src/Mapper.js","../src/Container.js","../src/LinkedCollection.js","../src/DataStore.js","../src/index.js"],"sourcesContent":["/**\n * Utility methods used by JSData.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @namespace utils\n * @type {Object}\n */\n\nconst DOMAIN = 'utils'\n\nconst INFINITY = 1 / 0\nconst MAX_INTEGER = 1.7976931348623157e+308\nconst BOOL_TAG = '[object Boolean]'\nconst DATE_TAG = '[object Date]'\nconst FUNC_TAG = '[object Function]'\nconst NUMBER_TAG = '[object Number]'\nconst OBJECT_TAG = '[object Object]'\nconst REGEXP_TAG = '[object RegExp]'\nconst STRING_TAG = '[object String]'\nconst objToString = Object.prototype.toString\nconst PATH = /^(.+)\\.(.+)$/\n\nconst ERRORS = {\n '400' () { return `expected: ${arguments[0]}, found: ${arguments[2] ? arguments[1] : typeof arguments[1]}` },\n '404' () { return `${arguments[0]} not found` }\n}\n\nconst toInteger = function (value) {\n if (!value) {\n return 0\n }\n // Coerce to number\n value = +value\n if (value === INFINITY || value === -INFINITY) {\n const sign = (value < 0 ? -1 : 1)\n return sign * MAX_INTEGER\n }\n const remainder = value % 1\n return value === value ? (remainder ? value - remainder : value) : 0 // eslint-disable-line\n}\n\nconst toStr = function (value) {\n return objToString.call(value)\n}\n\nconst isPlainObject = function (value) {\n return (!!value && typeof value === 'object' && value.constructor === Object)\n}\n\nconst mkdirP = function (object, path) {\n if (!path) {\n return object\n }\n const parts = path.split('.')\n parts.forEach(function (key) {\n if (!object[key]) {\n object[key] = {}\n }\n object = object[key]\n })\n return object\n}\n\nconst utils = {\n /**\n * Reference to the Promise constructor used by JSData. Defaults to\n * `window.Promise` or `global.Promise`.\n *\n * @example Make JSData use a different `Promise` constructor\n * import Promise from 'bluebird'\n * import {utils} from 'js-data'\n * utils.Promise = Promise\n *\n * @name utils.Promise\n * @since 3.0.0\n * @type {Function}\n */\n Promise: Promise,\n\n /**\n * Shallow copy properties that meet the following criteria from `src` to\n * `dest`:\n *\n * - own enumerable\n * - not a function\n * - does not start with \"_\"\n *\n * @method utils._\n * @param {Object} dest Destination object.\n * @param {Object} src Source object.\n * @private\n * @since 3.0.0\n */\n _ (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (key && dest[key] === undefined && !utils.isFunction(value) && key.indexOf('_') !== 0) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Recursively iterates over relations found in `opts.with`.\n *\n * @method utils._forRelation\n * @param {Object} opts Configuration options.\n * @param {Relation} def Relation definition.\n * @param {Function} fn Callback function.\n * @param {*} [thisArg] Execution context for the callback function.\n * @private\n * @since 3.0.0\n */\n _forRelation (opts, def, fn, thisArg) {\n const relationName = def.relation\n let containedName = null\n let index\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n if ((index = utils._getIndex(opts.with, relationName)) >= 0) {\n containedName = relationName\n } else if ((index = utils._getIndex(opts.with, def.localField)) >= 0) {\n containedName = def.localField\n }\n\n if (opts.withAll) {\n fn.call(thisArg, def, {})\n return\n } else if (!containedName) {\n return\n }\n let optsCopy = {}\n utils.fillIn(optsCopy, def.getRelation())\n utils.fillIn(optsCopy, opts)\n optsCopy.with = opts.with.slice()\n optsCopy._activeWith = optsCopy.with.splice(index, 1)[0]\n optsCopy.with.forEach(function (relation, i) {\n if (relation && relation.indexOf(containedName) === 0 && relation.length >= containedName.length && relation[containedName.length] === '.') {\n optsCopy.with[i] = relation.substr(containedName.length + 1)\n } else {\n optsCopy.with[i] = ''\n }\n })\n fn.call(thisArg, def, optsCopy)\n },\n\n /**\n * Find the index of a relation in the given list\n *\n * @method utils._getIndex\n * @param {string[]} list List to search.\n * @param {string} relation Relation to find.\n * @private\n * @returns {number}\n */\n _getIndex (list, relation) {\n let index = -1\n list.forEach(function (_relation, i) {\n if (_relation === relation) {\n index = i\n return false\n } else if (utils.isObject(_relation)) {\n if (_relation.relation === relation) {\n index = i\n return false\n }\n }\n })\n return index\n },\n\n /**\n * Define hidden (non-enumerable), writable properties on `target` from the\n * provided `props`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {}\n * utils.addHiddenPropsToTarget(Cat.prototype, {\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat.say() // \"meow\"\n *\n * @method utils.addHiddenPropsToTarget\n * @param {Object} target That to which `props` should be added.\n * @param {Object} props Properties to be added to `target`.\n * @since 3.0.0\n */\n addHiddenPropsToTarget (target, props) {\n const map = {}\n Object.keys(props).forEach(function (propName) {\n const descriptor = Object.getOwnPropertyDescriptor(props, propName)\n\n descriptor.enumerable = false\n map[propName] = descriptor\n })\n Object.defineProperties(target, map)\n },\n\n /**\n * Return whether the two objects are deeply different.\n *\n * @example\n * import {utils} from 'js-data'\n * utils.areDifferent({}, {}) // false\n * utils.areDifferent({ a: 1 }, { a: 1 }) // false\n * utils.areDifferent({ foo: 'bar' }, {}) // true\n *\n * @method utils.areDifferent\n * @param {Object} a Base object.\n * @param {Object} b Comparison object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Whether the two objects are deeply different.\n * @see utils.diffObjects\n * @since 3.0.0\n */\n areDifferent (newObject, oldObject, opts) {\n opts || (opts = {})\n const diff = utils.diffObjects(newObject, oldObject, opts)\n const diffCount = Object.keys(diff.added).length +\n Object.keys(diff.removed).length +\n Object.keys(diff.changed).length\n return diffCount > 0\n },\n\n /**\n * Verified that the given constructor is being invoked via `new`, as opposed\n * to just being called like a normal function.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {\n * utils.classCallCheck(this, Cat)\n * }\n * const cat = new Cat() // this is ok\n * Cat() // this throws an error\n *\n * @method utils.classCallCheck\n * @param {*} instance Instance that is being constructed.\n * @param {Constructor} ctor Constructor function used to construct the\n * instance.\n * @since 3.0.0\n * @throws {Error} Throws an error if the constructor is being improperly\n * invoked.\n */\n classCallCheck (instance, ctor) {\n if (!(instance instanceof ctor)) {\n throw utils.err(`${ctor.name}`)(500, 'Cannot call a class as a function')\n }\n },\n\n /**\n * Deep copy a value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' } }\n * const b = utils.copy(a)\n * a === b // false\n * utils.areDifferent(a, b) // false\n *\n * @param {*} from Value to deep copy.\n * @param {*} [to] Destination object for the copy operation.\n * @param {*} [stackFrom] For internal use.\n * @param {*} [stackTo] For internal use.\n * @param {string[]|RegExp[]} [blacklist] List of strings or RegExp of\n * properties to skip.\n * @param {boolean} [plain] Whether to make a plain copy (don't try to use\n * original prototype).\n * @returns {*} Deep copy of `from`.\n * @since 3.0.0\n */\n copy (from, to, stackFrom, stackTo, blacklist, plain) {\n if (!to) {\n to = from\n if (from) {\n if (utils.isArray(from)) {\n to = utils.copy(from, [], stackFrom, stackTo, blacklist, plain)\n } else if (utils.isDate(from)) {\n to = new Date(from.getTime())\n } else if (utils.isRegExp(from)) {\n to = new RegExp(from.source, from.toString().match(/[^\\/]*$/)[0])\n to.lastIndex = from.lastIndex\n } else if (utils.isObject(from)) {\n if (plain) {\n to = utils.copy(from, {}, stackFrom, stackTo, blacklist, plain)\n } else {\n to = utils.copy(from, Object.create(Object.getPrototypeOf(from)), stackFrom, stackTo, blacklist, plain)\n }\n }\n }\n } else {\n if (from === to) {\n throw utils.err(`${DOMAIN}.copy`)(500, 'Cannot copy! Source and destination are identical.')\n }\n\n stackFrom = stackFrom || []\n stackTo = stackTo || []\n\n if (utils.isObject(from)) {\n let index = stackFrom.indexOf(from)\n if (index !== -1) {\n return stackTo[index]\n }\n\n stackFrom.push(from)\n stackTo.push(to)\n }\n\n let result\n if (utils.isArray(from)) {\n let i\n to.length = 0\n for (i = 0; i < from.length; i++) {\n result = utils.copy(from[i], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[i])) {\n stackFrom.push(from[i])\n stackTo.push(result)\n }\n to.push(result)\n }\n } else {\n if (utils.isArray(to)) {\n to.length = 0\n } else {\n utils.forOwn(to, function (value, key) {\n delete to[key]\n })\n }\n for (var key in from) {\n if (from.hasOwnProperty(key)) {\n if (utils.isBlacklisted(key, blacklist)) {\n continue\n }\n result = utils.copy(from[key], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[key])) {\n stackFrom.push(from[key])\n stackTo.push(result)\n }\n to[key] = result\n }\n }\n }\n }\n return to\n },\n\n /**\n * Recursively shallow fill in own enumerable properties from `source` to\n * `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"bip\"}\n *\n * @method utils.deepFillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n deepFillIn (dest, source) {\n if (source) {\n utils.forOwn(source, function (value, key) {\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepFillIn(existing, value)\n } else if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n }\n return dest\n },\n\n /**\n * Recursively shallow copy enumerable properties from `source` to `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"boop\"}\n *\n * @method utils.deepMixIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepFillIn\n * @since 3.0.0\n */\n deepMixIn (dest, source) {\n if (source) {\n for (var key in source) {\n const value = source[key]\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepMixIn(existing, value)\n } else {\n dest[key] = value\n }\n }\n }\n return dest\n },\n\n /**\n * Return a diff of the base object to the comparison object.\n *\n * @example\n * import {utils} from 'js-data'\n * const oldObject = { foo: 'bar', a: 1234 }\n * const newObject = { beep: 'boop', a: 5678 }\n * const diff = utils.diffObjects(oldObject, newObject)\n * console.log(diff.added) // {\"beep\":\"boop\"}\n * console.log(diff.changed) // {\"a\":5678}\n * console.log(diff.removed) // {\"foo\":undefined}\n *\n * @method utils.diffObjects\n * @param {Object} newObject Comparison object.\n * @param {Object} oldObject Base object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} The diff from the base object to the comparison object.\n * @see utils.areDifferent\n * @since 3.0.0\n */\n diffObjects (newObject, oldObject, opts) {\n opts || (opts = {})\n let equalsFn = opts.equalsFn\n let blacklist = opts.ignore\n const diff = {\n added: {},\n changed: {},\n removed: {}\n }\n if (!utils.isFunction(equalsFn)) {\n equalsFn = utils.deepEqual\n }\n\n const newKeys = Object.keys(newObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n const oldKeys = Object.keys(oldObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n\n // Check for properties that were added or changed\n newKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (equalsFn(oldValue, newValue)) {\n return\n }\n if (oldValue === undefined) {\n diff.added[key] = newValue\n } else {\n diff.changed[key] = newValue\n }\n })\n\n // Check for properties that were removed\n oldKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (newValue === undefined && oldValue !== undefined) {\n diff.removed[key] = undefined\n }\n })\n\n return diff\n },\n\n /**\n * Return whether the two values are equal according to the `==` operator.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.equal(1,1)) // true\n * console.log(utils.equal(1,'1')) // true\n * console.log(utils.equal(93, 66)) // false\n *\n * @method utils.equal\n * @param {*} a First value in the comparison.\n * @param {*} b Second value in the comparison.\n * @returns {boolean} Whether the two values are equal according to `==`.\n * @since 3.0.0\n */\n equal (a, b) {\n return a == b // eslint-disable-line\n },\n\n /**\n * Produce a factory function for making Error objects with the provided\n * metadata. Used throughout the various js-data components.\n *\n * @example\n * import {utils} from 'js-data'\n * const errorFactory = utils.err('domain', 'target')\n * const error400 = errorFactory(400, 'expected type', 'actual type')\n * console.log(error400) // [Error: [domain:target] expected: expected type, found: string\nhttp://www.js-data.io/v3.0/docs/errors#400]\n * @method utils.err\n * @param {string} domain Namespace.\n * @param {string} target Target.\n * @returns {Function} Factory function.\n * @since 3.0.0\n */\n err (domain, target) {\n return function (code) {\n const prefix = `[${domain}:${target}] `\n let message = ERRORS[code].apply(null, Array.prototype.slice.call(arguments, 1))\n message = `${prefix}${message}\nhttp://www.js-data.io/v3.0/docs/errors#${code}`\n return new Error(message)\n }\n },\n\n /**\n * Add eventing capabilities into the target object.\n *\n * @example\n * import {utils} from 'js-data'\n * const user = { name: 'John' }\n * utils.eventify(user)\n * user.on('foo', () => console.log(arguments))\n * user.emit('foo', 1, 'bar') // should log to console values (1, \"bar\")\n *\n * @method utils.eventify\n * @param {Object} target Target object.\n * @param {Function} [getter] Custom getter for retrieving the object's event\n * listeners.\n * @param {Function} [setter] Custom setter for setting the object's event\n * listeners.\n * @since 3.0.0\n */\n eventify (target, getter, setter) {\n target = target || this\n let _events = {}\n if (!getter && !setter) {\n getter = function () { return _events }\n setter = function (value) { _events = value }\n }\n Object.defineProperties(target, {\n emit: {\n value (...args) {\n const events = getter.call(this) || {}\n const type = args.shift()\n let listeners = events[type] || []\n let i\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n listeners = events.all || []\n args.unshift(type)\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n }\n },\n off: {\n value (type, func) {\n const events = getter.call(this)\n const listeners = events[type]\n if (!listeners) {\n setter.call(this, {})\n } else if (func) {\n for (let i = 0; i < listeners.length; i++) {\n if (listeners[i].f === func) {\n listeners.splice(i, 1)\n break\n }\n }\n } else {\n listeners.splice(0, listeners.length)\n }\n }\n },\n on: {\n value (type, func, thisArg) {\n if (!getter.call(this)) {\n setter.call(this, {})\n }\n const events = getter.call(this)\n events[type] = events[type] || []\n events[type].push({\n c: thisArg,\n f: func\n })\n }\n }\n })\n },\n\n /**\n * Used for sublcassing. Invoke this method in the context of a superclass to\n * to produce a subclass based on `props` and `classProps`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Animal () {}\n * Animal.extend = utils.extend\n * const Cat = Animal.extend({\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat instanceof Animal // true\n * cat instanceof Cat // true\n * cat.say() // \"meow\"\n *\n * @method utils.extend\n * @param {Object} props Instance properties for the subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to use as the subclass.\n * @param {Object} props Static properties for the subclass.\n * @returns {Constructor} A new subclass.\n * @since 3.0.0\n */\n extend (props, classProps) {\n const superClass = this\n let subClass\n\n props || (props = {})\n classProps || (classProps = {})\n\n if (props.hasOwnProperty('constructor')) {\n subClass = props.constructor\n delete props.constructor\n } else {\n subClass = function (...args) {\n utils.classCallCheck(this, subClass)\n superClass.apply(this, args)\n }\n }\n\n // Setup inheritance of instance members\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n configurable: true,\n enumerable: false,\n value: subClass,\n writable: true\n }\n })\n\n const obj = Object\n // Setup inheritance of static members\n if (obj.setPrototypeOf) {\n obj.setPrototypeOf(subClass, superClass)\n } else if (classProps.strictEs6Class) {\n subClass.__proto__ = superClass // eslint-disable-line\n } else {\n utils.forOwn(superClass, function (value, key) {\n subClass[key] = value\n })\n }\n if (!subClass.hasOwnProperty('__super__')) {\n Object.defineProperty(subClass, '__super__', {\n configurable: true,\n value: superClass\n })\n }\n\n utils.addHiddenPropsToTarget(subClass.prototype, props)\n utils.fillIn(subClass, classProps)\n\n return subClass\n },\n\n /**\n * Shallow copy own enumerable properties from `src` to `dest` that are on\n * `src` but are missing from `dest.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: 'bar', beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.fillIn(b, a)\n * console.log(b) // {\"foo\":\"bar\",\"beep\":\"bip\"}\n *\n * @method utils.fillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.deepFillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n fillIn (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Find the last index of an item in an array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = { name: 'John', age: 20 }\n * const sara = { name: 'Sara', age: 25 }\n * const dan = { name: 'Dan', age: 20 }\n * const users = [john, sara, dan]\n *\n * console.log(utils.findIndex(users, (user) => user.age === 25)) // 1\n * console.log(utils.findIndex(users, (user) => user.age > 19)) // 2\n * console.log(utils.findIndex(users, (user) => user.name === 'John')) // 0\n * console.log(utils.findIndex(users, (user) => user.name === 'Jimmy')) // -1\n *\n * @method utils.findIndex\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n * @returns {number} Index if found or -1 if not found.\n * @since 3.0.0\n */\n findIndex (array, fn) {\n let index = -1\n if (!array) {\n return index\n }\n array.forEach(function (record, i) {\n if (fn(record)) {\n index = i\n return false\n }\n })\n return index\n },\n\n /**\n * Recursively iterate over a {@link Mapper}'s relations according to\n * `opts.with`.\n *\n * @method utils.forEachRelation\n * @param {Mapper} mapper Mapper.\n * @param {Object} opts Configuration options.\n * @param {Function} fn Callback function.\n * @param {*} thisArg Execution context for the callback function.\n * @since 3.0.0\n */\n forEachRelation (mapper, opts, fn, thisArg) {\n const relationList = mapper.relationList || []\n if (!relationList.length) {\n return\n }\n relationList.forEach(function (def) {\n utils._forRelation(opts, def, fn, thisArg)\n })\n },\n\n /**\n * Iterate over an object's own enumerable properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { b: 1, c: 4 }\n * let sum = 0\n * utils.forOwn(a, function (value, key) {\n * sum += value\n * })\n * console.log(sum) // 5\n *\n * @method utils.forOwn\n * @param {Object} object The object whose properties are to be enumerated.\n * @param {Function} fn Iteration function.\n * @param {Object} [thisArg] Content to which to bind `fn`.\n * @since 3.0.0\n */\n forOwn (obj, fn, thisArg) {\n const keys = Object.keys(obj)\n const len = keys.length\n let i\n for (i = 0; i < len; i++) {\n fn.call(thisArg, obj[keys[i]], keys[i], obj)\n }\n },\n\n /**\n * Proxy for `JSON.parse`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = utils.fromJson('{\"name\" : \"John\"}')\n * console.log(a) // { name: 'John' }\n *\n * @method utils.fromJson\n * @param {string} json JSON to parse.\n * @returns {Object} Parsed object.\n * @see utils.toJson\n * @since 3.0.0\n */\n fromJson (json) {\n return utils.isString(json) ? JSON.parse(json) : json\n },\n\n /**\n * Retrieve the specified property from the given object. Supports retrieving\n * nested properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * console.log(utils.get(a, 'beep')) // \"boop\"\n * console.log(utils.get(a, 'foo.bar')) // \"baz\"\n *\n * @method utils.get\n * @param {Object} object Object from which to retrieve a property's value.\n * @param {string} prop Property to retrieve.\n * @returns {*} Value of the specified property.\n * @see utils.set\n * @since 3.0.0\n */\n 'get': function (object, prop) {\n if (!prop) {\n return\n }\n const parts = prop.split('.')\n const last = parts.pop()\n\n while (prop = parts.shift()) { // eslint-disable-line\n object = object[prop]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n return object[last]\n },\n\n /**\n * Return the superclass for the given instance or subclass. If an instance is\n * provided, then finds the parent class of the instance's constructor.\n *\n * @example\n * import {utils} from 'js-data'\n * // using ES2015 classes\n * class Foo {}\n * class Bar extends Foo {}\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * // using Function constructor with utils.extend\n * function Foo () {}\n * Foo.extend = utils.extend\n * const Bar = Foo.extend()\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * @method utils.getSuper\n * @param {Object|Function} instance Instance or constructor.\n * @param {boolean} [isCtor=false] Whether `instance` is a constructor.\n * @returns {Constructor} The superclass (grandparent constructor).\n * @since 3.0.0\n */\n getSuper (instance, isCtor) {\n const ctor = isCtor ? instance : instance.constructor\n if (ctor.hasOwnProperty('__super__')) {\n return ctor.__super__\n }\n return Object.getPrototypeOf(ctor) || ctor.__proto__ // eslint-disable-line\n },\n\n /**\n * Return the intersection of two arrays.\n *\n * @example\n * import {utils} from 'js-data'\n * const arrA = ['green', 'red', 'blue', 'red']\n * const arrB = ['green', 'yellow', 'red']\n * const intersected = utils.intersection(arrA, arrB)\n *\n * console.log(intersected) // ['green', 'red'])\n *\n * @method utils.intersection\n * @param {Array} array1 First array.\n * @param {Array} array2 Second array.\n * @returns {Array} Array of elements common to both arrays.\n * @since 3.0.0\n */\n intersection (array1, array2) {\n if (!array1 || !array2) {\n return []\n }\n const result = []\n let item\n let i\n const len = array1.length\n for (i = 0; i < len; i++) {\n item = array1[i]\n if (result.indexOf(item) !== -1) {\n continue\n }\n if (array2.indexOf(item) !== -1) {\n result.push(item)\n }\n }\n return result\n },\n\n /**\n * Proxy for `Array.isArray`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = [1,2,3,4,5]\n * const b = { foo: \"bar\" }\n * console.log(utils.isArray(a)) // true\n * console.log(utils.isArray(b)) // false\n *\n * @method utils.isArray\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an array.\n * @since 3.0.0\n */\n isArray: Array.isArray,\n\n /**\n * Return whether `prop` is matched by any string or regular expression in\n * `blacklist`.\n *\n * @example\n * import {utils} from 'js-data'\n * const blacklist = [/^\\$hashKey/g, /^_/g, 'id']\n * console.log(utils.isBlacklisted(\"$hashKey\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"id\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"_myProp\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"my_id\", blacklist)) // false\n *\n * @method utils.isBlacklisted\n * @param {string} prop The name of a property to check.\n * @param {Array} blacklist Array of strings and regular expressions.\n * @returns {boolean} Whether `prop` was matched.\n * @since 3.0.0\n */\n isBlacklisted (prop, blacklist) {\n if (!blacklist || !blacklist.length) {\n return false\n }\n let matches\n for (var i = 0; i < blacklist.length; i++) {\n if ((toStr(blacklist[i]) === REGEXP_TAG && blacklist[i].test(prop)) || blacklist[i] === prop) {\n matches = prop\n return !!matches\n }\n }\n return !!matches\n },\n\n /**\n * Return whether the provided value is a boolean.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = true\n * const b = { foo: \"bar\" }\n * console.log(utils.isBoolean(a)) // true\n * console.log(utils.isBoolean(b)) // false\n *\n * @method utils.isBoolean\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a boolean.\n * @since 3.0.0\n */\n isBoolean (value) {\n return toStr(value) === BOOL_TAG\n },\n\n /**\n * Return whether the provided value is a date.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = new Date()\n * const b = { foo: \"bar\" }\n * console.log(utils.isDate(a)) // true\n * console.log(utils.isDate(b)) // false\n *\n * @method utils.isDate\n * @param {*} value The value to test.\n * @returns {Date} Whether the provided value is a date.\n * @since 3.0.0\n */\n isDate (value) {\n return (value && typeof value === 'object' && toStr(value) === DATE_TAG)\n },\n\n /**\n * Return whether the provided value is a function.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = function (){ console.log('foo bar')}\n * const b = { foo: \"bar\" }\n * console.log(utils.isFunction(a)) // true\n * console.log(utils.isFunction(b)) // false\n *\n * @method utils.isFunction\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a function.\n * @since 3.0.0\n */\n isFunction (value) {\n return typeof value === 'function' || (value && toStr(value) === FUNC_TAG)\n },\n\n /**\n * Return whether the provided value is an integer.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = 1.25\n * const c = '1'\n * console.log(utils.isInteger(a)) // true\n * console.log(utils.isInteger(b)) // false\n * console.log(utils.isInteger(c)) // false\n *\n * @method utils.isInteger\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an integer.\n * @since 3.0.0\n */\n isInteger (value) {\n return toStr(value) === NUMBER_TAG && value == toInteger(value) // eslint-disable-line\n },\n\n /**\n * Return whether the provided value is `null`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = null\n * const b = { foo: \"bar\" }\n * console.log(utils.isNull(a)) // true\n * console.log(utils.isNull(b)) // false\n *\n * @method utils.isNull\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is `null`.\n * @since 3.0.0\n */\n isNull (value) {\n return value === null\n },\n\n /**\n * Return whether the provided value is a number.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = -1.25\n * const c = '1'\n * console.log(utils.isNumber(a)) // true\n * console.log(utils.isNumber(b)) // true\n * console.log(utils.isNumber(c)) // false\n *\n * @method utils.isNumber\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a number.\n * @since 3.0.0\n */\n isNumber (value) {\n const type = typeof value\n return type === 'number' || (value && type === 'object' && toStr(value) === NUMBER_TAG)\n },\n\n /**\n * Return whether the provided value is an object.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\" }\n * const b = 'foo bar'\n * console.log(utils.isObject(a)) // true\n * console.log(utils.isObject(b)) // false\n *\n * @method utils.isObject\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an object.\n * @since 3.0.0\n */\n isObject (value) {\n return toStr(value) === OBJECT_TAG\n },\n\n /**\n * Return whether the provided value is a regular expression.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = /^\\$.+$/ig\n * const b = new RegExp('^\\$.+$', 'ig')\n * const c = { foo: \"bar\" }\n * console.log(utils.isRegExp(a)) // true\n * console.log(utils.isRegExp(b)) // true\n * console.log(utils.isRegExp(c)) // false\n *\n * @method utils.isRegExp\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a regular expression.\n * @since 3.0.0\n */\n isRegExp (value) {\n return toStr(value) === REGEXP_TAG\n },\n\n /**\n * Return whether the provided value is a string or a number.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isSorN('')) // true\n * console.log(utils.isSorN(-1.65)) // true\n * console.log(utils.isSorN('my string')) // true\n * console.log(utils.isSorN({})) // false\n * console.log(utils.isSorN([1,2,4])) // false\n *\n * @method utils.isSorN\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string or a number.\n * @since 3.0.0\n */\n isSorN (value) {\n return utils.isString(value) || utils.isNumber(value)\n },\n\n /**\n * Return whether the provided value is a string.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('')) // true\n * console.log(utils.isString('my string')) // true\n * console.log(utils.isString(100)) // false\n * console.log(utils.isString([1,2,4])) // false\n *\n * @method utils.isString\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string.\n * @since 3.0.0\n */\n isString (value) {\n return typeof value === 'string' || (value && typeof value === 'object' && toStr(value) === STRING_TAG)\n },\n\n /**\n * Return whether the provided value is a `undefined`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = undefined\n * const b = { foo: \"bar\"}\n * console.log(utils.isUndefined(a)) // true\n * console.log(utils.isUndefined(b.baz)) // true\n * console.log(utils.isUndefined(b)) // false\n * console.log(utils.isUndefined(b.foo)) // false\n *\n * @method utils.isUndefined\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a `undefined`.\n * @since 3.0.0\n */\n isUndefined (value) {\n return value === undefined\n },\n\n /**\n * Mix in logging capabilities to the target.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\"}\n *\n * // Add standard logging to an object\n * utils.logify(a)\n * a.log('info', 'test log info') // output 'test log info' to console.\n *\n * // Toggle debug output of an object\n * a.dbg('test debug output') // does not output because debug is off.\n * a.debug = true\n * a.dbg('test debug output') // output 'test debug output' to console.\n *\n * @method utils.logify\n * @param {*} target The target.\n * @since 3.0.0\n */\n logify (target) {\n utils.addHiddenPropsToTarget(target, {\n dbg (...args) {\n if (utils.isFunction(this.log)) {\n this.log('debug', ...args)\n }\n },\n log (level, ...args) {\n if (level && !args.length) {\n args.push(level)\n level = 'debug'\n }\n if (level === 'debug' && !this.debug) {\n return\n }\n const prefix = `${level.toUpperCase()}: (${this.name || this.constructor.name})`\n if (utils.isFunction(console[level])) {\n console[level](prefix, ...args)\n } else {\n console.log(prefix, ...args)\n }\n }\n })\n },\n\n /**\n * Adds the given record to the provided array only if it's not already in the\n * array.\n *\n * @example\n * import {utils} from 'js-data'\n * const colors = ['red', 'green', 'yellow']\n *\n * console.log(colors.length) // 3\n * utils.noDupeAdd(colors, 'red')\n * console.log(colors.length) // 3, red already exists\n *\n * utils.noDupeAdd(colors, 'blue')\n * console.log(colors.length) // 4, blue was added\n *\n * @method utils.noDupeAdd\n * @param {Array} array The array.\n * @param {*} record The value to add.\n * @param {Function} fn Callback function passed to {@link utils.findIndex}.\n * @since 3.0.0\n */\n noDupeAdd (array, record, fn) {\n if (!array) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index < 0) {\n array.push(record)\n }\n },\n\n /**\n * Return a shallow copy of the provided object, minus the properties\n * specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.omit(a, ['$hashKey'])\n * console.log(b) // { name: 'John' }\n *\n * @method utils.omit\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to skip.\n * @returns {Object} Shallow copy of `props`, minus `keys`.\n * @since 3.0.0\n */\n omit (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) === -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a shallow copy of the provided object, but only include the\n * properties specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.pick(a, ['$hashKey'])\n * console.log(b) // { $hashKey: 1214910 }\n *\n * @method utils.pick\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to keep.\n * @returns {Object} Shallow copy of `props`, but only including `keys`.\n * @since 3.0.0\n */\n pick (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) !== -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a plain copy of the given value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John' }\n * let b = utils.plainCopy(a)\n * console.log(a === b) // false\n *\n * @method utils.plainCopy\n * @param {*} value The value to copy.\n * @returns {*} Plain copy of `value`.\n * @see utils.copy\n * @since 3.0.0\n */\n plainCopy (value) {\n return utils.copy(value, undefined, undefined, undefined, undefined, true)\n },\n\n /**\n * Shortcut for `utils.Promise.reject(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.reject(\"Testing static reject\").then(function(data) {\n * // not called\n * }).catch(function(reason) {\n * console.log(reason); // \"Testing static reject\"\n * })\n *\n * @method utils.reject\n * @param {*} [value] Value with which to reject the Promise.\n * @returns {Promise} Promise reject with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n reject (value) {\n return utils.Promise.reject(value)\n },\n\n /**\n * Remove the last item found in array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const colors = ['red', 'green', 'yellow', 'red']\n * utils.remove(colors, (color) => color === 'red')\n * console.log(colors) // ['red', 'green', 'yellow']\n *\n * @method utils.remove\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n */\n remove (array, fn) {\n if (!array || !array.length) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index >= 0) {\n array.splice(index, 1) // todo should this be recursive?\n }\n },\n\n /**\n * Shortcut for `utils.Promise.resolve(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.resolve(\"Testing static resolve\").then(function(data) {\n * console.log(data); // \"Testing static resolve\"\n * }).catch(function(reason) {\n * // not called\n * })\n *\n * @param {*} [value] Value with which to resolve the Promise.\n * @returns {Promise} Promise resolved with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n resolve (value) {\n return utils.Promise.resolve(value)\n },\n\n /**\n * Set the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n * // set value by key\n * utils.set(john, 'id', 98)\n * console.log(john.id) // 98\n *\n * // set value by path\n * utils.set(john, 'parent.id', 20)\n * console.log(john.parent.id) // 20\n *\n * // set value by path/value map\n * utils.set(john, {\n * 'id': 1098,\n * 'parent': { id: 1020 },\n * 'parent.age': '55'\n * })\n * console.log(john.id) // 1098\n * console.log(john.parent.id) // 1020\n * console.log(john.parent.age) // 55\n *\n * @method utils.set\n * @param {Object} object The object on which to set a property.\n * @param {(string|Object)} path The key or path to the property. Can also\n * pass in an object of path/value pairs, which will all be set on the target\n * object.\n * @param {*} [value] The value to set.\n */\n set: function (object, path, value) {\n if (utils.isObject(path)) {\n utils.forOwn(path, function (value, _path) {\n utils.set(object, _path, value)\n })\n } else {\n const parts = PATH.exec(path)\n if (parts) {\n mkdirP(object, parts[1])[parts[2]] = value\n } else {\n object[path] = value\n }\n }\n },\n\n /**\n * Check whether the two provided objects are deeply equal.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const objA = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * const objB = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * console.log(utils.deepEqual(a,b)) // true\n * objB.nested.colors.add('yellow') // make a change to a nested object's array\n * console.log(utils.deepEqual(a,b)) // false\n *\n * @method utils.deepEqual\n * @param {Object} a First object in the comparison.\n * @param {Object} b Second object in the comparison.\n * @returns {boolean} Whether the two provided objects are deeply equal.\n * @see utils.equal\n * @since 3.0.0\n */\n deepEqual (a, b) {\n if (a === b) {\n return true\n }\n let _equal = true\n if (utils.isObject(a) && utils.isObject(b)) {\n utils.forOwn(a, function (value, key) {\n _equal = _equal && utils.deepEqual(value, b[key])\n })\n if (!_equal) {\n return _equal\n }\n utils.forOwn(b, function (value, key) {\n _equal = _equal && utils.deepEqual(value, a[key])\n })\n } else if (utils.isArray(a) && utils.isArray(b)) {\n a.forEach(function (value, i) {\n _equal = _equal && utils.deepEqual(value, b[i])\n if (!_equal) {\n return false\n }\n })\n } else {\n return false\n }\n return _equal\n },\n\n /**\n * Proxy for `JSON.stringify`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = { name: 'John' }\n * let jsonVal = utils.toJson(a)\n * console.log(jsonVal) // '{\"name\" : \"John\"}'\n *\n * @method utils.toJson\n * @param {*} value Value to serialize to JSON.\n * @returns {string} JSON string.\n * @see utils.fromJson\n * @since 3.0.0\n */\n toJson: JSON.stringify,\n\n /**\n * Unset the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n *\n * utils.unset(john, age)\n * utils.unset(john, parent.age)\n *\n * console.log(john.age) // null\n * console.log(john.parent.age) // null\n *\n * @method utils.unset\n * @param {Object} object The object from which to delete the property.\n * @param {string} path The key or path to the property.\n * @see utils.set\n * @since 3.0.0\n */\n unset (object, path) {\n const parts = path.split('.')\n const last = parts.pop()\n\n while (path = parts.shift()) { // eslint-disable-line\n object = object[path]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n object[last] = undefined\n }\n}\n\nexport default utils\n","import utils from './utils'\n\n/**\n * A base class which gives instances private properties.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Settable.extend} for an example of using {@link Settable} as a\n * base class.\n *\n *```javascript\n * import {Settable} from 'js-data'\n * ```\n *\n * @class Settable\n * @returns {Settable} A new {@link Settable} instance.\n * @since 3.0.0\n */\nexport default function Settable () {\n const _props = {}\n Object.defineProperties(this, {\n /**\n * Get a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method Settable#_get\n * @param {string} key The property to retrieve.\n * @returns {*} The value of the property.\n * @since 3.0.0\n */\n _get: { value (key) { return utils.get(_props, key) } },\n\n /**\n * Set a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_set\n * @param {(string|Object)} key The key or path to the property. Can also\n * pass in an object of key/value pairs, which will all be set on the instance.\n * @param {*} [value] The value to set.\n * @since 3.0.0\n */\n _set: { value (key, value) { return utils.set(_props, key, value) } },\n\n /**\n * Unset a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_unset\n * @param {string} key The property to unset.\n * @since 3.0.0\n */\n _unset: { value (key) { return utils.unset(_props, key) } }\n })\n}\n\n/**\n * Create a subclass of this Settable:\n *\n * @example Settable.extend\n * // Normally you would do: import {Settable} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Settable} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSettableClass extends Settable {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSettable = new CustomSettableClass()\n * console.log(customSettable.foo())\n * console.log(CustomSettableClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSettableClass = Settable.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSettable = new OtherSettableClass()\n * console.log(otherSettable.foo())\n * console.log(OtherSettableClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSettableClass () {\n * Settable.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Settable.extend({\n * constructor: AnotherSettableClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSettable = new AnotherSettableClass()\n * console.log(anotherSettable.created_at)\n * console.log(anotherSettable.foo())\n * console.log(AnotherSettableClass.beep())\n *\n * @method Settable.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Settable class.\n * @since 3.0.0\n */\nSettable.extend = utils.extend\n","import utils from './utils'\nimport Settable from './Settable'\n\n/**\n * The base class from which all JSData components inherit some basic\n * functionality.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Component.extend} for an example of using {@link Component} as a\n * base class.\n *\n *```javascript\n * import {Component} from 'js-data'\n * ```\n *\n * @class Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @returns {Component} A new {@link Component} instance.\n * @since 3.0.0\n */\nfunction Component (opts) {\n Settable.call(this)\n opts || (opts = {})\n\n /**\n * Whether to enable debug-level logs for this component. Anything that\n * extends `Component` inherits this option and the corresponding logging\n * functionality.\n *\n * @example Component#debug\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const component = new Component()\n * component.log('debug', 'some message') // nothing gets logged\n * // Display debug logs:\n * component.debug = true\n * component.log('debug', 'other message') // this DOES get logged\n *\n * @default false\n * @name Component#debug\n * @since 3.0.0\n * @type {boolean}\n */\n this.debug = opts.hasOwnProperty('debug') ? !!opts.debug : false\n\n /**\n * Event listeners attached to this Component. __Do not modify.__ Use\n * {@link Component#on} and {@link Component#off} instead.\n *\n * @name Component#_listeners\n * @instance\n * @since 3.0.0\n * @type {Object}\n */\n Object.defineProperty(this, '_listeners', { value: {}, writable: true })\n}\n\nexport default Settable.extend({\n constructor: Component\n})\n\n/**\n * Create a subclass of this Component:\n *\n * @example Component.extend\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomComponentClass extends Component {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customComponent = new CustomComponentClass()\n * console.log(customComponent.foo())\n * console.log(CustomComponentClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherComponentClass = Component.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherComponent = new OtherComponentClass()\n * console.log(otherComponent.foo())\n * console.log(OtherComponentClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherComponentClass () {\n * Component.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Component.extend({\n * constructor: AnotherComponentClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherComponent = new AnotherComponentClass()\n * console.log(anotherComponent.created_at)\n * console.log(anotherComponent.foo())\n * console.log(AnotherComponentClass.beep())\n *\n * @method Component.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Component class.\n * @since 3.0.0\n */\nComponent.extend = utils.extend\n\n/**\n * Log the provided values at the \"debug\" level. Debug-level logs are only\n * logged if {@link Component#debug} is `true`.\n *\n * `.dbg(...)` is shorthand for `.log('debug', ...)`.\n *\n * @method Component#dbg\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\n/**\n * Log the provided values. By default sends values to `console[level]`.\n * Debug-level logs are only logged if {@link Component#debug} is `true`.\n *\n * Will attempt to use appropriate `console` methods if they are available.\n *\n * @method Component#log\n * @param {string} level Log level.\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\nutils.logify(Component.prototype)\n\n/**\n * Register a new event listener on this Component.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * collection.on('add', (records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * post.on('change', (record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method Component#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n/**\n * Remove an event listener from this Component. If no listener is provided,\n * then all listeners for the specified event will be removed. If no event is\n * specified then all listeners for all events will be removed.\n *\n * @example\n * // Remove a particular listener for a particular event\n * collection.off('add', handler)\n *\n * @example\n * // Remove all listeners for a particular event\n * record.off('change')\n *\n * @example\n * // Remove all listeners to all events\n * store.off()\n *\n * @method Component#off\n * @param {string} [event] Name of event to unsubsribe to.\n * @param {Function} [listener] Listener to remove.\n * @since 3.0.0\n */\n/**\n * Trigger an event on this Component.\n *\n * @example Component#emit\n * // import {Collection, DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, DataStore} = JSData\n *\n * const collection = new Collection()\n * collection.on('foo', function (msg) {\n * console.log(msg)\n * })\n * collection.emit('foo', 'bar')\n *\n * const store = new DataStore()\n * store.on('beep', function (msg) {\n * console.log(msg)\n * })\n * store.emit('beep', 'boop')\n *\n * @method Component#emit\n * @param {string} event Name of event to emit.\n * @param {...*} [args] Arguments to pass to any listeners.\n * @since 3.0.0\n */\nutils.eventify(\n Component.prototype,\n function () {\n return this._listeners\n },\n function (value) {\n this._listeners = value\n }\n)\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Query'\nconst INDEX_ERR = 'Index inaccessible after first operation'\n\n// Reserved words used by JSData's Query Syntax\nconst reserved = {\n limit: '',\n offset: '',\n orderBy: '',\n skip: '',\n sort: '',\n where: ''\n}\n\n// Used by our JavaScript implementation of the LIKE operator\nconst escapeRegExp = /([.*+?^=!:${}()|[\\]\\/\\\\])/g\nconst percentRegExp = /%/g\nconst underscoreRegExp = /_/g\nconst escape = function (pattern) {\n return pattern.replace(escapeRegExp, '\\\\$1')\n}\n\n/**\n * A class used by the {@link Collection} class to build queries to be executed\n * against the collection's data. An instance of `Query` is returned by\n * {@link Collection#query}. Query instances are typically short-lived, and you\n * shouldn't have to create them yourself. Just use {@link Collection#query}.\n *\n * ```javascript\n * import {Query} from 'js-data'\n * ```\n *\n * @example\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const drafts = store.query('post').filter({ status: 'draft' }).limit(2).run()\n * console.log(drafts)\n *\n * @class Query\n * @extends Component\n * @param {Collection} collection The collection on which this query operates.\n * @since 3.0.0\n */\nfunction Query (collection) {\n utils.classCallCheck(this, Query)\n\n /**\n * The {@link Collection} on which this query operates.\n *\n * @name Query#collection\n * @since 3.0.0\n * @type {Collection}\n */\n this.collection = collection\n\n /**\n * The current data result of this query.\n *\n * @name Query#data\n * @since 3.0.0\n * @type {Array}\n */\n this.data = null\n}\n\nexport default Component.extend({\n constructor: Query,\n\n _applyWhereFromObject (where) {\n const fields = []\n const ops = []\n const predicates = []\n utils.forOwn(where, (clause, field) => {\n if (!utils.isObject(clause)) {\n clause = {\n '==': clause\n }\n }\n utils.forOwn(clause, (expr, op) => {\n fields.push(field)\n ops.push(op)\n predicates.push(expr)\n })\n })\n return {\n fields,\n ops,\n predicates\n }\n },\n\n _applyWhereFromArray (where) {\n const groups = []\n where.forEach((_where, i) => {\n if (utils.isString(_where)) {\n return\n }\n const prev = where[i - 1]\n const parser = utils.isArray(_where) ? this._applyWhereFromArray : this._applyWhereFromObject\n const group = parser.call(this, _where)\n if (prev === 'or') {\n group.isOr = true\n }\n groups.push(group)\n })\n groups.isArray = true\n return groups\n },\n\n _testObjectGroup (keep, first, group, item) {\n let i\n const fields = group.fields\n const ops = group.ops\n const predicates = group.predicates\n const len = ops.length\n for (i = 0; i < len; i++) {\n let op = ops[i]\n const isOr = op.charAt(0) === '|'\n op = isOr ? op.substr(1) : op\n const expr = this.evaluate(utils.get(item, fields[i]), op, predicates[i])\n if (expr !== undefined) {\n keep = first ? expr : (isOr ? keep || expr : keep && expr)\n }\n first = false\n }\n return { keep, first }\n },\n\n _testArrayGroup (keep, first, groups, item) {\n let i\n const len = groups.length\n for (i = 0; i < len; i++) {\n const group = groups[i]\n const parser = group.isArray ? this._testArrayGroup : this._testObjectGroup\n const result = parser.call(this, true, true, group, item)\n if (groups[i - 1]) {\n if (group.isOr) {\n keep = keep || result.keep\n } else {\n keep = keep && result.keep\n }\n } else {\n keep = result.keep\n }\n first = result.first\n }\n return { keep, first }\n },\n\n /**\n * Find all entities between two boundaries.\n *\n * @example Get the users ages 18 to 30.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between(18, 30, { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @example Same as above.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between([18], [30], { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @method Query#between\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#between`)(500, 'Cannot access index')\n }\n this.data = this.collection.getIndex(opts.index).between(leftKeys, rightKeys, opts)\n return this\n },\n\n /**\n * The comparison function used by the {@link Query} class.\n *\n * @method Query#compare\n * @param {Array} orderBy An orderBy clause used for sorting and sub-sorting.\n * @param {number} index The index of the current orderBy clause being used.\n * @param {*} a The first item in the comparison.\n * @param {*} b The second item in the comparison.\n * @returns {number} -1 if `b` should preceed `a`. 0 if `a` and `b` are equal.\n * 1 if `a` should preceed `b`.\n * @since 3.0.0\n */\n compare (orderBy, index, a, b) {\n const def = orderBy[index]\n let cA = utils.get(a, def[0])\n let cB = utils.get(b, def[0])\n if (cA && utils.isString(cA)) {\n cA = cA.toUpperCase()\n }\n if (cB && utils.isString(cB)) {\n cB = cB.toUpperCase()\n }\n if (a === undefined) {\n a = null\n }\n if (b === undefined) {\n b = null\n }\n if (def[1].toUpperCase() === 'DESC') {\n const temp = cB\n cB = cA\n cA = temp\n }\n if (cA < cB) {\n return -1\n } else if (cA > cB) {\n return 1\n } else {\n if (index < orderBy.length - 1) {\n return this.compare(orderBy, index + 1, a, b)\n } else {\n return 0\n }\n }\n },\n\n /**\n * Predicate evaluation function used by the {@link Query} class.\n *\n * @method Query#evaluate\n * @param {*} value The value to evaluate.\n * @param {string} op The operator to use in this evaluation.\n * @param {*} predicate The predicate to use in this evaluation.\n * @returns {boolean} Whether the value passed the evaluation or not.\n * @since 3.0.0\n */\n evaluate (value, op, predicate) {\n const ops = this.constructor.ops\n if (ops[op]) {\n return ops[op](value, predicate)\n }\n if (op.indexOf('like') === 0) {\n return this.like(predicate, op.substr(4)).exec(value) !== null\n } else if (op.indexOf('notLike') === 0) {\n return this.like(predicate, op.substr(7)).exec(value) === null\n }\n },\n\n /**\n * Find the record or records that match the provided query or are accepted by\n * the provided filter function.\n *\n * @example Get the draft posts by authors younger than 30\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * let results = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * age: {\n * '<': 30\n * }\n * }\n * }).run()\n * console.log(results)\n *\n * @example Use a custom filter function\n * const posts = query.filter(function (post) {\n * return post.isReady()\n * }).run()\n *\n * @method Query#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Function} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n filter (query, thisArg) {\n /**\n * Selection query as defined by JSData's [Query Syntax][querysyntax].\n *\n * [querysyntax]: http://www.js-data.io/v3.0/docs/query-syntax\n *\n * @example Empty \"findAll\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * store.findAll('post').then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @example Empty \"filter\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = store.filter('post')\n * console.log(posts) // [...]\n *\n * @example Complex \"filter\" query\n * const PAGE_SIZE = 2\n * let currentPage = 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * // Retrieve a filtered page of blog posts\n * // Would typically replace filter with findAll\n * store.filter('post', {\n * where: {\n * status: {\n * // WHERE status = 'published'\n * '==': 'published'\n * },\n * author: {\n * // AND author IN ('bob', 'alice')\n * 'in': ['bob', 'alice'],\n * // OR author IN ('karen')\n * '|in': ['karen']\n * }\n * },\n * orderBy: [\n * // ORDER BY date_published DESC,\n * ['date_published', 'DESC'],\n * // ORDER BY title ASC\n * ['title', 'ASC']\n * ],\n * // LIMIT 2\n * limit: PAGE_SIZE,\n * // SKIP 4\n * offset: PAGE_SIZE * (currentPage - 1)\n * })\n *\n * @namespace query\n * @property {number} [limit] See {@link query.limit}.\n * @property {number} [offset] See {@link query.offset}.\n * @property {string|Array[]} [orderBy] See {@link query.orderBy}.\n * @property {number} [skip] Alias for {@link query.offset}.\n * @property {string|Array[]} [sort] Alias for {@link query.orderBy}.\n * @property {Object} [where] See {@link query.where}.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/query-syntax\",\"JSData's Query Syntax\"]\n */\n query || (query = {})\n this.getData()\n if (utils.isObject(query)) {\n let where = {}\n\n /**\n * Filtering criteria. Records that do not meet this criteria will be exluded\n * from the result.\n *\n * @example Return posts where author is at least 32 years old\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * where: {\n * age: {\n * '>=': 30\n * }\n * }\n * })\n * console.log(results)\n *\n * @name query.where\n * @type {Object}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isObject(query.where) || utils.isArray(query.where)) {\n where = query.where\n }\n utils.forOwn(query, function (value, key) {\n if (!(key in reserved) && !(key in where)) {\n where[key] = {\n '==': value\n }\n }\n })\n let groups\n\n // Apply filter for each field\n if (utils.isObject(where) && Object.keys(where).length !== 0) {\n groups = this._applyWhereFromArray([where])\n } else if (utils.isArray(where)) {\n groups = this._applyWhereFromArray(where)\n }\n\n if (groups) {\n this.data = this.data.filter((item, i) => this._testArrayGroup(true, true, groups, item).keep)\n }\n\n // Sort\n let orderBy = query.orderBy || query.sort\n\n if (utils.isString(orderBy)) {\n orderBy = [\n [orderBy, 'ASC']\n ]\n }\n if (!utils.isArray(orderBy)) {\n orderBy = null\n }\n\n /**\n * Determines how records should be ordered in the result.\n *\n * @example Order posts by `author` then by `id` descending \n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * orderBy:[['author','ASC'],['id','DESC']]\n * })\n * console.log(results)\n *\n * @name query.orderBy\n * @type {string|Array[]}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (orderBy) {\n let index = 0\n orderBy.forEach(function (def, i) {\n if (utils.isString(def)) {\n orderBy[i] = [def, 'ASC']\n }\n })\n this.data.sort((a, b) => this.compare(orderBy, index, a, b))\n }\n\n /**\n * Number of records to skip.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n *\n * @name query.offset\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.skip)) {\n this.skip(query.skip)\n } else if (utils.isNumber(query.offset)) {\n this.skip(query.offset)\n }\n\n /**\n * Maximum number of records to retrieve.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n * @name query.limit\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.limit)) {\n this.limit(query.limit)\n }\n } else if (utils.isFunction(query)) {\n this.data = this.data.filter(query, thisArg)\n }\n return this\n },\n\n /**\n * Iterate over all entities.\n *\n * @method Query#forEach\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n forEach (forEachFn, thisArg) {\n this.getData().forEach(forEachFn, thisArg)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided key.\n *\n * @example Get the entity whose primary key is 25.\n * const entities = query.get(25).run()\n *\n * @example Same as above.\n * const entities = query.get([25]).run()\n *\n * @example Get all users who are active and have the \"admin\" role.\n * const activeAdmins = query.get(['active', 'admin'], {\n * index: 'activityAndRoles'\n * }).run()\n *\n * @example Get all entities that match a certain weather condition.\n * const niceDays = query.get(['sunny', 'humid', 'calm'], {\n * index: 'weatherConditions'\n * }).run()\n *\n * @method Query#get\n * @param {Array} keyList Key(s) defining the entity to retrieve. If\n * `keyList` is not an array (i.e. for a single-value key), it will be\n * wrapped in an array.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.string] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n get (keyList, opts) {\n keyList || (keyList = [])\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#get`)(500, INDEX_ERR)\n }\n if (keyList && !utils.isArray(keyList)) {\n keyList = [keyList]\n }\n if (!keyList.length) {\n this.getData()\n return this\n }\n this.data = this.collection.getIndex(opts.index).get(keyList)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided keyLists.\n *\n * @example Get the posts where \"status\" is \"draft\" or \"inReview\".\n * const posts = query.getAll('draft', 'inReview', { index: 'status' }).run()\n *\n * @example Same as above.\n * const posts = query.getAll(['draft'], ['inReview'], { index: 'status' }).run()\n *\n * @method Query#getAll\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * entities matching each keyList will be retrieved. If no keyLists are\n * provided, all entities will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n getAll (...args) {\n let opts = {}\n if (this.data) {\n throw utils.err(`${DOMAIN}#getAll`)(500, INDEX_ERR)\n }\n if (!args.length || args.length === 1 && utils.isObject(args[0])) {\n this.getData()\n return this\n } else if (args.length && utils.isObject(args[args.length - 1])) {\n opts = args[args.length - 1]\n args.pop()\n }\n const collection = this.collection\n const index = collection.getIndex(opts.index)\n this.data = []\n args.forEach((keyList) => {\n this.data = this.data.concat(index.get(keyList))\n })\n return this\n },\n\n /**\n * Return the current data result of this query.\n *\n * @method Query#getData\n * @returns {Array} The data in this query.\n * @since 3.0.0\n */\n getData () {\n if (!this.data) {\n this.data = this.collection.index.getAll()\n }\n return this.data\n },\n\n /**\n * Implementation used by the `like` operator. Takes a pattern and flags and\n * returns a `RegExp` instance that can test strings.\n *\n * @method Query#like\n * @param {string} pattern Testing pattern.\n * @param {string} flags Flags for the regular expression.\n * @returns {RegExp} Regular expression for testing strings.\n * @since 3.0.0\n */\n like (pattern, flags) {\n return new RegExp(`^${(escape(pattern).replace(percentRegExp, '.*').replace(underscoreRegExp, '.'))}$`, flags)\n },\n\n /**\n * Limit the result.\n *\n * @example Get only the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').limit(2).run()\n * console.log(results)\n *\n * @method Query#limit\n * @param {number} num The maximum number of entities to keep in the result.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n limit (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#limit`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n this.data = data.slice(0, Math.min(data.length, num))\n return this\n },\n\n /**\n * Apply a mapping function to the result data.\n *\n * @example\n * // Return the age of all users\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const ages = store.query('user').map((user) => {\n * return user.age\n * }).run()\n * console.log(ages)\n *\n * @method Query#map\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n map (mapFn, thisArg) {\n this.data = this.getData().map(mapFn, thisArg)\n return this\n },\n\n /**\n * Return the result of calling the specified function on each item in this\n * collection's main index.\n *\n * @example\n * const stringAges = UserCollection.query().mapCall('toString').run()\n *\n * @method Query#mapCall\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n mapCall (funcName, ...args) {\n this.data = this.getData().map(function (item) {\n return item[funcName](...args)\n })\n return this\n },\n\n /**\n * Complete the execution of the query and return the resulting data.\n *\n * @method Query#run\n * @returns {Array} The result of executing this query.\n * @since 3.0.0\n */\n run () {\n const data = this.data\n this.data = null\n return data\n },\n\n /**\n * Skip a number of results.\n *\n * @example Get all but the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').skip(2).run()\n * console.log(results)\n *\n * @method Query#skip\n * @param {number} num The number of entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n skip (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#skip`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n if (num < data.length) {\n this.data = data.slice(num)\n } else {\n this.data = []\n }\n return this\n }\n}, {\n /**\n * The filtering operators supported by {@link Query#filter}, and which are\n * implemented by adapters (for the most part).\n *\n * @example Variant 1\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * status: 'published',\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n *\n * @example Variant 2\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * }\n * },\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n * @example Variant 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * status: 'published'\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Variant 4\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'published'\n * }\n * }\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Multiple operators\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const myPublishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * },\n * user_id: {\n * '==': currentUser.id\n * }\n * }\n * })\n *\n * console.log(myPublishedPosts)\n *\n * @name Query.ops\n * @property {Function} == Equality operator.\n * @property {Function} != Inequality operator.\n * @property {Function} > Greater than operator.\n * @property {Function} >= Greater than (inclusive) operator.\n * @property {Function} < Less than operator.\n * @property {Function} <= Less than (inclusive) operator.\n * @property {Function} isectEmpty Operator that asserts that the intersection\n * between two arrays is empty.\n * @property {Function} isectNotEmpty Operator that asserts that the\n * intersection between two arrays is __not__ empty.\n * @property {Function} in Operator that asserts whether a value is in an\n * array.\n * @property {Function} notIn Operator that asserts whether a value is __not__\n * in an array.\n * @property {Function} contains Operator that asserts whether an array\n * contains a value.\n * @property {Function} notContains Operator that asserts whether an array\n * does __not__ contain a value.\n * @since 3.0.0\n * @type {Object}\n */\n ops: {\n '=': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '==': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '===': function (value, predicate) {\n return value === predicate\n },\n '!=': function (value, predicate) {\n return value != predicate // eslint-disable-line\n },\n '!==': function (value, predicate) {\n return value !== predicate\n },\n '>': function (value, predicate) {\n return value > predicate\n },\n '>=': function (value, predicate) {\n return value >= predicate\n },\n '<': function (value, predicate) {\n return value < predicate\n },\n '<=': function (value, predicate) {\n return value <= predicate\n },\n 'isectEmpty': function (value, predicate) {\n return !utils.intersection((value || []), (predicate || [])).length\n },\n 'isectNotEmpty': function (value, predicate) {\n return utils.intersection((value || []), (predicate || [])).length\n },\n 'in': function (value, predicate) {\n return predicate.indexOf(value) !== -1\n },\n 'notIn': function (value, predicate) {\n return predicate.indexOf(value) === -1\n },\n 'contains': function (value, predicate) {\n return (value || []).indexOf(predicate) !== -1\n },\n 'notContains': function (value, predicate) {\n return (value || []).indexOf(predicate) === -1\n }\n }\n})\n\n/**\n * Create a subclass of this Query:\n * @example Query.extend\n * // Normally you would do: import {Query} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Query} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomQueryClass extends Query {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customQuery = new CustomQueryClass()\n * console.log(customQuery.foo())\n * console.log(CustomQueryClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherQueryClass = Query.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherQuery = new OtherQueryClass()\n * console.log(otherQuery.foo())\n * console.log(OtherQueryClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherQueryClass (collection) {\n * Query.call(this, collection)\n * this.created_at = new Date().getTime()\n * }\n * Query.extend({\n * constructor: AnotherQueryClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherQuery = new AnotherQueryClass()\n * console.log(anotherQuery.created_at)\n * console.log(anotherQuery.foo())\n * console.log(AnotherQueryClass.beep())\n *\n * @method Query.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Query class.\n * @since 3.0.0\n */\n","export function sort (a, b, hashCode) {\n // Short-circuit comparison if a and b are strictly equal\n // This is absolutely necessary for indexed objects that\n // don't have the idAttribute field\n if (a === b) {\n return 0\n }\n if (hashCode) {\n a = hashCode(a)\n b = hashCode(b)\n }\n if ((a === null && b === null) || (a === undefined && b === undefined)) {\n return -1\n }\n\n if (a === null || a === undefined) {\n return -1\n }\n\n if (b === null || b === undefined) {\n return 1\n }\n\n if (a < b) {\n return -1\n }\n\n if (a > b) {\n return 1\n }\n\n return 0\n}\n\nexport function insertAt (array, index, value) {\n array.splice(index, 0, value)\n return array\n}\n\nexport function removeAt (array, index) {\n array.splice(index, 1)\n return array\n}\n\nexport function binarySearch (array, value, field) {\n let lo = 0\n let hi = array.length\n let compared\n let mid\n\n while (lo < hi) {\n mid = ((lo + hi) / 2) | 0\n compared = sort(value, array[mid], field)\n if (compared === 0) {\n return {\n found: true,\n index: mid\n }\n } else if (compared < 0) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n\n return {\n found: false,\n index: hi\n }\n}\n","// Copyright (c) 2015, InternalFX.\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose with or\n// without fee is hereby granted, provided that the above copyright notice and this permission\n// notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO\n// THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT\n// SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR\n// ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE\n// USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// Modifications\n// Copyright 2015-2016 Jason Dobry\n//\n// Summary of modifications:\n// Reworked dependencies so as to re-use code already in js-data\n// Removed unused code\nimport utils from '../../src/utils'\nimport {binarySearch, insertAt, removeAt} from './_utils'\n\nexport default function Index (fieldList, opts) {\n utils.classCallCheck(this, Index)\n fieldList || (fieldList = [])\n\n if (!utils.isArray(fieldList)) {\n throw new Error('fieldList must be an array.')\n }\n\n opts || (opts = {})\n this.fieldList = fieldList\n this.fieldGetter = opts.fieldGetter\n this.hashCode = opts.hashCode\n this.isIndex = true\n this.keys = []\n this.values = []\n}\n\nutils.addHiddenPropsToTarget(Index.prototype, {\n 'set' (keyList, value) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n let dataLocation = binarySearch(this.values[pos.index], value, this.hashCode)\n if (!dataLocation.found) {\n insertAt(this.values[pos.index], dataLocation.index, value)\n }\n } else {\n insertAt(this.keys, pos.index, key)\n insertAt(this.values, pos.index, [value])\n }\n } else {\n if (pos.found) {\n this.values[pos.index].set(keyList, value)\n } else {\n insertAt(this.keys, pos.index, key)\n let newIndex = new Index([], { hashCode: this.hashCode })\n newIndex.set(keyList, value)\n insertAt(this.values, pos.index, newIndex)\n }\n }\n },\n\n 'get' (keyList) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n if (this.values[pos.index].isIndex) {\n return this.values[pos.index].getAll()\n } else {\n return this.values[pos.index].slice()\n }\n } else {\n return []\n }\n } else {\n if (pos.found) {\n return this.values[pos.index].get(keyList)\n } else {\n return []\n }\n }\n },\n\n getAll (opts) {\n opts || (opts = {})\n let results = []\n const values = this.values\n if (opts.order === 'desc') {\n for (let i = values.length - 1; i >= 0; i--) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n } else {\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n }\n return results\n },\n\n visitAll (cb, thisArg) {\n this.values.forEach(function (value) {\n if (value.isIndex) {\n value.visitAll(cb, thisArg)\n } else {\n value.forEach(cb, thisArg)\n }\n })\n },\n\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (!utils.isArray(leftKeys)) {\n leftKeys = [leftKeys]\n }\n if (!utils.isArray(rightKeys)) {\n rightKeys = [rightKeys]\n }\n utils.fillIn(opts, {\n leftInclusive: true,\n rightInclusive: false,\n limit: undefined,\n offset: 0\n })\n\n let results = this._between(leftKeys, rightKeys, opts)\n\n if (opts.limit) {\n return results.slice(opts.offset, opts.limit + opts.offset)\n } else {\n return results.slice(opts.offset)\n }\n },\n\n _between (leftKeys, rightKeys, opts) {\n let results = []\n\n let leftKey = leftKeys.shift()\n let rightKey = rightKeys.shift()\n\n let pos\n\n if (leftKey !== undefined) {\n pos = binarySearch(this.keys, leftKey)\n } else {\n pos = {\n found: false,\n index: 0\n }\n }\n\n if (leftKeys.length === 0) {\n if (pos.found && opts.leftInclusive === false) {\n pos.index += 1\n }\n\n for (let i = pos.index; i < this.keys.length; i += 1) {\n if (rightKey !== undefined) {\n if (opts.rightInclusive) {\n if (this.keys[i] > rightKey) { break }\n } else {\n if (this.keys[i] >= rightKey) { break }\n }\n }\n\n if (this.values[i].isIndex) {\n results = results.concat(this.values[i].getAll())\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n } else {\n for (let i = pos.index; i < this.keys.length; i += 1) {\n let currKey = this.keys[i]\n if (currKey > rightKey) { break }\n\n if (this.values[i].isIndex) {\n if (currKey === leftKey) {\n results = results.concat(this.values[i]._between(utils.copy(leftKeys), rightKeys.map(function () { return undefined }), opts))\n } else if (currKey === rightKey) {\n results = results.concat(this.values[i]._between(leftKeys.map(function () { return undefined }), utils.copy(rightKeys), opts))\n } else {\n results = results.concat(this.values[i].getAll())\n }\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n }\n\n if (opts.limit) {\n return results.slice(0, opts.limit + opts.offset)\n } else {\n return results\n }\n },\n\n peek () {\n if (this.values.length) {\n if (this.values[0].isIndex) {\n return this.values[0].peek()\n } else {\n return this.values[0]\n }\n }\n return []\n },\n\n clear () {\n this.keys = []\n this.values = []\n },\n\n insertRecord (data) {\n let keyList = this.fieldList.map(function (field) {\n if (utils.isFunction(field)) {\n return field(data) || undefined\n } else {\n return data[field] || undefined\n }\n })\n this.set(keyList, data)\n },\n\n removeRecord (data) {\n let removed\n const isUnique = this.hashCode(data) !== undefined\n this.values.forEach((value, i) => {\n if (value.isIndex) {\n if (value.removeRecord(data)) {\n if (value.keys.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n } else {\n let dataLocation = {}\n if (this.keys[i] === undefined || !isUnique) {\n for (let j = value.length - 1; j >= 0; j--) {\n if (value[j] === data) {\n dataLocation = {\n found: true,\n index: j\n }\n break\n }\n }\n } else if (isUnique) {\n dataLocation = binarySearch(value, data, this.hashCode)\n }\n if (dataLocation.found) {\n removeAt(value, dataLocation.index)\n if (value.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n }\n })\n return removed ? data : undefined\n },\n\n updateRecord (data) {\n const removed = this.removeRecord(data)\n if (removed !== undefined) {\n this.insertRecord(data)\n }\n }\n})\n","import utils from './utils'\nimport Component from './Component'\nimport Query from './Query'\nimport Index from '../lib/mindex/index'\n\nconst DOMAIN = 'Collection'\n\nconst COLLECTION_DEFAULTS = {\n /**\n * Whether to call {@link Record#commit} on records that are added to the\n * collection and already exist in the collection.\n *\n * @name Collection#commitOnMerge\n * @type {boolean}\n * @default true\n */\n commitOnMerge: true,\n\n /**\n * Field to be used as the unique identifier for records in this collection.\n * Defaults to `\"id\"` unless {@link Collection#mapper} is set, in which case\n * this will default to {@link Mapper#idAttribute}.\n *\n * @name Collection#idAttribute\n * @type {string}\n * @default \"id\"\n */\n idAttribute: 'id',\n\n /**\n * What to do when inserting a record into this Collection that shares a\n * primary key with a record already in this Collection.\n *\n * Possible values:\n * merge\n * replace\n *\n * Merge:\n *\n * Recursively shallow copy properties from the new record onto the existing\n * record.\n *\n * Replace:\n *\n * Shallow copy top-level properties from the new record onto the existing\n * record. Any top-level own properties of the existing record that are _not_\n * on the new record will be removed.\n *\n * @name Collection#onConflict\n * @type {string}\n * @default \"merge\"\n */\n onConflict: 'merge'\n}\n\n/**\n * An ordered set of {@link Record} instances.\n *\n * @example Collection#constructor\n * // import {Collection, Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const user1 = new Record({ id: 1 })\n * const user2 = new Record({ id: 2 })\n * const UserCollection = new Collection([user1, user2])\n * console.log(UserCollection.get(1) === user1)\n *\n * @class Collection\n * @extends Component\n * @param {Array} [records] Initial set of records to insert into the\n * collection.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.commitOnMerge] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.idAttribute] See {@link Collection#idAttribute}.\n * @param {string} [opts.onConflict=\"merge\"] See {@link Collection#onConflict}.\n * @param {string} [opts.mapper] See {@link Collection#mapper}.\n * @since 3.0.0\n */\nfunction Collection (records, opts) {\n utils.classCallCheck(this, Collection)\n Component.call(this, opts)\n\n if (records && !utils.isArray(records)) {\n opts = records\n records = []\n }\n if (utils.isString(opts)) {\n opts = { idAttribute: opts }\n }\n\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * Default Mapper for this collection. Optional. If a Mapper is provided, then\n * the collection will use the {@link Mapper#idAttribute} setting, and will\n * wrap records in {@link Mapper#recordClass}.\n *\n * @example Collection#mapper\n * // Normally you would do: import {Collection, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const myMapper = new MyMapperClass({ name: 'myMapper' })\n * const collection = new Collection(null, { mapper: myMapper })\n *\n * @name Collection#mapper\n * @type {Mapper}\n * @default null\n * @since 3.0.0\n */\n mapper: {\n value: undefined,\n writable: true\n },\n // Query class used by this collection\n queryClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(COLLECTION_DEFAULTS))\n\n if (!this.queryClass) {\n this.queryClass = Query\n }\n\n const idAttribute = this.recordId()\n\n Object.defineProperties(this, {\n /**\n * The main index, which uses @{link Collection#recordId} as the key.\n *\n * @name Collection#index\n * @type {Index}\n */\n index: {\n value: new Index([idAttribute], {\n hashCode (obj) {\n return utils.get(obj, idAttribute)\n }\n })\n },\n\n /**\n * Object that holds the secondary indexes of this collection.\n *\n * @name Collection#indexes\n * @type {Object.}\n */\n indexes: {\n value: {}\n }\n })\n\n // Insert initial data into the collection\n if (utils.isObject(records) || (utils.isArray(records) && records.length)) {\n this.add(records)\n }\n}\n\nexport default Component.extend({\n constructor: Collection,\n\n /**\n * Used to bind to events emitted by records in this Collection.\n *\n * @method Collection#_onRecordEvent\n * @since 3.0.0\n * @private\n * @param {...*} [arg] Args passed to {@link Collection#emit}.\n */\n _onRecordEvent (...args) {\n this.emit(...args)\n },\n\n /**\n * Insert the provided record or records.\n *\n * If a record is already in the collection then the provided record will\n * either merge with or replace the existing record based on the value of the\n * `onConflict` option.\n *\n * The collection's secondary indexes will be updated as each record is\n * visited.\n *\n * @method Collection#add\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} data The record or records to insert.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.onConflict] See {@link Collection#onConflict}.\n * @returns {(Object|Object[]|Record|Record[])} The added record or records.\n */\n add (records, opts) {\n // Default values for arguments\n opts || (opts = {})\n\n // Fill in \"opts\" with the Collection's configuration\n utils._(opts, this)\n records = this.beforeAdd(records, opts) || records\n\n // Track whether just one record or an array of records is being inserted\n let singular = false\n const idAttribute = this.recordId()\n if (!utils.isArray(records)) {\n if (utils.isObject(records)) {\n records = [records]\n singular = true\n } else {\n throw utils.err(`${DOMAIN}#add`, 'records')(400, 'object or array', records)\n }\n }\n\n // Map the provided records to existing records.\n // New records will be inserted. If any records map to existing records,\n // they will be merged into the existing records according to the onConflict\n // option.\n records = records.map((record) => {\n let id = this.recordId(record)\n // Grab existing record if there is one\n const existing = id === undefined ? id : this.get(id)\n // If the currently visited record is just a reference to an existing\n // record, then there is nothing to be done. Exit early.\n if (record === existing) {\n return existing\n }\n\n if (existing) {\n // Here, the currently visited record corresponds to a record already\n // in the collection, so we need to merge them\n const onConflict = opts.onConflict || this.onConflict\n if (onConflict === 'merge') {\n utils.deepMixIn(existing, record)\n } else if (onConflict === 'replace') {\n utils.forOwn(existing, (value, key) => {\n if (key !== idAttribute && record[key] === undefined) {\n existing[key] = undefined\n }\n })\n existing.set(record)\n } else {\n throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)\n }\n record = existing\n if (opts.commitOnMerge && utils.isFunction(record.commit)) {\n record.commit()\n }\n // Update all indexes in the collection\n this.updateIndexes(record)\n } else {\n // Here, the currently visted record does not correspond to any record\n // in the collection, so (optionally) instantiate this record and insert\n // it into the collection\n record = this.mapper ? this.mapper.createRecord(record, opts) : record\n this.index.insertRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.insertRecord(record)\n })\n if (record && utils.isFunction(record.on)) {\n record.on('all', this._onRecordEvent, this)\n }\n }\n return record\n })\n // Finally, return the inserted data\n const result = singular ? records[0] : records\n this.emit('add', result)\n return this.afterAdd(records, opts, result) || result\n },\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then {@link Collection#add} will return that same value.\n *\n * @method Collection#method\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} result The record or records\n * that were added to this Collection by {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n afterAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}. If this method returns\n * a value then {@link Collection#remove} will return that same value.\n *\n * @method Collection#afterRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n * @param {Object} record The result that will be returned by {@link Collection#remove}.\n */\n afterRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}. If this method\n * returns a value then {@link Collection#removeAll} will return that same\n * value.\n *\n * @method Collection#afterRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n * @param {Object} records The result that will be returned by {@link Collection#removeAll}.\n */\n afterRemoveAll () {},\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then the `records` argument in {@link Collection#add} will be\n * re-assigned to the returned value.\n *\n * @method Collection#beforeAdd\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} records The `records` argument passed to {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n beforeAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}.\n *\n * @method Collection#beforeRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n */\n beforeRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}.\n *\n * @method Collection#beforeRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n */\n beforeRemoveAll () {},\n\n /**\n * Find all records between two boundaries.\n *\n * Shortcut for `collection.query().between(18, 30, { index: 'age' }).run()`\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = collection.between(18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = collection.between([18], [30], { index: 'age' })\n *\n * @method Collection#between\n * @since 3.0.0\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting records to skip.\n * @returns {Object[]|Record[]} The result.\n */\n between (leftKeys, rightKeys, opts) {\n return this.query().between(leftKeys, rightKeys, opts).run()\n },\n\n /**\n * Create a new secondary index on the contents of the collection.\n *\n * @example\n * // Index users by age\n * collection.createIndex('age')\n *\n * @example\n * // Index users by status and role\n * collection.createIndex('statusAndRole', ['status', 'role'])\n *\n * @method Collection#createIndex\n * @since 3.0.0\n * @param {string} name The name of the new secondary index.\n * @param {string[]} [fieldList] Array of field names to use as the key or\n * compound key of the new secondary index. If no fieldList is provided, then\n * the name will also be the field that is used to index the collection.\n */\n createIndex (name, fieldList, opts) {\n if (utils.isString(name) && fieldList === undefined) {\n fieldList = [name]\n }\n opts || (opts = {})\n opts.hashCode || (opts.hashCode = (obj) => this.recordId(obj))\n const index = this.indexes[name] = new Index(fieldList, opts)\n this.index.visitAll(index.insertRecord, index)\n },\n\n /**\n * Find the record or records that match the provided query or pass the\n * provided filter function.\n *\n * Shortcut for `collection.query().filter(queryOrFn[, thisArg]).run()`\n *\n * @example Collection#filter\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const collection = new Collection([\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = collection.filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = collection.filter(function (post) {\n * return post.id % 2 === 0\n * })\n *\n * @method Collection#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Object} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Array} The result.\n * @see query\n * @since 3.0.0\n */\n filter (query, thisArg) {\n return this.query().filter(query, thisArg).run()\n },\n\n /**\n * Iterate over all records.\n *\n * @example\n * collection.forEach(function (record) {\n * // do something\n * })\n *\n * @method Collection#forEach\n * @since 3.0.0\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Array} The result.\n */\n forEach (cb, thisArg) {\n this.index.visitAll(cb, thisArg)\n },\n\n /**\n * Get the record with the given id.\n *\n * @method Collection#get\n * @since 3.0.0\n * @param {(string|number)} id The primary key of the record to get.\n * @returns {(Object|Record)} The record with the given id.\n */\n get (id) {\n const instances = this.query().get(id).run()\n return instances.length ? instances[0] : undefined\n },\n\n /**\n * Find the record or records that match the provided keyLists.\n *\n * Shortcut for `collection.query().getAll(keyList1, keyList2, ...).run()`\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = collection.getAll('draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = collection.getAll(['draft'], ['inReview'], { index: 'status' })\n *\n * @method Collection#getAll\n * @since 3.0.0\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * records matching each keyList will be retrieved. If no keyLists are\n * provided, all records will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Array} The result.\n */\n getAll (...args) {\n return this.query().getAll(...args).run()\n },\n\n /**\n * Return the index with the given name. If no name is provided, return the\n * main index. Throws an error if the specified index does not exist.\n *\n * @method Collection#getIndex\n * @since 3.0.0\n * @param {string} [name] The name of the index to retrieve.\n */\n getIndex (name) {\n const index = name ? this.indexes[name] : this.index\n if (!index) {\n throw utils.err(`${DOMAIN}#getIndex`, name)(404, 'index')\n }\n return index\n },\n\n /**\n * Limit the result.\n *\n * Shortcut for `collection.query().limit(maximumNumber).run()`\n *\n * @example\n * const posts = collection.limit(10)\n *\n * @method Collection#limit\n * @since 3.0.0\n * @param {number} num The maximum number of records to keep in the result.\n * @returns {Array} The result.\n */\n limit (num) {\n return this.query().limit(num).run()\n },\n\n /**\n * Apply a mapping function to all records.\n *\n * @example\n * const names = collection.map(function (user) {\n * return user.name\n * })\n *\n * @method Collection#map\n * @since 3.0.0\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Array} The result of the mapping.\n */\n map (cb, thisArg) {\n const data = []\n this.index.visitAll(function (value) {\n data.push(cb.call(thisArg, value))\n })\n return data\n },\n\n /**\n * Return the result of calling the specified function on each record in this\n * collection's main index.\n *\n * @method Collection#mapCall\n * @since 3.0.0\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Array} The result.\n */\n mapCall (funcName, ...args) {\n const data = []\n this.index.visitAll(function (record) {\n data.push(record[funcName](...args))\n })\n return data\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#prune\n * @param {Object} [opts] Configuration options, passed to {@link Collection#removeAll}.\n * @since 3.0.0\n * @returns {Array} The removed records, if any.\n */\n prune (opts) {\n return this.removeAll(this.unsaved(), opts)\n },\n\n /**\n * Create a new query to be executed against the contents of the collection.\n * The result will be all or a subset of the contents of the collection.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * collection.query()\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method Collection#query\n * @since 3.0.0\n * @returns {Query} New query object.\n */\n query () {\n const Ctor = this.queryClass\n return new Ctor(this)\n },\n\n /**\n * Return the primary key of the given, or if no record is provided, return the\n * name of the field that holds the primary key of records in this Collection.\n *\n * @method Collection#recordId\n * @since 3.0.0\n * @param {(Object|Record)} [record] The record whose primary key is to be\n * returned.\n * @returns {(string|number)} Primary key or name of field that holds primary\n * key.\n */\n recordId (record) {\n if (record) {\n return utils.get(record, this.recordId())\n }\n return this.mapper ? this.mapper.idAttribute : this.idAttribute\n },\n\n /**\n * Reduce the data in the collection to a single value and return the result.\n *\n * @example\n * const totalVotes = collection.reduce(function (prev, record) {\n * return prev + record.upVotes + record.downVotes\n * }, 0)\n *\n * @method Collection#reduce\n * @since 3.0.0\n * @param {Function} cb Reduction callback.\n * @param {*} initialValue Initial value of the reduction.\n * @returns {*} The result.\n */\n reduce (cb, initialValue) {\n const data = this.getAll()\n return data.reduce(cb, initialValue)\n },\n\n /**\n * Remove the record with the given id from this Collection.\n *\n * @method Collection#remove\n * @since 3.0.0\n * @param {(string|number|object|Record)} idOrRecord The primary key of the\n * record to be removed, or a reference to the record that is to be removed.\n * @param {Object} [opts] Configuration options.\n * @returns {Object|Record} The removed record, if any.\n */\n remove (idOrRecord, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemove(idOrRecord, opts)\n let record = utils.isSorN(idOrRecord) ? this.get(idOrRecord) : idOrRecord\n\n // The record is in the collection, remove it\n if (utils.isObject(record)) {\n record = this.index.removeRecord(record)\n if (record) {\n utils.forOwn(this.indexes, function (index, name) {\n index.removeRecord(record)\n })\n if (utils.isFunction(record.off)) {\n record.off('all', this._onRecordEvent, this)\n if (!opts.silent) {\n this.emit('remove', record)\n }\n }\n }\n }\n return this.afterRemove(idOrRecord, opts, record) || record\n },\n\n /**\n * Remove from this collection the given records or the records selected by\n * the given \"query\".\n *\n * @method Collection#removeAll\n * @since 3.0.0\n * @param {Object|Object[]|Record[]} [queryOrRecords={}] Records to be removed or selection query. See {@link query}.\n * @param {Object} [queryOrRecords.where] See {@link query.where}.\n * @param {number} [queryOrRecords.offset] See {@link query.offset}.\n * @param {number} [queryOrRecords.limit] See {@link query.limit}.\n * @param {string|Array[]} [queryOrRecords.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object[]|Record[])} The removed records, if any.\n */\n removeAll (queryOrRecords, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemoveAll(queryOrRecords, opts)\n let records = utils.isArray(queryOrRecords) ? queryOrRecords.slice() : this.filter(queryOrRecords)\n\n // Remove each selected record from the collection\n const optsCopy = utils.plainCopy(opts)\n optsCopy.silent = true\n records = records\n .map((record) => this.remove(record, optsCopy))\n .filter((record) => record)\n if (!opts.silent) {\n this.emit('remove', records)\n }\n return this.afterRemoveAll(queryOrRecords, opts, records) || records\n },\n\n /**\n * Skip a number of results.\n *\n * Shortcut for `collection.query().skip(numberToSkip).run()`\n *\n * @example\n * const posts = collection.skip(10)\n *\n * @method Collection#skip\n * @since 3.0.0\n * @param {number} num The number of records to skip.\n * @returns {Array} The result.\n */\n skip (num) {\n return this.query().skip(num).run()\n },\n\n /**\n * Return the plain JSON representation of all items in this collection.\n * Assumes records in this collection have a toJSON method.\n *\n * @method Collection#toJSON\n * @since 3.0.0\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation.\n * @returns {Array} The records.\n */\n toJSON (opts) {\n return this.mapCall('toJSON', opts)\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#unsaved\n * @since 3.0.0\n * @returns {Array} The unsaved records, if any.\n */\n unsaved (opts) {\n return this.index.get()\n },\n\n /**\n * Update a record's position in a single index of this collection. See\n * {@link Collection#updateIndexes} to update a record's position in all\n * indexes at once.\n *\n * @method Collection#updateIndex\n * @since 3.0.0\n * @param {Object} record The record to update.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] The index in which to update the record's\n * position. If you don't specify an index then the record will be updated\n * in the main index.\n */\n updateIndex (record, opts) {\n opts || (opts = {})\n this.getIndex(opts.index).updateRecord(record)\n },\n\n /**\n * Updates all indexes in this collection for the provided record. Has no\n * effect if the record is not in the collection.\n *\n * @method Collection#updateIndexes\n * @since 3.0.0\n * @param {Object} record TODO\n */\n updateIndexes (record) {\n this.index.updateRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.updateRecord(record)\n })\n }\n})\n\n/**\n * Fired when a record changes. Only works for records that have tracked changes.\n * See {@link Collection~changeListener} on how to listen for this event.\n *\n * @event Collection#change\n * @see Collection~changeListener\n */\n\n/**\n * Callback signature for the {@link Collection#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * collection.on('change', onChange)\n *\n * @callback Collection~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Collection#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the Collection. See\n * {@link Collection~addListener} on how to listen for this event.\n *\n * @event Collection#add\n * @see Collection~addListener\n * @see Collection#event:add\n * @see Collection#add\n */\n\n/**\n * Callback signature for the {@link Collection#event:add} event.\n *\n * @example\n * function onAdd (recordOrRecords) {\n * // do something\n * }\n * collection.on('add', onAdd)\n *\n * @callback Collection~addListener\n * @param {Record|Record[]} The Record or Records that were added.\n * @see Collection#event:add\n * @see Collection#add\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the Collection. See\n * {@link Collection~removeListener} for how to listen for this event.\n *\n * @event Collection#remove\n * @see Collection~removeListener\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n */\n\n/**\n * Callback signature for the {@link Collection#event:remove} event.\n *\n * @example\n * function onRemove (recordsOrRecords) {\n * // do something\n * }\n * collection.on('remove', onRemove)\n *\n * @callback Collection~removeListener\n * @param {Record|Record[]} Record or Records that were removed.\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Collection:\n * @example Collection.extend\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomCollectionClass extends Collection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customCollection = new CustomCollectionClass()\n * console.log(customCollection.foo())\n * console.log(CustomCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherCollectionClass = Collection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherCollection = new OtherCollectionClass()\n * console.log(otherCollection.foo())\n * console.log(OtherCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherCollectionClass () {\n * Collection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Collection.extend({\n * constructor: AnotherCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherCollection = new AnotherCollectionClass()\n * console.log(anotherCollection.created_at)\n * console.log(anotherCollection.foo())\n * console.log(AnotherCollectionClass.beep())\n *\n * @method Collection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Collection class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Settable from './Settable'\n\nconst DOMAIN = 'Record'\n\nconst superMethod = function (mapper, name) {\n const store = mapper.datastore\n if (store && store[name]) {\n return function (...args) {\n return store[name](mapper.name, ...args)\n }\n }\n return mapper[name].bind(mapper)\n}\n\n/**\n * js-data's Record class. An instance of `Record` corresponds to an in-memory\n * representation of a single row or document in a database, Firebase,\n * localstorage, etc. Basically, a `Record` instance represents whatever kind of\n * entity in your persistence layer that has a primary key.\n *\n * ```javascript\n * import {Record} from 'js-data'\n * ```\n *\n * @example Record#constructor\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a plain record\n * let record = new Record()\n * console.log('record: ' + JSON.stringify(record))\n *\n * // You can supply properties on instantiation\n * record = new Record({ name: 'John' })\n * console.log('record: ' + JSON.stringify(record))\n *\n * @example Record#constructor2\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a record that's associated with a Mapper:\n * const UserMapper = new Mapper({ name: 'user' })\n * const User = UserMapper.recordClass\n * const user = UserMapper.createRecord({ name: 'John' })\n * const user2 = new User({ name: 'Sally' })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user2: ' + JSON.stringify(user2))\n *\n * @example Record#constructor3\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n *\n * // Instantiate a record that's associated with a store's Mapper\n * const user = store.createRecord('user', { name: 'John' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor4\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Validate on instantiation\n * const user = store.createRecord('user', { name: 1234 })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor5\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Skip validation on instantiation\n * const user = store.createRecord('user', { name: 1234 }, { noValidate: true })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user.isValid(): ' + user.isValid())\n *\n * @class Record\n * @extends Component\n * @param {Object} [props] The initial properties of the new Record instance.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate=false] Whether to skip validation on the\n * initial properties.\n * @since 3.0.0\n */\nfunction Record (props, opts) {\n utils.classCallCheck(this, Record)\n Settable.call(this)\n props || (props = {})\n opts || (opts = {})\n const _set = this._set\n // TODO: Optimize these strings\n _set('creating', true)\n if (opts.noValidate) {\n _set('noValidate', true)\n }\n // Set the idAttribute value first, if it exists.\n const mapper = this.constructor.mapper\n const id = mapper ? utils.get(props, mapper.idAttribute) : undefined\n if (id !== undefined) {\n utils.set(this, mapper.idAttribute, id)\n }\n utils.fillIn(this, props)\n _set('creating', false)\n _set('noValidate', false)\n _set('previous', utils.plainCopy(props))\n}\n\nexport default Component.extend({\n constructor: Record,\n\n /**\n * Returns the {@link Mapper} paired with this record's class, if any.\n *\n * @method Record#_mapper\n * @returns {Mapper} The {@link Mapper} paired with this record's class, if any.\n * @since 3.0.0\n */\n _mapper () {\n const mapper = this.constructor.mapper\n if (!mapper) {\n throw utils.err(`${DOMAIN}#_mapper`, '')(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Lifecycle hook.\n *\n * @method Record#afterLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n afterLoadRelations () {},\n\n /**\n * Lifecycle hook.\n *\n * @method Record#beforeLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n beforeLoadRelations () {},\n\n /**\n * Return the change history of this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @method Record#changeHistory\n * @since 3.0.0\n */\n changeHistory () {\n return (this._get('history') || []).slice()\n },\n\n /**\n * Return changes to this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#changes\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n * user.name = 'John'\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n *\n * @method Record#changes\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} Object describing the changes to this record since it was\n * instantiated or its {@link Record#commit} method was last called.\n * @since 3.0.0\n */\n changes (opts) {\n opts || (opts = {})\n return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Make the record's current in-memory state it's only state, with any\n * previous property values being set to current values.\n *\n * @example Record#commit\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#commit\n * @since 3.0.0\n */\n commit () {\n this._set('changed') // unset\n this._set('history', []) // clear history\n this._set('previous', utils.plainCopy(this))\n },\n\n /**\n * Call {@link Mapper#destroy} using this record's primary key.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user')\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Destroy this user from the database\n * return user.destroy()\n * })\n *\n * @method Record#destroy\n * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}.\n * @returns {Promise} The result of calling {@link Mapper#destroy} with the\n * primary key of this record.\n * @since 3.0.0\n */\n destroy (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts)\n },\n\n /**\n * Return the value at the given path for this instance.\n *\n * @example Record#get\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', { name: 'Bob' })\n * console.log('user.get(\"name\"): ' + user.get('name'))\n *\n * @method Record#get\n * @param {string} key Path of value to retrieve.\n * @returns {*} Value at path.\n * @since 3.0.0\n */\n 'get' (key) {\n return utils.get(this, key)\n },\n\n /**\n * Return whether this record has changed since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#hasChanges\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#hasChanges\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Return whether the record has changed since it was\n * instantiated or since its {@link Record#commit} method was called.\n * @since 3.0.0\n */\n hasChanges (opts) {\n const quickHasChanges = !!(this._get('changed') || []).length\n return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Return whether the record is unsaved. Records that have primary keys are\n * considered \"saved\". Records without primary keys are considered \"unsaved\".\n *\n * @example Record#isNew\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * id: 1234\n * })\n * const user2 = store.createRecord('user')\n * console.log('user isNew: ' + user.isNew()) // false\n * console.log('user2 isNew: ' + user2.isNew()) // true\n *\n * @method Record#isNew\n * @returns {boolean} Whether the record is unsaved.\n * @since 3.0.0\n */\n isNew (opts) {\n return utils.get(this, this._mapper().idAttribute) === undefined\n },\n\n /**\n * Return whether the record in its current state passes validation.\n *\n * @example Record#isValid\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user isValid: ' + user.isValid())\n * user.name = 'John'\n * console.log('user isValid: ' + user.isValid())\n *\n * @method Record#isValid\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {boolean} Whether the record in its current state passes\n * validation.\n * @since 3.0.0\n */\n isValid (opts) {\n return !this._mapper().validate(this, opts)\n },\n\n /**\n * Lazy load relations of this record, to be attached to the record once their\n * loaded.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user', {\n * relations: {\n * hasMany: {\n * post: {\n * localField: 'posts',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.defineMapper('post', {\n * relations: {\n * belongsTo: {\n * user: {\n * localField: 'user',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Load the user's post relations\n * return user.loadRelations(['post'])\n * }).then((user) => {\n * console.log(user.posts) // [{...}, {...}, ...]\n * })\n *\n * @method Record#loadRelations\n * @param {string[]} [relations] List of relations to load. Can use localField\n * names or Mapper names to pick relations.\n * @param {Object} [opts] Configuration options.\n * @returns {Promise} Resolves with the record, with the loaded relations now\n * attached.\n * @since 3.0.0\n */\n loadRelations (relations, opts) {\n let op\n const mapper = this._mapper()\n\n // Default values for arguments\n relations || (relations = [])\n if (utils.isString(relations)) {\n relations = [relations]\n }\n opts || (opts = {})\n opts.with = relations\n\n // Fill in \"opts\" with the Model's configuration\n utils._(opts, mapper)\n opts.adapter = mapper.getAdapterName(opts)\n\n // beforeLoadRelations lifecycle hook\n op = opts.op = 'beforeLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'loadRelations'\n mapper.dbg(op, this, relations, opts)\n let tasks = []\n let task\n utils.forEachRelation(mapper, opts, (def, optsCopy) => {\n const relatedMapper = def.getRelation()\n optsCopy.raw = false\n if (utils.isFunction(def.load)) {\n task = def.load(mapper, def, this, opts)\n } else if (def.type === 'hasMany' || def.type === 'hasOne') {\n if (def.foreignKey) {\n task = superMethod(relatedMapper, 'findAll')({\n [def.foreignKey]: utils.get(this, mapper.idAttribute)\n }, optsCopy).then(function (relatedData) {\n if (def.type === 'hasOne') {\n return relatedData.length ? relatedData[0] : undefined\n }\n return relatedData\n })\n } else if (def.localKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [relatedMapper.idAttribute]: {\n 'in': utils.get(this, def.localKeys)\n }\n }\n })\n } else if (def.foreignKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [def.foreignKeys]: {\n 'contains': utils.get(this, mapper.idAttribute)\n }\n }\n }, opts)\n }\n } else if (def.type === 'belongsTo') {\n const key = utils.get(this, def.foreignKey)\n if (utils.isSorN(key)) {\n task = superMethod(relatedMapper, 'find')(key, optsCopy)\n }\n }\n if (task) {\n task = task.then((relatedData) => {\n def.setLocalField(this, relatedData)\n })\n tasks.push(task)\n }\n })\n return Promise.all(tasks)\n }).then(() => {\n // afterLoadRelations lifecycle hook\n op = opts.op = 'afterLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => this)\n })\n },\n\n /**\n * Return the properties with which this record was instantiated.\n *\n * @example Record#previous\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.name = 'Bob'\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.commit()\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n *\n * @method Record#previous\n * @param {string} [key] If specified, return just the initial value of the\n * given key.\n * @returns {Object} The initial properties of this record.\n * @since 3.0.0\n */\n previous (key) {\n if (key) {\n return this._get(`previous.${key}`)\n }\n return this._get('previous')\n },\n\n /**\n * Revert changes to this record back to the properties it had when it was\n * instantiated.\n *\n * @example Record#revert\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user: ' + JSON.stringify(user))\n * user.name = 'Bob'\n * console.log('user: ' + JSON.stringify(user))\n * user.revert()\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#revert\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.preserve] Array of strings or Regular Expressions\n * denoting properties that should not be reverted.\n * @since 3.0.0\n */\n revert (opts) {\n const previous = this._get('previous')\n opts || (opts = {})\n opts.preserve || (opts.preserve = [])\n utils.forOwn(this, (value, key) => {\n if (key !== this._mapper().idAttribute && !previous.hasOwnProperty(key) && this.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) {\n delete this[key]\n }\n })\n utils.forOwn(previous, (value, key) => {\n if (opts.preserve.indexOf(key) === -1) {\n this[key] = value\n }\n })\n this.commit()\n },\n\n /**\n * Delegates to {@link Mapper#create} or {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('session')\n * const session = store.createRecord('session', { topic: 'Node.js' })\n *\n * // Create a new record in the database\n * session.save().then(() => {\n * console.log(session.id) // 1234\n *\n * session.skill_level = 'beginner'\n *\n * // Update the record in the database\n * return user.save()\n * })\n *\n * @method Record#save\n * @param {Object} [opts] Configuration options. See {@link Mapper#create} and\n * {@link Mapper#update}.\n * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`.\n * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @param {Array} [opts.ignore] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @returns {Promise} The result of calling {@link Mapper#create} or\n * {@link Mapper#update}.\n * @since 3.0.0\n */\n save (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n const id = utils.get(this, mapper.idAttribute)\n let props = this\n\n const postProcess = (result) => {\n const record = opts.raw ? result.data : result\n if (record) {\n utils.deepMixIn(this, record)\n this.commit()\n }\n return result\n }\n\n if (id === undefined) {\n return superMethod(mapper, 'create')(props, opts).then(postProcess)\n }\n if (opts.changesOnly) {\n const changes = this.changes(opts)\n props = {}\n utils.fillIn(props, changes.added)\n utils.fillIn(props, changes.changed)\n }\n return superMethod(mapper, 'update')(id, props, opts).then(postProcess)\n },\n\n /**\n * Set the value for a given key, or the values for the given keys if \"key\" is\n * an object. Triggers change events on those properties that have `track: true`\n * in {@link Mapper#schema}.\n *\n * @example Record#set\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set('name', 'Bob')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set({ age: 30, role: 'admin' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @fires Record#change\n * @method Record#set\n * @param {(string|Object)} key Key to set or hash of key-value pairs to set.\n * @param {*} [value] Value to set for the given key.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n 'set' (key, value, opts) {\n if (utils.isObject(key)) {\n opts = value\n }\n opts || (opts = {})\n if (opts.silent) {\n this._set('silent', true)\n }\n utils.set(this, key, value)\n if (!this._get('eventId')) {\n this._set('silent') // unset\n }\n },\n\n /**\n * Return a plain object representation of this record. If the class from\n * which this record was created has a Mapper, then {@link Mapper#toJSON} will\n * be called with this record instead.\n *\n * @example Record#toJSON\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * const user = store.createRecord('user', {\n * name: 'John',\n * $$hashKey: '1234'\n * })\n * console.log('user: ' + JSON.stringify(user.toJSON()))\n * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true })))\n *\n * @method Record#toJSON\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation. Only available as an option if the class\n * from which this record was created has a Mapper and this record resides in\n * an instance of {@link DataStore}.\n * @returns {Object} Plain object representation of this record.\n * @since 3.0.0\n */\n toJSON (opts) {\n const mapper = this.constructor.mapper\n if (mapper) {\n return mapper.toJSON(this, opts)\n } else {\n const json = {}\n utils.forOwn(this, function (prop, key) {\n json[key] = utils.plainCopy(prop)\n })\n return json\n }\n },\n\n /**\n * Unset the value for a given key. Triggers change events on those properties\n * that have `track: true` in {@link Mapper#schema}.\n *\n * @example Record#unset\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', {\n * name: 'John'\n * })\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.unset('name')\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#unset\n * @param {string} key Key to unset.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n unset (key, opts) {\n this.set(key, undefined, opts)\n },\n\n /**\n * Validate this record based on its current properties.\n *\n * @example Record#validate\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user validation: ' + JSON.stringify(user.validate()))\n * user.name = 'John'\n * console.log('user validation: ' + user.validate())\n *\n * @method Record#validate\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {*} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (opts) {\n return this._mapper().validate(this, opts)\n }\n})\n\n/**\n * Allow records to emit events.\n *\n * An record's registered listeners are stored in the record's private data.\n */\nutils.eventify(\n Record.prototype,\n function () {\n return this._get('events')\n },\n function (value) {\n this._set('events', value)\n }\n)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link Record~changeListener} on how to listen for this event.\n *\n * @event Record#change\n * @see Record~changeListener\n */\n\n/**\n * Callback signature for the {@link Record#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * record.on('change', onChange)\n *\n * @callback Record~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Record#event:change\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Record:\n * @example Record.extend\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomRecordClass extends Record {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customRecord = new CustomRecordClass()\n * console.log(customRecord.foo())\n * console.log(CustomRecordClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherRecordClass = Record.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherRecord = new OtherRecordClass()\n * console.log(otherRecord.foo())\n * console.log(OtherRecordClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherRecordClass () {\n * Record.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Record.extend({\n * constructor: AnotherRecordClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherRecord = new AnotherRecordClass()\n * console.log(anotherRecord.created_at)\n * console.log(anotherRecord.foo())\n * console.log(AnotherRecordClass.beep())\n *\n * @method Record.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Record class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Schema'\n\n/**\n * A function map for each of the seven primitive JSON types defined by the core specification.\n * Each function will check a given value and return true or false if the value is an instance of that type.\n * ```\n * types.integer(1) // returns true\n * types.string({}) // returns false\n * ```\n * http://json-schema.org/latest/json-schema-core.html#anchor8\n * @name Schema.types\n * @type {Object}\n */\nconst types = {\n array: utils.isArray,\n boolean: utils.isBoolean,\n integer: utils.isInteger,\n 'null': utils.isNull,\n number: utils.isNumber,\n object: utils.isObject,\n string: utils.isString\n}\n\n/**\n * @ignore\n */\nconst segmentToString = function (segment, prev) {\n let str = ''\n if (segment) {\n if (utils.isNumber(segment)) {\n str += `[${segment}]`\n } else if (prev) {\n str += `.${segment}`\n } else {\n str += `${segment}`\n }\n }\n return str\n}\n\n/**\n * @ignore\n */\nconst makePath = function (opts) {\n opts || (opts = {})\n let path = ''\n const segments = opts.path || []\n segments.forEach(function (segment) {\n path += segmentToString(segment, path)\n })\n path += segmentToString(opts.prop, path)\n return path\n}\n\n/**\n * @ignore\n */\nconst makeError = function (actual, expected, opts) {\n return {\n expected,\n actual: '' + actual,\n path: makePath(opts)\n }\n}\n\n/**\n * @ignore\n */\nconst addError = function (actual, expected, opts, errors) {\n errors.push(makeError(actual, expected, opts))\n}\n\n/**\n * @ignore\n */\nconst maxLengthCommon = function (keyword, value, schema, opts) {\n const max = schema[keyword]\n if (value.length > max) {\n return makeError(value.length, `length no more than ${max}`, opts)\n }\n}\n\n/**\n * @ignore\n */\nconst minLengthCommon = function (keyword, value, schema, opts) {\n const min = schema[keyword]\n if (value.length < min) {\n return makeError(value.length, `length no less than ${min}`, opts)\n }\n}\n\n/**\n * A map of all object member validation functions for each keyword defined in the JSON Schema.\n * @name Schema.validationKeywords\n * @type {Object}\n */\nconst validationKeywords = {\n /**\n * Validates the provided value against all schemas defined in the Schemas `allOf` keyword.\n * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be a valid JSON Schema.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor82\n *\n * @name Schema.validationKeywords.allOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `allOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n allOf (value, schema, opts) {\n let allErrors = []\n schema.allOf.forEach(function (_schema) {\n allErrors = allErrors.concat(validate(value, _schema, opts) || [])\n })\n return allErrors.length ? undefined : allErrors\n },\n\n /**\n * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword.\n * The instance is valid against this keyword if and only if it is valid against\n * at least one of the schemas in this keyword's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor85\n *\n * @name Schema.validationKeywords.anyOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `anyOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n anyOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.anyOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * http://json-schema.org/latest/json-schema-validation.html#anchor70\n *\n * @name Schema.validationKeywords.dependencies\n * @method\n * @param {*} value TODO\n * @param {Object} schema TODO\n * @param {Object} opts TODO\n */\n dependencies (value, schema, opts) {\n // TODO\n },\n\n /**\n * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword\n * Validation succeeds if the value is deeply equal to one of the values in the array.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor76\n *\n * @name Schema.validationKeywords.enum\n * @method\n * @param {*} value Value to validate\n * @param {Object} schema Schema containing the `enum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n enum (value, schema, opts) {\n const possibleValues = schema['enum']\n if (utils.findIndex(possibleValues, (item) => utils.deepEqual(item, value)) === -1) {\n return makeError(value, `one of (${possibleValues.join(', ')})`, opts)\n }\n },\n\n /**\n * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword\n * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules.\n *\n * @name Schema.validationKeywords.items\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the items keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n items (value, schema, opts) {\n opts || (opts = {})\n // TODO: additionalItems\n let items = schema.items\n let errors = []\n const checkingTuple = utils.isArray(items)\n const length = value.length\n for (var prop = 0; prop < length; prop++) {\n if (checkingTuple) {\n // Validating a tuple, instead of just checking each item against the\n // same schema\n items = schema.items[prop]\n }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], items, opts) || [])\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword\n * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor17\n *\n * @name Schema.validationKeywords.maximum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `maximum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maximum (value, schema, opts) {\n // Must be a number\n const maximum = schema.maximum\n // Must be a boolean\n // Depends on maximum\n // default: false\n const exclusiveMaximum = schema.exclusiveMaximum\n if (typeof value === typeof maximum && !(exclusiveMaximum ? maximum > value : maximum >= value)) {\n return exclusiveMaximum\n ? makeError(value, `no more than nor equal to ${maximum}`, opts)\n : makeError(value, `no more than ${maximum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword.\n * Validation succeeds if the length of the array is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor42\n *\n * @name Schema.validationKeywords.maxItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `maxItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return maxLengthCommon('maxItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword.\n * Validation succeeds if the length of the string is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor26\n *\n * @name Schema.validationKeywords.maxLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `maxLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxLength (value, schema, opts) {\n return maxLengthCommon('maxLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword.\n * Validation succeeds if the object's property count is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor54\n *\n * @name Schema.validationKeywords.maxProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `maxProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const maxProperties = schema.maxProperties\n const length = Object.keys(value).length\n if (length > maxProperties) {\n return makeError(length, `no more than ${maxProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword\n * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor21\n *\n * @name Schema.validationKeywords.minimum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `minimum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minimum (value, schema, opts) {\n // Must be a number\n const minimum = schema.minimum\n // Must be a boolean\n // Depends on minimum\n // default: false\n const exclusiveMinimum = schema.exclusiveMinimum\n if (typeof value === typeof minimum && !(exclusiveMinimum ? value > minimum : value >= minimum)) {\n return exclusiveMinimum\n ? makeError(value, `no less than nor equal to ${minimum}`, opts)\n : makeError(value, `no less than ${minimum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword.\n * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor45\n *\n * @name Schema.validationKeywords.minItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `minItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return minLengthCommon('minItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword.\n * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor29\n *\n * @name Schema.validationKeywords.minLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `minLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minLength (value, schema, opts) {\n return minLengthCommon('minLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword.\n * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor57\n *\n * @name Schema.validationKeywords.minProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `minProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const minProperties = schema.minProperties\n const length = Object.keys(value).length\n if (length < minProperties) {\n return makeError(length, `no more than ${minProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword.\n * Validation succeeds if the number can be divided equally into the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor14\n *\n * @name Schema.validationKeywords.multipleOf\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing the `multipleOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n multipleOf (value, schema, opts) {\n const multipleOf = schema.multipleOf\n if (utils.isNumber(value)) {\n if ((value / multipleOf) % 1 !== 0) {\n return makeError(value, `multipleOf ${multipleOf}`, opts)\n }\n }\n },\n\n /**\n * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword.\n * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor91\n * @name Schema.validationKeywords.not\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the not keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n not (value, schema, opts) {\n if (!validate(value, schema.not, opts)) {\n // TODO: better messaging\n return makeError('succeeded', 'should have failed', opts)\n }\n },\n\n /**\n * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword.\n * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor88\n * @name Schema.validationKeywords.oneOf\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the `oneOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n oneOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.oneOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else if (validated) {\n allErrors = [makeError('valid against more than one', 'valid against only one', opts)]\n validated = false\n return false\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword.\n * Validation succeeds if the string is a match of the regex value of this keyword.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor33\n * @name Schema.validationKeywords.pattern\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `pattern` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n pattern (value, schema, opts) {\n const pattern = schema.pattern\n if (utils.isString(value) && !value.match(pattern)) {\n return makeError(value, pattern, opts)\n }\n },\n\n /**\n * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword.\n * Validation succeeds if the object's property are valid with each of the schema's in the provided map.\n * Validation also depends on the additionalProperties and or patternProperties.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info.\n *\n * @name Schema.validationKeywords.properties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `properties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n properties (value, schema, opts) {\n opts || (opts = {})\n // Can be a boolean or an object\n // Technically the default is an \"empty schema\", but here \"true\" is\n // functionally the same\n const additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties\n // \"s\": The property set of the instance to validate.\n const toValidate = {}\n // \"p\": The property set from \"properties\".\n // Default is an object\n const properties = schema.properties || {}\n // \"pp\": The property set from \"patternProperties\".\n // Default is an object\n const patternProperties = schema.patternProperties || {}\n let errors = []\n\n // Collect set \"s\"\n utils.forOwn(value, function (_value, prop) {\n toValidate[prop] = undefined\n })\n // Remove from \"s\" all elements of \"p\", if any.\n utils.forOwn(properties || {}, function (_schema, prop) {\n // if (value[prop] === undefined && _schema['default'] !== undefined) {\n // value[prop] = utils.copy(_schema['default'])\n // }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n })\n // For each regex in \"pp\", remove all elements of \"s\" which this regex\n // matches.\n utils.forOwn(patternProperties, function (_schema, pattern) {\n utils.forOwn(toValidate, function (undef, prop) {\n if (prop.match(pattern)) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n }\n })\n })\n const keys = Object.keys(toValidate)\n // If \"s\" is not empty, validation fails\n if (additionalProperties === false) {\n if (keys.length) {\n addError(`extra fields: ${keys.join(', ')}`, 'no extra fields', opts, errors)\n }\n } else if (utils.isObject(additionalProperties)) {\n // Otherwise, validate according to provided schema\n keys.forEach(function (prop) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], additionalProperties, opts) || [])\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided object's has all properties listed in the Schema's `properties` keyword array.\n * Validation succeeds if the object contains all properties provided in the array value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor61\n *\n * @name Schema.validationKeywords.required\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `required` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n required (value, schema, opts) {\n opts || (opts = {})\n const required = schema.required\n let errors = []\n if (!opts.existingOnly) {\n required.forEach(function (prop) {\n if (utils.get(value, prop) === undefined) {\n const prevProp = opts.prop\n opts.prop = prop\n addError(undefined, 'a value', opts, errors)\n opts.prop = prevProp\n }\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor79\n *\n * @name Schema.validationKeywords.type\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `type` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n type (value, schema, opts) {\n let type = schema.type\n let validType\n // Can be one of several types\n if (utils.isString(type)) {\n type = [type]\n }\n // Try to match the value against an expected type\n type.forEach(function (_type) {\n // TODO: throw an error if type is not defined\n if (types[_type](value, schema, opts)) {\n // Matched a type\n validType = _type\n return false\n }\n })\n // Value did not match any expected type\n if (!validType) {\n return makeError(value !== undefined && value !== null ? typeof value : '' + value, `one of (${type.join(', ')})`, opts)\n }\n // Run keyword validators for matched type\n // http://json-schema.org/latest/json-schema-validation.html#anchor12\n const validator = typeGroupValidators[validType]\n if (validator) {\n return validator(value, schema, opts)\n }\n },\n\n /**\n * Validates the provided array values are unique.\n * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true\n * see http://json-schema.org/latest/json-schema-validation.html#anchor49\n *\n * @name Schema.validationKeywords.uniqueItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `uniqueItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n uniqueItems (value, schema, opts) {\n if (value && value.length && schema.uniqueItems) {\n const length = value.length\n let item, i, j\n // Check n - 1 items\n for (i = length - 1; i > 0; i--) {\n item = value[i]\n // Only compare against unchecked items\n for (j = i - 1; j >= 0; j--) {\n // Found a duplicate\n if (utils.deepEqual(item, value[j])) {\n return makeError(item, 'no duplicates', opts)\n }\n }\n }\n }\n }\n}\n\n/**\n * @ignore\n */\nconst validateKeyword = function (op, value, schema, opts) {\n return schema[op] !== undefined && validationKeywords[op](value, schema, opts)\n}\n\n/**\n * @ignore\n */\nconst runOps = function (ops, value, schema, opts) {\n let errors = []\n ops.forEach(function (op) {\n errors = errors.concat(validateKeyword(op, value, schema, opts) || [])\n })\n return errors.length ? errors : undefined\n}\n\nconst ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']\nconst ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']\nconst NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']\nconst OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\nconst STRING_OPS = ['maxLength', 'minLength', 'pattern']\n\n/**\n * http://json-schema.org/latest/json-schema-validation.html#anchor75\n * @ignore\n */\nconst validateAny = function (value, schema, opts) {\n return runOps(ANY_OPS, value, schema, opts)\n}\n\n/**\n * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification.\n *\n * @name Schema.validate\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\nconst validate = function (value, schema, opts) {\n let errors = []\n opts || (opts = {})\n opts.ctx || (opts.ctx = { value, schema })\n let shouldPop\n let prevProp = opts.prop\n if (schema === undefined) {\n return\n }\n if (!utils.isObject(schema)) {\n throw utils.err(`${DOMAIN}#validate`)(500, `Invalid schema at path: \"${opts.path}\"`)\n }\n if (opts.path === undefined) {\n opts.path = []\n }\n // Track our location as we recurse\n if (opts.prop !== undefined) {\n shouldPop = true\n opts.path.push(opts.prop)\n opts.prop = undefined\n }\n // Validate against parent schema\n if (schema['extends']) {\n // opts.path = path\n // opts.prop = prop\n if (utils.isFunction(schema['extends'].validate)) {\n errors = errors.concat(schema['extends'].validate(value, opts) || [])\n } else {\n errors = errors.concat(validate(value, schema['extends'], opts) || [])\n }\n }\n if (value === undefined) {\n // Check if property is required\n if (schema.required === true && !opts.existingOnly) {\n addError(value, 'a value', opts, errors)\n }\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n }\n\n errors = errors.concat(validateAny(value, schema, opts) || [])\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n}\n\n// These strings are cached for optimal performance of the change detection\n// boolean - Whether a Record is changing in the current execution frame\nconst changingPath = 'changing'\n// string[] - Properties that have changed in the current execution frame\nconst changedPath = 'changed'\n// Object[] - History of change records\nconst changeHistoryPath = 'history'\n// boolean - Whether a Record is currently being instantiated\nconst creatingPath = 'creating'\n// number - The setTimeout change event id of a Record, if any\nconst eventIdPath = 'eventId'\n// boolean - Whether to skip validation for a Record's currently changing property\nconst noValidatePath = 'noValidate'\n// boolean - Whether to skip change notification for a Record's currently\n// changing property\nconst silentPath = 'silent'\nconst validationFailureMsg = 'validation failed'\n\n/**\n * Assemble a property descriptor which will be added to the prototype of\n * {@link Mapper#recordClass}. This method is called when\n * {@link Mapper#applySchema} is set to `true`.\n *\n * @ignore\n */\nconst makeDescriptor = function (prop, schema, opts) {\n const descriptor = {\n // Better to allow configurability, but at the user's own risk\n configurable: true,\n // These properties are enumerable by default, but regardless of their\n // enumerability, they won't be \"own\" properties of individual records\n enumerable: schema.enumerable === undefined ? true : !!schema.enumerable\n }\n // Cache a few strings for optimal performance\n const keyPath = `props.${prop}`\n const previousPath = `previous.${prop}`\n const getter = opts.getter\n const setter = opts.setter\n const unsetter = opts.unsetter\n const track = utils.isBoolean(opts.track) ? opts.track : schema.track\n\n descriptor.get = function () {\n return this._get(keyPath)\n }\n\n if (utils.isFunction(schema.get)) {\n const originalGet = descriptor.get\n descriptor.get = function () {\n return schema.get.call(this, originalGet)\n }\n }\n\n descriptor.set = function (value) {\n // These are accessed a lot\n const _get = this[getter]\n const _set = this[setter]\n const _unset = this[unsetter]\n\n // Optionally check that the new value passes validation\n if (!_get(noValidatePath)) {\n const errors = schema.validate(value, { path: [prop] })\n if (errors) {\n // Immediately throw an error, preventing the record from getting into\n // an invalid state\n const error = new Error(validationFailureMsg)\n error.errors = errors\n throw error\n }\n }\n // TODO: Make it so tracking can be turned on for all properties instead of\n // only per-property\n if (track && !_get(creatingPath)) {\n const previous = _get(previousPath)\n const current = _get(keyPath)\n let changing = _get(changingPath)\n let changed = _get(changedPath)\n\n if (!changing) {\n // Track properties that are changing in the current event loop\n changed = []\n }\n\n // Add changing properties to this array once at most\n const index = changed.indexOf(prop)\n if (current !== value && index === -1) {\n changed.push(prop)\n }\n if (previous === value) {\n if (index >= 0) {\n changed.splice(index, 1)\n }\n }\n // No changes in current event loop\n if (!changed.length) {\n changing = false\n _unset(changingPath)\n _unset(changedPath)\n // Cancel pending change event\n if (_get(eventIdPath)) {\n clearTimeout(_get(eventIdPath))\n _unset(eventIdPath)\n }\n }\n // Changes detected in current event loop\n if (!changing && changed.length) {\n _set(changedPath, changed)\n _set(changingPath, true)\n // Saving the timeout id allows us to batch all changes in the same\n // event loop into a single \"change\"\n // TODO: Optimize\n _set(eventIdPath, setTimeout(() => {\n // Previous event loop where changes were gathered has ended, so\n // notify any listeners of those changes and prepare for any new\n // changes\n _unset(changedPath)\n _unset(eventIdPath)\n _unset(changingPath)\n // TODO: Optimize\n if (!_get(silentPath)) {\n let i\n for (i = 0; i < changed.length; i++) {\n this.emit('change:' + changed[i], this, utils.get(this, changed[i]))\n }\n const changes = this.changes()\n const changeRecord = utils.plainCopy(changes)\n changeRecord.timestamp = new Date().getTime()\n const changeHistory = _get(changeHistoryPath) || []\n _set(changeHistoryPath, changeHistory)\n changeHistory.push(changeRecord)\n this.emit('change', this, changes)\n }\n _unset(silentPath)\n }, 0))\n }\n }\n _set(keyPath, value)\n return value\n }\n\n if (utils.isFunction(schema.set)) {\n const originalSet = descriptor.set\n descriptor.set = function (value) {\n return schema.set.call(this, value, originalSet)\n }\n }\n\n return descriptor\n}\n\n/**\n * A map of validation functions grouped by type.\n *\n * @name Schema.typeGroupValidators\n * @type {Object}\n */\nconst typeGroupValidators = {\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an array.\n * The validation keywords for the type `array` are:\n *```\n * ['items', 'maxItems', 'minItems', 'uniqueItems']\n *```\n * see http://json-schema.org/latest/json-schema-validation.html#anchor25\n *\n * @name Schema.typeGroupValidators.array\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing at least one array keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n array: function (value, schema, opts) {\n return runOps(ARRAY_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer.\n * The validation keywords for the type `integer` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.integer\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `integer` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n integer: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an number.\n * The validation keywords for the type `number` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.number\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `number` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n number: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer.\n * The validation keywords for the type `numeric` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor13.\n *\n * @name Schema.typeGroupValidators.numeric\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `numeric` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n numeric: function (value, schema, opts) {\n return runOps(NUMERIC_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an object.\n * The validation keywords for the type `object` are:\n *```\n * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor53.\n *\n * @name Schema.typeGroupValidators.object\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing at least one `object` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n object: function (value, schema, opts) {\n return runOps(OBJECT_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an string.\n * The validation keywords for the type `string` are:\n *```\n * ['maxLength', 'minLength', 'pattern']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor25.\n *\n * @name Schema.typeGroupValidators.string\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing at least one `string` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n string: function (value, schema, opts) {\n return runOps(STRING_OPS, value, schema, opts)\n }\n}\n\n/**\n * js-data's Schema class.\n *\n * @example Schema#constructor\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const PostSchema = new Schema({\n * type: 'object',\n * properties: {\n * title: { type: 'string' }\n * }\n * })\n * PostSchema.validate({ title: 1234 })\n *\n * @class Schema\n * @extends Component\n * @param {Object} definition Schema definition according to json-schema.org\n */\nfunction Schema (definition) {\n definition || (definition = {})\n // TODO: schema validation\n utils.fillIn(this, definition)\n\n if (this.type === 'object' && this.properties) {\n utils.forOwn(this.properties, (_definition, prop) => {\n if (!(_definition instanceof Schema)) {\n this.properties[prop] = new Schema(_definition)\n }\n })\n }\n if (this.type === 'array' && this.items && !(this.items instanceof Schema)) {\n this.items = new Schema(this.items)\n }\n ['allOf', 'anyOf', 'oneOf'].forEach((validationKeyword) => {\n if (this[validationKeyword]) {\n this[validationKeyword].forEach((_definition, i) => {\n if (!(_definition instanceof Schema)) {\n this[validationKeyword][i] = new Schema(_definition)\n }\n })\n }\n })\n}\n\nexport default Component.extend({\n constructor: Schema,\n\n /**\n * This adds ES5 getters/setters to the target based on the \"properties\" in\n * this Schema, which makes possible change tracking and validation on\n * property assignment.\n *\n * @name Schema#validate\n * @method\n * @param {Object} target The prototype to which to apply this schema.\n */\n apply (target, opts) {\n opts || (opts = {})\n opts.getter || (opts.getter = '_get')\n opts.setter || (opts.setter = '_set')\n opts.unsetter || (opts.unsetter = '_unset')\n opts.track || (opts.track = this.track)\n const properties = this.properties || {}\n utils.forOwn(properties, function (schema, prop) {\n Object.defineProperty(\n target,\n prop,\n makeDescriptor(prop, schema, opts)\n )\n })\n },\n\n /**\n * Apply default values to the target object for missing values.\n *\n * @name Schema#applyDefaults\n * @method\n * @param {Object} target The target to which to apply values for missing values.\n */\n applyDefaults (target) {\n if (!target) {\n return\n }\n const properties = this.properties || {}\n const hasSet = utils.isFunction(target.set) || utils.isFunction(target._set)\n utils.forOwn(properties, function (schema, prop) {\n if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) {\n if (hasSet) {\n target.set(prop, utils.plainCopy(schema['default']), { silent: true })\n } else {\n utils.set(target, prop, utils.plainCopy(schema['default']))\n }\n }\n if (schema.type === 'object' && schema.properties) {\n if (hasSet) {\n const orig = target._get('noValidate')\n target._set('noValidate', true)\n utils.set(target, prop, utils.get(target, prop) || {}, { silent: true })\n target._set('noValidate', orig)\n } else {\n utils.set(target, prop, utils.get(target, prop) || {})\n }\n schema.applyDefaults(utils.get(target, prop))\n }\n })\n },\n\n /**\n * Validate the provided value against this schema.\n *\n * @name Schema#validate\n * @method\n * @param {*} value Value to validate.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n validate (value, opts) {\n return validate(value, this, opts)\n }\n}, {\n ANY_OPS,\n ARRAY_OPS,\n NUMERIC_OPS,\n OBJECT_OPS,\n STRING_OPS,\n typeGroupValidators,\n types,\n validate,\n validationKeywords\n})\n\n/**\n * Create a subclass of this Schema:\n * @example Schema.extend\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSchemaClass extends Schema {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSchema = new CustomSchemaClass()\n * console.log(customSchema.foo())\n * console.log(CustomSchemaClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSchemaClass = Schema.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSchema = new OtherSchemaClass()\n * console.log(otherSchema.foo())\n * console.log(OtherSchemaClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSchemaClass () {\n * Schema.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Schema.extend({\n * constructor: AnotherSchemaClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSchema = new AnotherSchemaClass()\n * console.log(anotherSchema.created_at)\n * console.log(anotherSchema.foo())\n * console.log(AnotherSchemaClass.beep())\n *\n * @method Schema.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Schema class.\n * @since 3.0.0\n */\n\n","import utils from './utils'\n\n// TODO: remove this when the rest of the project is cleaned\nexport const belongsToType = 'belongsTo'\nexport const hasManyType = 'hasMany'\nexport const hasOneType = 'hasOne'\n\nconst DOMAIN = 'Relation'\n\nexport function Relation (relatedMapper, options = {}) {\n utils.classCallCheck(this, Relation)\n\n options.type = this.constructor.TYPE_NAME\n this.validateOptions(relatedMapper, options)\n\n if (typeof relatedMapper === 'object') {\n Object.defineProperty(this, 'relatedMapper', { value: relatedMapper })\n }\n\n Object.defineProperty(this, 'inverse', { writable: true })\n utils.fillIn(this, options)\n}\n\nRelation.extend = utils.extend\n\nutils.addHiddenPropsToTarget(Relation.prototype, {\n get canAutoAddLinks () {\n return this.add === undefined || !!this.add\n },\n\n get relatedCollection () {\n return this.mapper.datastore.getCollection(this.relation)\n },\n\n validateOptions (related, opts) {\n const DOMAIN_ERR = `new ${DOMAIN}`\n\n const localField = opts.localField\n if (!localField) {\n throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField)\n }\n\n const foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey\n if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) {\n throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey)\n }\n\n if (utils.isString(related)) {\n opts.relation = related\n if (!utils.isFunction(opts.getRelation)) {\n throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation)\n }\n } else if (related) {\n opts.relation = related.name\n } else {\n throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related)\n }\n },\n\n assignTo (mapper) {\n this.name = mapper.name\n Object.defineProperty(this, 'mapper', { value: mapper })\n\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] })\n mapper.relationList.push(this)\n mapper.relationFields.push(this.localField)\n },\n\n canFindLinkFor () {\n return !!(this.foreignKey || this.localKey)\n },\n\n getRelation () {\n return this.relatedMapper\n },\n\n getForeignKey (record) {\n return utils.get(record, this.mapper.idAttribute)\n },\n\n setForeignKey (record, relatedRecord) {\n if (!record || !relatedRecord) {\n return\n }\n\n this._setForeignKey(record, relatedRecord)\n },\n\n _setForeignKey (record, relatedRecords) {\n const idAttribute = this.mapper.idAttribute\n\n if (!utils.isArray(relatedRecords)) {\n relatedRecords = [relatedRecords]\n }\n\n relatedRecords.forEach((relatedRecord) => {\n utils.set(relatedRecord, this.foreignKey, utils.get(record, idAttribute))\n })\n },\n\n getLocalField (record) {\n return utils.get(record, this.localField)\n },\n\n setLocalField (record, relatedData) {\n return utils.set(record, this.localField, relatedData)\n },\n\n getInverse (mapper) {\n if (!this.inverse) {\n this.findInverseRelation(mapper)\n }\n\n return this.inverse\n },\n\n findInverseRelation (mapper) {\n this.getRelation().relationList.forEach((def) => {\n if (def.getRelation() === mapper && this.isInversedTo(def)) {\n this.inverse = def\n return true\n }\n })\n },\n\n isInversedTo (def) {\n return !def.foreignKey || def.foreignKey === this.foreignKey\n },\n\n addLinkedRecords (records) {\n const datastore = this.mapper.datastore\n\n records.forEach((record) => {\n let relatedData = this.getLocalField(record)\n\n if (utils.isFunction(this.add)) {\n relatedData = this.add(datastore, this, record)\n } else if (relatedData) {\n relatedData = this.linkRecord(record, relatedData)\n }\n\n const isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length\n\n if (isEmptyLinks && this.canFindLinkFor(record)) {\n relatedData = this.findExistingLinksFor(record)\n }\n\n if (relatedData) {\n this.setLocalField(record, relatedData)\n }\n })\n },\n\n removeLinkedRecords (relatedMapper, records) {\n const localField = this.localField\n records.forEach((record) => {\n const relatedData = utils.get(record, localField)\n this.unlinkInverseRecords(relatedData)\n utils.set(record, localField, undefined)\n })\n },\n\n unlinkInverseRecords (record) {\n if (!record) {\n return\n }\n utils.set(record, this.getInverse(this.mapper).localField, undefined)\n },\n\n linkRecord (record, relatedRecord) {\n const relatedId = utils.get(relatedRecord, this.mapper.idAttribute)\n\n if (relatedId === undefined) {\n const unsaved = this.relatedCollection.unsaved()\n if (unsaved.indexOf(relatedRecord) === -1) {\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n } else {\n if (relatedRecord !== this.relatedCollection.get(relatedId)) {\n this.setForeignKey(record, relatedRecord)\n\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n }\n\n return relatedRecord\n },\n\n // e.g. user hasMany post via \"foreignKey\", so find all posts of user\n findExistingLinksByForeignKey (id) {\n return this.relatedCollection.filter({\n [this.foreignKey]: id\n })\n }\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const BelongsToRelation = Relation.extend({\n getForeignKey (record) {\n return utils.get(record, this.foreignKey)\n },\n\n _setForeignKey (record, relatedRecord) {\n utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute))\n },\n\n findExistingLinksFor (record) {\n // console.log('\\tBelongsTo#findExistingLinksFor', record)\n if (!record) {\n return\n }\n const relatedId = utils.get(record, this.foreignKey)\n if (relatedId !== undefined && relatedId !== null) {\n return this.relatedCollection.get(relatedId)\n }\n }\n}, {\n TYPE_NAME: 'belongsTo'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasManyRelation = Relation.extend({\n validateOptions (related, opts) {\n Relation.prototype.validateOptions.call(this, related, opts)\n\n const { localKeys, foreignKeys, foreignKey } = opts\n\n if (!foreignKey && !localKeys && !foreignKeys) {\n throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey)\n }\n },\n\n canFindLinkFor (record) {\n const hasForeignKeys = this.foreignKey || this.foreignKeys\n return !!(hasForeignKeys || (this.localKeys && utils.get(record, this.localKeys)))\n },\n\n unlinkInverseRecords (records) {\n if (!records) {\n return\n }\n const localField = this.getInverse(this.mapper).localField\n records.forEach(function (record) {\n utils.set(record, localField, undefined)\n })\n },\n\n linkRecord (record, relatedRecords) {\n const relatedCollection = this.relatedCollection\n const canAutoAddLinks = this.canAutoAddLinks\n const foreignKey = this.foreignKey\n const unsaved = this.relatedCollection.unsaved()\n\n return relatedRecords.map((relatedRecord) => {\n const relatedId = relatedCollection.recordId(relatedRecord)\n\n if ((relatedId === undefined && unsaved.indexOf(relatedRecord) === -1) || relatedRecord !== relatedCollection.get(relatedId)) {\n if (foreignKey) {\n // TODO: slow, could be optimized? But user loses hook\n this.setForeignKey(record, relatedRecord)\n }\n if (canAutoAddLinks) {\n relatedRecord = relatedCollection.add(relatedRecord)\n }\n }\n\n return relatedRecord\n })\n },\n\n findExistingLinksFor (record) {\n const id = utils.get(record, this.mapper.idAttribute)\n const ids = this.localKeys ? utils.get(record, this.localKeys) : null\n let records\n\n if (id !== undefined && this.foreignKey) {\n records = this.findExistingLinksByForeignKey(id)\n } else if (this.localKeys && ids) {\n records = this.findExistingLinksByLocalKeys(ids)\n } else if (id !== undefined && this.foreignKeys) {\n records = this.findExistingLinksByForeignKeys(id)\n }\n\n if (records && records.length) {\n return records\n }\n },\n\n // e.g. user hasMany group via \"foreignKeys\", so find all users of a group\n findExistingLinksByLocalKeys (ids) {\n return this.relatedCollection.filter({\n where: {\n [this.mapper.idAttribute]: {\n 'in': ids\n }\n }\n })\n },\n\n // e.g. group hasMany user via \"localKeys\", so find all groups that own a user\n findExistingLinksByForeignKeys (id) {\n return this.relatedCollection.filter({\n where: {\n [this.foreignKeys]: {\n 'contains': id\n }\n }\n })\n }\n}, {\n TYPE_NAME: 'hasMany'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasOneRelation = Relation.extend({\n findExistingLinksFor (relatedMapper, record) {\n const recordId = utils.get(record, relatedMapper.idAttribute)\n const records = this.findExistingLinksByForeignKey(recordId)\n\n if (records.length) {\n return records[0]\n }\n }\n}, {\n TYPE_NAME: 'hasOne'\n})\n","import { Relation } from './Relation'\nimport { BelongsToRelation } from './Relation/BelongsTo'\nimport { HasManyRelation } from './Relation/HasMany'\nimport { HasOneRelation } from './Relation/HasOne'\n\n[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) {\n Relation[RelationType.TYPE_NAME] = function (related, options) {\n return new RelationType(related, options)\n }\n})\n\nexport { belongsToType, hasManyType, hasOneType, Relation } from './Relation'\n","import { Relation } from './relations'\n\nexport { belongsToType, hasManyType, hasOneType } from './relations'\n/**\n * BelongsTo relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.belongsTo\n * @method\n * @param {Mapper} related The relation the target belongs to.\n * @param {Object} opts Configuration options.\n * @param {string} opts.foreignKey The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const belongsTo = function (related, opts) {\n return function (mapper) {\n Relation.belongsTo(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasMany relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasMany\n * @method\n * @param {Mapper} related The relation of which the target has many.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasMany = function (related, opts) {\n return function (mapper) {\n Relation.hasMany(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasOne relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasOne\n * @method\n * @param {Mapper} related The relation of which the target has one.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasOne = function (related, opts) {\n return function (mapper) {\n Relation.hasOne(related, opts).assignTo(mapper)\n }\n}\n","import utils from './utils'\nimport Component from './Component'\nimport Record from './Record'\nimport Schema from './Schema'\nimport { Relation } from './relations'\nimport {\n belongsTo,\n belongsToType,\n hasMany,\n hasManyType,\n hasOne,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Mapper'\nconst applyDefaultsHooks = [\n 'beforeCreate',\n 'beforeCreateMany'\n]\nconst validatingHooks = [\n 'beforeCreate',\n 'beforeCreateMany',\n 'beforeUpdate',\n 'beforeUpdateAll',\n 'beforeUpdateMany'\n]\nconst makeNotify = function (num) {\n return function (...args) {\n const opts = args[args.length - num]\n const op = opts.op\n this.dbg(op, ...args)\n\n if (applyDefaultsHooks.indexOf(op) !== -1 && opts.applyDefaults !== false) {\n const schema = this.getSchema()\n if (schema && schema.applyDefaults) {\n let toProcess = args[0]\n if (!utils.isArray(toProcess)) {\n toProcess = [toProcess]\n }\n toProcess.forEach((record) => {\n schema.applyDefaults(record)\n })\n }\n }\n\n // Automatic validation\n if (validatingHooks.indexOf(op) !== -1 && !opts.noValidate) {\n // Save current value of option\n const originalExistingOnly = opts.existingOnly\n\n // For updates, ignore required fields if they aren't present\n if (op.indexOf('beforeUpdate') === 0 && opts.existingOnly === undefined) {\n opts.existingOnly = true\n }\n const errors = this.validate(args[op === 'beforeUpdate' ? 1 : 0], utils.pick(opts, ['existingOnly']))\n\n // Restore option\n opts.existingOnly = originalExistingOnly\n\n // Abort lifecycle due to validation errors\n if (errors) {\n return utils.reject(errors)\n }\n }\n\n // Emit lifecycle event\n if (opts.notify || (opts.notify === undefined && this.notify)) {\n setTimeout(() => {\n this.emit(op, ...args)\n })\n }\n }\n}\n\n// These are the default implementations of all of the lifecycle hooks\nconst notify = makeNotify(1)\nconst notify2 = makeNotify(2)\n\n// This object provides meta information used by Mapper#crud to actually\n// execute each lifecycle method\nconst LIFECYCLE_METHODS = {\n count: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroy: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroyAll: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n find: {\n defaults: [undefined, {}],\n types: []\n },\n findAll: {\n defaults: [{}, {}],\n types: []\n },\n sum: {\n defaults: [undefined, {}, {}],\n skip: true,\n types: []\n },\n update: {\n adapterArgs (mapper, id, props, opts) {\n return [id, mapper.toJSON(props, opts), opts]\n },\n beforeAssign: 1,\n defaults: [undefined, {}, {}],\n types: []\n },\n updateAll: {\n adapterArgs (mapper, props, query, opts) {\n return [mapper.toJSON(props, opts), query, opts]\n },\n beforeAssign: 0,\n defaults: [{}, {}, {}],\n types: []\n },\n updateMany: {\n adapterArgs (mapper, records, opts) {\n return [records.map(function (record) {\n return mapper.toJSON(record, opts)\n }), opts]\n },\n beforeAssign: 0,\n defaults: [[], {}],\n types: []\n }\n}\n\nconst MAPPER_DEFAULTS = {\n /**\n * Hash of registered adapters. Don't modify directly. Use\n * {@link Mapper#registerAdapter} instead.\n *\n * @default {}\n * @name Mapper#_adapters\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n _adapters: {},\n\n /**\n * Whether {@link Mapper#beforeCreate} and {@link Mapper#beforeCreateMany}\n * should automatically receive default values according to the Mapper's schema.\n *\n * @default true\n * @name Mapper#applyDefaults\n * @since 3.0.0\n * @type {boolean}\n */\n applyDefaults: true,\n\n /**\n * Whether to augment {@link Mapper#recordClass} with ES5 getters and setters\n * according to the properties defined in {@link Mapper#schema}. This makes\n * possible validation and change tracking on individual properties\n * when using the dot (e.g. `user.name = \"Bob\"`) operator to modify a\n * property, and is `true` by default.\n *\n * @default true\n * @name Mapper#applySchema\n * @since 3.0.0\n * @type {boolean}\n */\n applySchema: true,\n\n /**\n * The name of the registered adapter that this Mapper should used by default.\n *\n * @default \"http\"\n * @name Mapper#defaultAdapter\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n * @type {string}\n */\n defaultAdapter: 'http',\n\n /**\n * The field used as the unique identifier on records handled by this Mapper.\n *\n * @default id\n * @name Mapper#idAttribute\n * @since 3.0.0\n * @type {string}\n */\n idAttribute: 'id',\n\n /**\n * Whether this Mapper should emit operational events.\n *\n * @default true\n * @name Mapper#notify\n * @since 3.0.0\n * @type {boolean}\n */\n notify: true,\n\n /**\n * Whether to skip validation when the Record instances are created.\n *\n * @default false\n * @name Mapper#noValidate\n * @since 3.0.0\n * @type {boolean}\n */\n noValidate: false,\n\n /**\n * Whether {@link Mapper#create}, {@link Mapper#createMany},\n * {@link Mapper#update}, {@link Mapper#updateAll}, {@link Mapper#updateMany},\n * {@link Mapper#find}, {@link Mapper#findAll}, {@link Mapper#destroy},\n * {@link Mapper#destroyAll}, {@link Mapper#count}, and {@link Mapper#sum}\n * should return a raw result object that contains both the instance data\n * returned by the adapter _and_ metadata about the operation.\n *\n * The default is to NOT return the result object, and instead return just the\n * instance data.\n *\n * @default false\n * @name Mapper#raw\n * @since 3.0.0\n * @type {boolean}\n */\n raw: false\n}\n\n/**\n * The core of JSData's [ORM/ODM][orm] implementation. Given a minimum amout of\n * meta information about a resource, a Mapper can perform generic CRUD\n * operations against that resource. Apart from its configuration, a Mapper is\n * stateless. The particulars of various persistence layers have been abstracted\n * into adapters, which a Mapper uses to perform its operations.\n *\n * The term \"Mapper\" comes from the [Data Mapper Pattern][pattern] described in\n * Martin Fowler's [Patterns of Enterprise Application Architecture][book]. A\n * Data Mapper moves data between [in-memory object instances][record] and a\n * relational or document-based database. JSData's Mapper can work with any\n * persistence layer you can write an adapter for.\n *\n * _(\"Model\" is a heavily overloaded term and is avoided in this documentation\n * to prevent confusion.)_\n *\n * [orm]: https://en.wikipedia.org/wiki/Object-relational_mapping\n * [pattern]: https://en.wikipedia.org/wiki/Data_mapper_pattern\n * [book]: http://martinfowler.com/books/eaa.html\n * [record]: Record.html\n *\n * @example\n * // Import and instantiate\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @example\n * // Define a Mapper using the Container component\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @class Mapper\n * @extends Component\n * @param {Object} opts Configuration options.\n * @param {boolean} [opts.applySchema=true] See {@link Mapper#applySchema}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {string} [opts.defaultAdapter=http] See {@link Mapper#defaultAdapter}.\n * @param {string} [opts.idAttribute=id] See {@link Mapper#idAttribute}.\n * @param {Object} [opts.methods] See {@link Mapper#methods}.\n * @param {string} opts.name See {@link Mapper#name}.\n * @param {boolean} [opts.notify] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw=false] See {@link Mapper#raw}.\n * @param {Function|boolean} [opts.recordClass] See {@link Mapper#recordClass}.\n * @param {Object|Schema} [opts.schema] See {@link Mapper#schema}.\n * @returns {Mapper} A new {@link Mapper} instance.\n * @see http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n */\nfunction Mapper (opts) {\n utils.classCallCheck(this, Mapper)\n Component.call(this)\n opts || (opts = {})\n\n // Prepare certain properties to be non-enumerable\n Object.defineProperties(this, {\n _adapters: {\n value: undefined,\n writable: true\n },\n\n /**\n * The {@link Container} that holds this Mapper. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n datastore: {\n value: undefined,\n writable: true\n },\n\n /**\n * The meta information describing this Mapper's available lifecycle\n * methods. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n lifecycleMethods: {\n value: LIFECYCLE_METHODS\n },\n\n /**\n * Set to `false` to force the Mapper to work with POJO objects only.\n *\n * @example\n * // Use POJOs only.\n * import {Mapper, Record} from 'js-data'\n * const UserMapper = new Mapper({ recordClass: false })\n * UserMapper.recordClass // false\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n *\n * @example\n * // Set to a custom class to have records wrapped in your custom class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User {\n * constructor (props = {}) {\n * for (var key in props) {\n * if (props.hasOwnProperty(key)) {\n * this[key] = props[key]\n * }\n * }\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n * user instanceof User // true\n *\n *\n * @example\n * // Extend the {@link Record} class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User extends Record {\n * constructor () {\n * super(props)\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // true\n * user instanceof User // true\n *\n * @name Mapper#recordClass\n * @default {@link Record}\n * @see Record\n * @since 3.0.0\n */\n recordClass: {\n value: undefined,\n writable: true\n },\n\n /**\n * This Mapper's {@link Schema}.\n *\n * @example Mapper#schema\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const UserMapper = new Mapper({\n * name: 'user',\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * first: { type: 'string', track: true },\n * last: { type: 'string', track: true },\n * role: { type: 'string', track: true, required: true },\n * age: { type: 'integer', track: true },\n * is_active: { type: 'number' }\n * }\n * }\n * })\n * const user = UserMapper.createRecord({\n * id: 1,\n * name: 'John',\n * role: 'admin'\n * })\n * user.on('change', function (user, changes) {\n * console.log(changes)\n * })\n * user.on('change:role', function (user, value) {\n * console.log('change:role - ' + value)\n * })\n * user.role = 'owner'\n *\n * @name Mapper#schema\n * @see Schema\n * @since 3.0.0\n * @type {Schema}\n */\n schema: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(MAPPER_DEFAULTS))\n\n /**\n * The name for this Mapper. This is the minimum amount of meta information\n * required for a Mapper to be able to execute CRUD operations for a\n * Resource.\n *\n * @name Mapper#name\n * @since 3.0.0\n * @type {string}\n */\n if (!this.name) {\n throw utils.err(`new ${DOMAIN}`, 'opts.name')(400, 'string', this.name)\n }\n\n // Setup schema, with an empty default schema if necessary\n if (this.schema) {\n this.schema.type || (this.schema.type = 'object')\n }\n if (!(this.schema instanceof Schema)) {\n this.schema = new Schema(this.schema || { type: 'object' })\n }\n\n // Create a subclass of Record that's tied to this Mapper\n if (this.recordClass === undefined) {\n const superClass = Record\n this.recordClass = superClass.extend({\n constructor: (function Record () {\n var subClass = function Record (props, opts) {\n utils.classCallCheck(this, subClass)\n superClass.call(this, props, opts)\n }\n return subClass\n })()\n })\n }\n\n if (this.recordClass) {\n this.recordClass.mapper = this\n\n /**\n * Functions that should be added to the prototype of {@link Mapper#recordClass}.\n *\n * @name Mapper#methods\n * @since 3.0.0\n * @type {Object}\n */\n if (utils.isObject(this.methods)) {\n utils.addHiddenPropsToTarget(this.recordClass.prototype, this.methods)\n }\n\n // We can only apply the schema to the prototype of this.recordClass if the\n // class extends Record\n if (Record.prototype.isPrototypeOf(Object.create(this.recordClass.prototype)) && this.schema && this.schema.apply && this.applySchema) {\n this.schema.apply(this.recordClass.prototype)\n }\n }\n}\n\nexport default Component.extend({\n constructor: Mapper,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCount: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroy: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroyAll\n * @param {*} data The `data` returned by the adapter.\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroyAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFind: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFindAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterSum\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterSum: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @since 3.0.0\n */\n beforeCreate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @since 3.0.0\n */\n beforeCreateMany: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @since 3.0.0\n */\n beforeCount: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @since 3.0.0\n */\n beforeDestroy: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroyAll\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @since 3.0.0\n */\n beforeDestroyAll: notify,\n\n /**\n * Mappers lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @since 3.0.0\n */\n beforeFind: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @since 3.0.0\n */\n beforeFindAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeSum\n * @param {string} field The `field` argument passed to {@link Mapper#sum}.\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @since 3.0.0\n */\n beforeSum: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @since 3.0.0\n */\n beforeUpdate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @since 3.0.0\n */\n beforeUpdateAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @since 3.0.0\n */\n beforeUpdateMany: notify,\n\n /**\n * This method is called at the end of most lifecycle methods. It does the\n * following:\n *\n * 1. If `opts.raw` is `true`, add this Mapper's configuration to the `opts`\n * argument as metadata for the operation.\n * 2. Wrap the result data appropriately using {@link Mapper#wrap}, which\n * calls {@link Mapper#createRecord}.\n *\n * @method Mapper#_end\n * @private\n * @since 3.0.0\n */\n _end (result, opts, skip) {\n if (opts.raw) {\n utils._(result, opts)\n }\n if (skip) {\n return result\n }\n let _data = opts.raw ? result.data : result\n if (_data && utils.isFunction(this.wrap)) {\n _data = this.wrap(_data, opts)\n if (opts.raw) {\n result.data = _data\n } else {\n result = _data\n }\n }\n return result\n },\n\n /**\n * Define a belongsTo relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * PostMapper.belongsTo(UserMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to post records at \"post.user\"\n * localField: 'user'\n * })\n *\n * CommentMapper.belongsTo(UserMapper, {\n * // comment.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to comment records at \"comment.user\"\n * localField: 'user'\n * })\n * CommentMapper.belongsTo(PostMapper, {\n * // comment.post_id points to post.id\n * foreignKey: 'post_id'\n * // post records will be attached to comment records at \"comment.post\"\n * localField: 'post'\n * })\n *\n * @method Mapper#belongsTo\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n belongsTo (relatedMapper, opts) {\n return belongsTo(relatedMapper, opts)(this)\n },\n\n /**\n * Select records according to the `query` argument and return the count.\n *\n * {@link Mapper#beforeCount} will be called before calling the adapter.\n * {@link Mapper#afterCount} will be called after calling the adapter.\n *\n * @example\n * // Get the number of published blog posts\n * PostMapper.count({ status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Mapper#count\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `count` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the count of the selected records.\n * @since 3.0.0\n */\n count (query, opts) {\n return this.crud('count', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~beforeCreateListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreate\n * @see Mapper~beforeCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Mapper~beforeCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeCreate}.\n * @see Mapper#event:beforeCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~afterCreateListener} for how to listen for this event.\n *\n * @event Mapper#afterCreate\n * @see Mapper~afterCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Mapper~afterCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterCreate}.\n * @see Mapper#event:afterCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Create and save a new the record using the provided `props`.\n *\n * {@link Mapper#beforeCreate} will be called before calling the adapter.\n * {@link Mapper#afterCreate} will be called after calling the adapter.\n *\n * @example\n * // Create and save a new blog post\n * PostMapper.create({\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#create\n * @param {Object} props The properties for the new record.\n * @param {Object} [opts] Configuration options. Refer to the `create` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `props` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#create}\n * or {@link Mapper#createMany} call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created record.\n * @since 3.0.0\n */\n create (props, opts) {\n let op, adapter\n // Default values for arguments\n props || (props = {})\n opts || (opts = {})\n const originalRecord = props\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreate lifecycle hook\n op = opts.op = 'beforeCreate'\n return utils.resolve(this[op](props, opts)).then((_props) => {\n // Allow for re-assignment from lifecycle hook\n props = _props === undefined ? props : _props\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n const relatedMapper = def.getRelation()\n const relatedIdAttribute = relatedMapper.idAttribute\n optsCopy.raw = false\n if (!relationData) {\n return\n }\n if (def.type === belongsToType) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(relatedMapper.create(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n def.setForeignKey(props, data)\n }))\n } else if (def.type === hasManyType && def.localKeys) {\n // Create his hasMany relation first because it uses localKeys\n tasks.push(relatedMapper.createMany(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n utils.set(props, def.localKeys, data.map((record) => utils.get(record, relatedIdAttribute)))\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter for the main create\n op = opts.op = 'create'\n this.dbg(op, props, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, this.toJSON(props, { with: opts.pass || [] }), opts))\n }).then((result) => {\n const createdRecordData = opts.raw ? result.data : result\n\n // Deep post-create hasMany and hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n if (!relationData) {\n return\n }\n optsCopy.raw = false\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType && def.foreignKey) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === hasOneType) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().create(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === belongsToType && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n } else if (def.type === hasManyType && def.localKeys && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n if (opts.raw) {\n result.data = originalRecord\n } else {\n result = originalRecord\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreate lifecycle hook\n op = opts.op = 'afterCreate'\n return utils.resolve(this[op](props, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Use {@link Mapper#createRecord} instead.\n * @deprecated\n * @method Mapper#createInstance\n * @param {Object|Array} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Object|Array} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n createInstance (props, opts) {\n return this.createRecord(props, opts)\n },\n\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreateMany\n * @see Mapper~beforeCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Mapper~beforeCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Mapper#event:beforeCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~afterCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterCreateMany\n * @see Mapper~afterCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Mapper~afterCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Mapper#event:afterCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Given an array of records, batch create them via an adapter.\n *\n * {@link Mapper#beforeCreateMany} will be called before calling the adapter.\n * {@link Mapper#afterCreateMany} will be called after calling the adapter.\n *\n * @example\n * // Create and save several new blog posts\n * PostMapper.createMany([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#createMany\n * @param {Record[]} records Array of records to be created in one batch.\n * @param {Object} [opts] Configuration options. Refer to the `createMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `records` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#createMany}\n * call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created records.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n createMany (records, opts) {\n let op, adapter\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n const originalRecords = records\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreateMany lifecycle hook\n op = opts.op = 'beforeCreateMany'\n return utils.resolve(this[op](records, opts)).then((_records) => {\n // Allow for re-assignment from lifecycle hook\n records = _records === undefined ? records : _records\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (def.type === belongsToType && relationData.length === records.length) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(def.getRelation().createMany(relationData, optsCopy).then((data) => {\n const relatedRecords = optsCopy.raw ? data.data : data\n def.setLocalField(belongsToRelationData, relatedRecords)\n records.forEach((record, i) => {\n def.setForeignKey(record, relatedRecords[i])\n })\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'createMany'\n const json = records.map((record) => this.toJSON(record, { with: opts.pass || [] }))\n this.dbg(op, records, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, json, opts))\n }).then((result) => {\n const createdRecordsData = opts.raw ? result.data : result\n\n // Deep post-create hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (relationData.length !== records.length) {\n return\n }\n const belongsToData = def.getLocalField(belongsToRelationData)\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType) {\n // Not supported\n this.log('warn', 'deep createMany of hasMany type not supported!')\n } else if (def.type === hasOneType) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setForeignKey(createdRecordData, relationData[i])\n })\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n const relatedData = opts.raw ? result.data : result\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, relatedData[i])\n })\n })\n } else if (def.type === belongsToType && belongsToData && belongsToData.length === createdRecordsData.length) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, belongsToData[i])\n })\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n createdRecordsData.forEach((createdRecordData, i) => {\n const originalRecord = originalRecords[i]\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n })\n if (opts.raw) {\n result.data = originalRecords\n } else {\n result = originalRecords\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreateMany lifecycle hook\n op = opts.op = 'afterCreateMany'\n return utils.resolve(this[op](records, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Create an unsaved, uncached instance of this Mapper's\n * {@link Mapper#recordClass}.\n *\n * Returns `props` if `props` is already an instance of\n * {@link Mapper#recordClass}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * const post = PostMapper.createRecord()\n *\n * @example\n * // Create an unsaved record instance with inital properties\n * const post = PostMapper.createRecord({\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create a record instance that corresponds to a saved record\n * const post = PostMapper.createRecord({\n * // JSData thinks this record has been saved if it has a primary key\n * id: 1234,\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create record instances from an array\n * const posts = PostMapper.createRecord([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }])\n *\n * @example\n * // Records are validated by default\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * try {\n * const post = PostMapper.createRecord({\n * title: 1234,\n * })\n * } catch (err) {\n * console.log(err.errors) // [{ expected: 'one of (string)', actual: 'number', path: 'title' }]\n * }\n *\n * @example\n * // Skip validation\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * const post = PostMapper.createRecord({\n * title: 1234,\n * }, { noValidate: true })\n * console.log(post.isValid()) // false\n *\n * @method Mapper#createRecord\n * @param {Object|Object[]} props The properties for the Record instance or an\n * array of property objects for the Record instances.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @returns {Record|Record[]} The Record instance or Record instances.\n * @since 3.0.0\n */\n createRecord (props, opts) {\n props || (props = {})\n if (utils.isArray(props)) {\n return props.map((_props) => this.createRecord(_props, opts))\n }\n if (!utils.isObject(props)) {\n throw utils.err(`${DOMAIN}#createRecord`, 'props')(400, 'array or object', props)\n }\n const RecordCtor = this.recordClass\n const relationList = this.relationList || []\n relationList.forEach(function (def) {\n const relatedMapper = def.getRelation()\n const relationData = def.getLocalField(props)\n if (relationData && !relatedMapper.is(relationData)) {\n if (utils.isArray(relationData) && (!relationData.length || relatedMapper.is(relationData[0]))) {\n return\n }\n utils.set(props, def.localField, relatedMapper.createRecord(relationData, opts))\n }\n })\n // Check to make sure \"props\" is not already an instance of this Mapper.\n if (RecordCtor && (!(props instanceof RecordCtor))) {\n return new RecordCtor(props, opts)\n }\n return props\n },\n\n /**\n * Lifecycle invocation method. You probably won't call this method directly.\n *\n * @method Mapper#crud\n * @param {string} method Name of the lifecycle method to invoke.\n * @param {...*} args Arguments to pass to the lifecycle method.\n * @returns {Promise}\n * @since 3.0.0\n */\n crud (method, ...args) {\n const config = this.lifecycleMethods[method]\n if (!config) {\n throw utils.err(`${DOMAIN}#crud`, method)(404, 'method')\n }\n\n const upper = `${method.charAt(0).toUpperCase()}${method.substr(1)}`\n const before = `before${upper}`\n const after = `after${upper}`\n\n let op, adapter\n\n // Default values for arguments\n config.defaults.forEach((value, i) => {\n if (args[i] === undefined) {\n args[i] = utils.copy(value)\n }\n })\n\n const opts = args[args.length - 1]\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // before lifecycle hook\n op = opts.op = before\n return utils.resolve(this[op](...args)).then((_value) => {\n if (args[config.beforeAssign] !== undefined) {\n // Allow for re-assignment from lifecycle hook\n args[config.beforeAssign] = _value === undefined ? args[config.beforeAssign] : _value\n }\n // Now delegate to the adapter\n op = opts.op = method\n args = config.adapterArgs ? config.adapterArgs(this, ...args) : args\n this.dbg(op, ...args)\n return utils.resolve(this.getAdapter(adapter)[op](this, ...args))\n }).then((result) => {\n result = this._end(result, opts, !!config.skip)\n args.push(result)\n // after lifecycle hook\n op = opts.op = after\n return utils.resolve(this[op](...args)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~beforeDestroyListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroy\n * @see Mapper~beforeDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Mapper~beforeDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroy}.\n * @see Mapper#event:beforeDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~afterDestroyListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroy\n * @see Mapper~afterDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Mapper~afterDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroy}.\n * @see Mapper#event:afterDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Using an adapter, destroy the record with the given primary key.\n *\n * {@link Mapper#beforeDestroy} will be called before destroying the record.\n * {@link Mapper#afterDestroy} will be called after destroying the record.\n *\n * @example\n * // Destroy a specific blog post\n * PostMapper.destroy(1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @example\n * // Get full response\n * PostMapper.destroy(1234, { raw: true }).then((result) => {\n * console.log(result.deleted) e.g. 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroy\n * @fires Mapper#afterDestroy\n * @method Mapper#destroy\n * @param {(string|number)} id The primary key of the record to destroy.\n * @param {Object} [opts] Configuration options. Refer to the `destroy` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the record has been destroyed. Resolves\n * even if no record was found to be destroyed.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroy (id, opts) {\n return this.crud('destroy', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroyAll\n * @see Mapper~beforeDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Mapper~beforeDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroyAll}.\n * @see Mapper#event:beforeDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroyAll\n * @see Mapper~afterDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Mapper~afterDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroyAll}.\n * @see Mapper#event:afterDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Destroy the records selected by `query` via an adapter. If no `query` is\n * provided then all records will be destroyed.\n *\n * {@link Mapper#beforeDestroyAll} will be called before destroying the records.\n * {@link Mapper#afterDestroyAll} will be called after destroying the records.\n *\n * @example\n * // Destroy all blog posts\n * PostMapper.destroyAll().then(() => {\n * // All blog posts have been destroyed\n * })\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * PostMapper.destroyAll({ status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @example\n * // Get full response\n * const query = null\n * const options = { raw: true }\n * PostMapper.destroyAll(query, options).then((result) => {\n * console.log(result.deleted) e.g. 14\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroyAll\n * @fires Mapper#afterDestroyAll\n * @method Mapper#destroyAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `destroyAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the records have been destroyed. Resolves\n * even if no records were found to be destroyed.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroyAll (query, opts) {\n return this.crud('destroyAll', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~beforeFindListener} for how to listen for this event.\n *\n * @event Mapper#beforeFind\n * @see Mapper~beforeFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Mapper~beforeFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFind}.\n * @see Mapper#event:beforeFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~afterFindListener} for how to listen for this event.\n *\n * @event Mapper#afterFind\n * @see Mapper~afterFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFind} event.\n *\n * @example\n * function onAfterFind (id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Mapper~afterFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFind}.\n * @see Mapper#event:afterFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Retrieve via an adapter the record with the given primary key.\n *\n * {@link Mapper#beforeFind} will be called before calling the adapter.\n * {@link Mapper#afterFind} will be called after calling the adapter.\n *\n * @example\n * PostMapper.find(1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @example\n * // Get full response\n * PostMapper.find(1, { raw: true }).then((result) => {\n * console.log(result.data) // { id: 1, ...}\n * console.log(result.found) // 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFind\n * @fires Mapper#afterFind\n * @method Mapper#find\n * @param {(string|number)} id The primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options. Refer to the `find` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found record. Resolves with\n * `undefined` if no record was found.\n * @see http://www.js-data.io/v3.0/docs/reading-data\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n find (id, opts) {\n return this.crud('find', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~beforeFindAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeFindAll\n * @see Mapper~beforeFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Mapper~beforeFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFindAll}.\n * @see Mapper#event:beforeFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~afterFindAllListener} for how to listen for this event.\n *\n * @event Mapper#afterFindAll\n * @see Mapper~afterFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Mapper~afterFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFindAll}.\n * @see Mapper#event:afterFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, select records to retrieve via an adapter.\n *\n * {@link Mapper#beforeFindAll} will be called before calling the adapter.\n * {@link Mapper#afterFindAll} will be called after calling the adapter.\n *\n * @example\n * // Find all \"published\" blog posts\n * PostMapper.findAll({ status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, status: 'published', ...}, ...]\n * })\n *\n * @example\n * // Get full response\n * PostMapper.findAll({ status: 'published' }, { raw: true }).then((result) => {\n * console.log(result.data) // [{ id: 1, status: 'published', ...}, ...]\n * console.log(result.found) // e.g. 13\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFindAll\n * @fires Mapper#afterFindAll\n * @method Mapper#findAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `findAll` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n findAll (query, opts) {\n return this.crud('findAll', query, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Mapper#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapter (name) {\n this.dbg('getAdapter', 'name:', name)\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Mapper#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || opts.defaultAdapter\n },\n\n /**\n * Get the object of registered adapters for this Mapper.\n *\n * @method Mapper#getAdapters\n * @returns {Object} {@link Mapper#_adapters}\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Returns this Mapper's {@link Schema}.\n *\n * @method Mapper#getSchema\n * @returns {Schema} This Mapper's {@link Schema}.\n * @see Mapper#schema\n * @since 3.0.0\n */\n getSchema () {\n return this.schema\n },\n\n /**\n * Defines a hasMany relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * UserMapper.hasMany(PostMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // post records will be attached to user records at \"user.posts\"\n * localField: 'posts'\n * })\n *\n * @method Mapper#hasMany\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasMany (relatedMapper, opts) {\n return hasMany(relatedMapper, opts)(this)\n },\n\n /**\n * Defines a hasOne relationship. Only useful if you're managing your Mappers\n * manually and not using a {@link Container} or {@link DataStore} component.\n *\n * @example\n * UserMapper.hasOne(ProfileMapper, {\n * // profile.user_id points to user.id\n * foreignKey: 'user_id'\n * // profile records will be attached to user records at \"user.profile\"\n * localField: 'profile'\n * })\n *\n * @method Mapper#hasOne\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasOne (relatedMapper, opts) {\n return hasOne(relatedMapper, opts)(this)\n },\n\n /**\n * Return whether `record` is an instance of this Mapper's recordClass.\n *\n * @example\n * const post = PostMapper.createRecord()\n *\n * console.log(PostMapper.is(post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof PostMapper.recordClass) // true\n *\n * @method Mapper#is\n * @param {Object|Record} record The record to check.\n * @returns {boolean} Whether `record` is an instance of this Mapper's\n * {@link Mapper#recordClass}.\n * @since 3.0.0\n */\n is (record) {\n const recordClass = this.recordClass\n return recordClass ? record instanceof recordClass : false\n },\n\n /**\n * Register an adapter on this Mapper under the given name.\n *\n * @method Mapper#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for this Mapper.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.defaultAdapter = name\n }\n },\n\n /**\n * Select records according to the `query` argument, and aggregate the sum\n * value of the property specified by `field`.\n *\n * {@link Mapper#beforeSum} will be called before calling the adapter.\n * {@link Mapper#afterSum} will be called after calling the adapter.\n *\n * @example\n * PurchaseOrderMapper.sum('amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Mapper#sum\n * @param {string} field The field to sum.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `sum` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the aggregated sum.\n * @since 3.0.0\n */\n sum (field, query, opts) {\n return this.crud('sum', field, query, opts)\n },\n\n /**\n * Return a plain object representation of the given record. Relations can\n * be optionally be included. Non-schema properties can be excluded.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })\n * console.log(PersonMapper.toJSON(person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(PersonMapper.toJSON(person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Mapper#toJSON\n * @param {Record|Record[]} records Record or records from which to create a\n * POJO representation.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the POJO representation.\n * @param {boolean} [opts.withAll] Whether to simply include all relations in\n * the representation. Overrides `opts.with`.\n * @returns {Object|Object[]} POJO representation of the record or records.\n * @since 3.0.0\n */\n toJSON (records, opts) {\n let record\n opts || (opts = {})\n if (utils.isArray(records)) {\n return records.map((record) => this.toJSON(record, opts))\n } else {\n record = records\n }\n const relationFields = (this ? this.relationFields : []) || []\n let json = {}\n let properties\n if (this && this.schema) {\n properties = this.schema.properties || {}\n // TODO: Make this work recursively\n utils.forOwn(properties, (opts, prop) => {\n json[prop] = utils.plainCopy(record[prop])\n })\n }\n properties || (properties = {})\n if (!opts.strict) {\n for (var key in record) {\n if (!properties[key] && relationFields.indexOf(key) === -1) {\n json[key] = utils.plainCopy(record[key])\n }\n }\n }\n // The user wants to include relations in the resulting plain object\n // representation\n if (this && opts.withAll) {\n opts.with = relationFields.slice()\n }\n if (this && opts.with) {\n if (utils.isString(opts.with)) {\n opts.with = [opts.with]\n }\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(record)\n if (relationData) {\n // The actual recursion\n if (utils.isArray(relationData)) {\n def.setLocalField(json, relationData.map((item) => {\n return def.getRelation().toJSON(item, optsCopy)\n }))\n } else {\n def.setLocalField(json, def.getRelation().toJSON(relationData, optsCopy))\n }\n }\n })\n }\n return json\n },\n\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~beforeUpdateListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdate\n * @see Mapper~beforeUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Mapper~beforeUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeUpdate}.\n * @see Mapper#event:beforeUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~afterUpdateListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdate\n * @see Mapper~afterUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Mapper~afterUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterUpdate}.\n * @see Mapper#event:afterUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Using an adapter, update the record with the primary key specified by the\n * `id` argument.\n *\n * {@link Mapper#beforeUpdate} will be called before updating the record.\n * {@link Mapper#afterUpdate} will be called after updating the record.\n *\n * @example\n * // Update a specific post\n * PostMapper.update(1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Mapper#beforeUpdate\n * @fires Mapper#afterUpdate\n * @method Mapper#update\n * @param {(string|number)} id The primary key of the record to update.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options. Refer to the `update` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * transaction.\n * @returns {Promise} Resolves with the updated record. Rejects if the record\n * could not be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n update (id, props, opts) {\n return this.crud('update', id, props, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateAll\n * @see Mapper~beforeUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Mapper~beforeUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Mapper#event:beforeUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateAll\n * @see Mapper~afterUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Mapper~afterUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Mapper#event:afterUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, perform the a single updated to the selected\n * records.\n *\n * {@link Mapper#beforeUpdateAll} will be called before making the update.\n * {@link Mapper#afterUpdateAll} will be called after making the update.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * PostMapper.updateAll(update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateAll\n * @fires Mapper#afterUpdateAll\n * @method Mapper#updateAll\n * @param {Object} props Update to apply to selected records.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `updateAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the update records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateAll (props, query, opts) {\n return this.crud('updateAll', props, query, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateMany\n * @see Mapper~beforeUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Mapper~beforeUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Mapper#event:beforeUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateMany\n * @see Mapper~afterUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Mapper~afterUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Mapper#event:afterUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Given an array of updates, perform each of the updates via an adapter. Each\n * \"update\" is a hash of properties with which to update an record. Each\n * update must contain the primary key of the record to be updated.\n *\n * {@link Mapper#beforeUpdateMany} will be called before making the update.\n * {@link Mapper#afterUpdateMany} will be called after making the update.\n *\n * @example\n * PostMapper.updateMany([\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateMany\n * @fires Mapper#afterUpdateMany\n * @method Mapper#updateMany\n * @param {Record[]} records Array up record updates.\n * @param {Object} [opts] Configuration options. Refer to the `updateMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the updated records. Rejects if any of the\n * records could be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateMany (records, opts) {\n return this.crud('updateMany', records, opts)\n },\n\n /**\n * Validate the given record or records according to this Mapper's\n * {@link Schema}. If there are no validation errors then the return value\n * will be `undefined`.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonSchema = new Schema({\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * })\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: PersonSchema\n * })\n * let errors = PersonMapper.validate({ name: 'John' })\n * console.log(errors) // undefined\n * errors = PersonMapper.validate({ name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Mapper#validate\n * @param {Object|Object[]} record The record or records to validate.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Schema#validate}.\n * @returns {Object[]} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (record, opts) {\n opts || (opts = {})\n const schema = this.getSchema()\n const _opts = utils.pick(opts, ['existingOnly'])\n if (utils.isArray(record)) {\n const errors = record.map((_record) => schema.validate(_record, utils.pick(_opts, ['existingOnly'])))\n let hasErrors = false\n errors.forEach(function (err) {\n if (err) {\n hasErrors = true\n }\n })\n if (hasErrors) {\n return errors\n }\n return undefined\n }\n return schema.validate(record, _opts)\n },\n\n /**\n * Method used to wrap data returned by an adapter with this Mapper's\n * {@link Mapper#recordClass}. This method is used by all of a Mapper's CRUD\n * methods. The provided implementation of this method assumes that the `data`\n * passed to it is a record or records that need to be wrapped with\n * {@link Mapper#createRecord}. Override with care.\n *\n * Provided implementation of {@link Mapper#wrap}:\n *\n * ```\n * function (data, opts) {\n * return this.createRecord(data, opts)\n * }\n * ```\n *\n * @example\n * const PostMapper = new Mapper({\n * name: 'post',\n * // Override to customize behavior\n * wrap (data, opts) {\n * const originalWrap = this.constructor.prototype.wrap\n * // Let's say \"GET /post\" doesn't return JSON quite like JSData expects,\n * // but the actual post records are nested under a \"posts\" field. So,\n * // we override Mapper#wrap to handle this special case.\n * if (opts.op === 'findAll') {\n * return originalWrap.call(this, data.posts, opts)\n * }\n * // Otherwise perform original behavior\n * return originalWrap.call(this, data, opts)\n * }\n * })\n *\n * @method Mapper#wrap\n * @param {Object|Object[]} data The record or records to be wrapped.\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#createRecord}.\n * @returns {Record|Record[]} The wrapped record or records.\n * @since 3.0.0\n */\n wrap (data, opts) {\n return this.createRecord(data, opts)\n },\n\n /**\n * @ignore\n */\n defineRelations () {\n // Setup the mapper's relations, including generating Mapper#relationList\n // and Mapper#relationFields\n utils.forOwn(this.relations, (group, type) => {\n utils.forOwn(group, (relations, _name) => {\n if (utils.isObject(relations)) {\n relations = [relations]\n }\n relations.forEach((def) => {\n const relatedMapper = this.datastore.getMapperByName(_name) || _name\n def.getRelation = () => this.datastore.getMapper(_name)\n\n if (typeof Relation[type] !== 'function') {\n throw utils.err(DOMAIN, 'defineRelations')(400, 'relation type (hasOne, hasMany, etc)', type, true)\n }\n\n this[type](relatedMapper, def)\n })\n })\n })\n }\n})\n\n/**\n * Create a subclass of this Mapper:\n *\n * @example Mapper.extend\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomMapperClass extends Mapper {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customMapper = new CustomMapperClass()\n * console.log(customMapper.foo())\n * console.log(CustomMapperClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherMapperClass = Mapper.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherMapper = new OtherMapperClass()\n * console.log(otherMapper.foo())\n * console.log(OtherMapperClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherMapperClass () {\n * Mapper.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Mapper.extend({\n * constructor: AnotherMapperClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherMapper = new AnotherMapperClass()\n * console.log(anotherMapper.created_at)\n * console.log(anotherMapper.foo())\n * console.log(AnotherMapperClass.beep())\n *\n * @method Mapper.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Mapper class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Mapper from './Mapper'\n\nconst DOMAIN = 'Container'\n\nexport const proxiedMapperMethods = [\n /**\n * Wrapper for {@link Mapper#count}.\n *\n * @example\n * // Get the number of published blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.count('post', { status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Container#count\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#count}.\n * @param {Object} [opts] See {@link Mapper#count}.\n * @returns {Promise} See {@link Mapper#count}.\n * @see Mapper#count\n * @since 3.0.0\n */\n 'count',\n\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~beforeCreateListener} for how to listen for this event.\n *\n * @event Container#beforeCreate\n * @see Container~beforeCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Container~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see Container#event:beforeCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~afterCreateListener} for how to listen for this event.\n *\n * @event Container#afterCreate\n * @see Container~afterCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Container~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see Container#event:afterCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}.\n *\n * @example\n * // Create and save a new blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.create('post', {\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreate\n * @fires Container#afterCreate\n * @method Container#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props See {@link Mapper#create}.\n * @param {Object} [opts] See {@link Mapper#create}.\n * @returns {Promise} See {@link Mapper#create}.\n * @see Mapper#create\n * @since 3.0.0\n */\n 'create',\n\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Container#beforeCreateMany\n * @see Container~beforeCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Container~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Container#event:beforeCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~afterCreateManyListener} for how to listen for this event.\n *\n * @event Container#afterCreateMany\n * @see Container~afterCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Container~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Container#event:afterCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}.\n *\n * @example\n * // Create and save several new blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.createMany('post', [{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreateMany\n * @fires Container#afterCreateMany\n * @method Container#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record[]} records See {@link Mapper#createMany}.\n * @param {Object} [opts] See {@link Mapper#createMany}.\n * @returns {Promise} See {@link Mapper#createMany}.\n * @see Mapper#createMany\n * @since 3.0.0\n */\n 'createMany',\n\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = PostMapper.createRecord()\n *\n * @method Container#createRecord\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Object[]} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Promise} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n 'createRecord',\n\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~beforeDestroyListener} for how to listen for this event.\n *\n * @event Container#beforeDestroy\n * @see Container~beforeDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Container~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see Container#event:beforeDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~afterDestroyListener} for how to listen for this event.\n *\n * @event Container#afterDestroy\n * @see Container~afterDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Container~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see Container#event:afterDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}.\n *\n * @example\n * // Destroy a specific blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroy('post', 1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @fires Container#beforeDestroy\n * @fires Container#afterDestroy\n * @method Container#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#destroy}.\n * @param {Object} [opts] See {@link Mapper#destroy}.\n * @returns {Promise} See {@link Mapper#destroy}.\n * @see Mapper#destroy\n * @since 3.0.0\n */\n 'destroy',\n\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Container#beforeDestroyAll\n * @see Container~beforeDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Container~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see Container#event:beforeDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Container#afterDestroyAll\n * @see Container~afterDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Container~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see Container#event:afterDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}.\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroyAll('post', { status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @fires Container#beforeDestroyAll\n * @fires Container#afterDestroyAll\n * @method Container#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#destroyAll}.\n * @param {Object} [opts] See {@link Mapper#destroyAll}.\n * @returns {Promise} See {@link Mapper#destroyAll}.\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n 'destroyAll',\n\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~beforeFindListener} for how to listen for this event.\n *\n * @event Container#beforeFind\n * @see Container~beforeFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Container~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see Container#event:beforeFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~afterFindListener} for how to listen for this event.\n *\n * @event Container#afterFind\n * @see Container~afterFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Container~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see Container#event:afterFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.find('post', 1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @fires Container#beforeFind\n * @fires Container#afterFind\n * @method Container#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#find}.\n * @param {Object} [opts] See {@link Mapper#find}.\n * @returns {Promise} See {@link Mapper#find}.\n * @see Mapper#find\n * @since 3.0.0\n */\n 'find',\n\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~beforeFindAllListener} for how to listen for this event.\n *\n * @event Container#beforeFindAll\n * @see Container~beforeFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Container~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see Container#event:beforeFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~afterFindAllListener} for how to listen for this event.\n *\n * @event Container#afterFindAll\n * @see Container~afterFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Container~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see Container#event:afterFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * @example\n * // Find all \"published\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.findAll('post', { status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, ...}, ...]\n * })\n *\n * @fires Container#beforeFindAll\n * @fires Container#afterFindAll\n * @method Container#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#findAll}.\n * @param {Object} [opts] See {@link Mapper#findAll}.\n * @returns {Promise} See {@link Mapper#findAll}.\n * @see Mapper#findAll\n * @since 3.0.0\n */\n 'findAll',\n\n /**\n * Wrapper for {@link Mapper#getSchema}.\n *\n * @method Container#getSchema\n * @param {string} name Name of the {@link Mapper} to target.\n * @returns {Schema} See {@link Mapper#getSchema}.\n * @see Mapper#getSchema\n * @since 3.0.0\n */\n 'getSchema',\n\n /**\n * Wrapper for {@link Mapper#is}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = store.createRecord()\n *\n * console.log(store.is('post', post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof store.getMapper('post').recordClass) // true\n *\n * @method Container#is\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Record} record See {@link Mapper#is}.\n * @returns {boolean} See {@link Mapper#is}.\n * @see Mapper#is\n * @since 3.0.0\n */\n 'is',\n\n /**\n * Wrapper for {@link Mapper#sum}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('purchase_order')\n *\n * store.sum('purchase_order', 'amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Container#sum\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {string} field See {@link Mapper#sum}.\n * @param {Object} [query] See {@link Mapper#sum}.\n * @param {Object} [opts] See {@link Mapper#sum}.\n * @returns {Promise} See {@link Mapper#sum}.\n * @see Mapper#sum\n * @since 3.0.0\n */\n 'sum',\n\n /**\n * Wrapper for {@link Mapper#toJSON}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('person', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' })\n * console.log(store.toJSON('person', person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(store.toJSON('person', person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Container#toJSON\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record|Record[]} records See {@link Mapper#toJSON}.\n * @param {Object} [opts] See {@link Mapper#toJSON}.\n * @returns {Object|Object[]} See {@link Mapper#toJSON}.\n * @see Mapper#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~beforeUpdateListener} for how to listen for this event.\n *\n * @event Container#beforeUpdate\n * @see Container~beforeUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Container~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see Container#event:beforeUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~afterUpdateListener} for how to listen for this event.\n *\n * @event Container#afterUpdate\n * @see Container~afterUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Container~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see Container#event:afterUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.update('post', 1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Container#beforeUpdate\n * @fires Container#afterUpdate\n * @method Container#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#update}.\n * @param {Object} record See {@link Mapper#update}.\n * @param {Object} [opts] See {@link Mapper#update}.\n * @returns {Promise} See {@link Mapper#update}.\n * @see Mapper#update\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n 'update',\n\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateAll\n * @see Container~beforeUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Container~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Container#event:beforeUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Container#afterUpdateAll\n * @see Container~afterUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Container~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Container#event:afterUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * store.updateAll('post', update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateAll\n * @fires Container#afterUpdateAll\n * @method Container#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} update See {@link Mapper#updateAll}.\n * @param {Object} [query] See {@link Mapper#updateAll}.\n * @param {Object} [opts] See {@link Mapper#updateAll}.\n * @returns {Promise} See {@link Mapper#updateAll}.\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n 'updateAll',\n\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateMany\n * @see Container~beforeUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Container~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Container#event:beforeUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Container#afterUpdateMany\n * @see Container~afterUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Container~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Container#event:afterUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.updateMany('post', [\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateMany\n * @fires Container#afterUpdateMany\n * @method Container#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#updateMany}.\n * @param {Object} [opts] See {@link Mapper#updateMany}.\n * @returns {Promise} See {@link Mapper#updateMany}.\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n 'updateMany',\n\n /**\n * Wrapper for {@link Mapper#validate}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * let errors = store.validate('post', { name: 'John' })\n * console.log(errors) // undefined\n * errors = store.validate('post', { name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Container#validate\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#validate}.\n * @param {Object} [opts] See {@link Mapper#validate}.\n * @returns {Promise} See {@link Mapper#validate}.\n * @see Mapper#validate\n * @since 3.0.0\n */\n 'validate'\n]\n\n/**\n * The `Container` class is a place to define and store {@link Mapper} instances.\n *\n * `Container` makes it easy to manage your Mappers. Without a container, you\n * need to manage Mappers yourself, including resolving circular dependencies\n * among relations. All Mappers in a container share the same adapters, so you\n * don't have to register adapters for every single Mapper.\n *\n * @example Container#constructor\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n *\n * @class Container\n * @extends Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {Constructor} [opts.mapperClass] See {@link Container#mapperClass}.\n * @param {Object} [opts.mapperDefaults] See {@link Container#mapperDefaults}.\n * @since 3.0.0\n */\nexport function Container (opts) {\n utils.classCallCheck(this, Container)\n Component.call(this)\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * The adapters registered with this Container, which are also shared by all\n * Mappers in this Container.\n *\n * @name Container#_adapters\n * @see Container#registerAdapter\n * @since 3.0.0\n * @type {Object}\n */\n _adapters: {\n value: {}\n },\n\n /**\n * The the mappers in this container\n *\n * @name Container#_mappers\n * @see Mapper\n * @since 3.0.0\n * @type {Object}\n */\n _mappers: {\n value: {}\n },\n\n /**\n * Constructor function to use in {@link Container#defineMapper} to create new\n * {@link Mapper} instances. {@link Container#mapperClass} should extend\n * {@link Mapper}. By default {@link Mapper} is used to instantiate Mappers.\n *\n * @example Container#mapperClass\n * // import {Container, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const store = new Container({\n * mapperClass: MyMapperClass\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').foo())\n *\n * @name Container#mapperClass\n * @see Mapper\n * @since 3.0.0\n * @type {Constructor}\n */\n mapperClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply options provided by the user\n utils.fillIn(this, opts)\n\n /**\n * Defaults options to pass to {@link Container#mapperClass} when creating a\n * new {@link Mapper}.\n *\n * @example Container#mapperDefaults\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: {\n * idAttribute: '_id'\n * }\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').idAttribute)\n *\n * @default {}\n * @name Container#mapperDefaults\n * @since 3.0.0\n * @type {Object}\n */\n this.mapperDefaults = this.mapperDefaults || {}\n\n // Use the Mapper class if the user didn't provide a mapperClass\n this.mapperClass || (this.mapperClass = Mapper)\n}\n\nconst props = {\n constructor: Container,\n\n /**\n * Register a new event listener on this Container.\n *\n * Proxy for {@link Component#on}. If an event was emitted by a {@link Mapper}\n * in the Container, then the name of the {@link Mapper} will be prepended to\n * the arugments passed to the listener.\n *\n * @example Container#on\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.on('foo', function (...args) { console.log(args.join(':')) })\n * store.defineMapper('user')\n * store.emit('foo', 'arg1', 'arg2')\n * store.getMapper('user').emit('foo', 'arg1', 'arg2')\n *\n * @method Container#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n\n /**\n * Used to bind to events emitted by mappers in this container.\n *\n * @method Container#_onMapperEvent\n * @param {string} name Name of the mapper that emitted the event.\n * @param {...*} [args] Args See {@link Mapper#emit}.\n * @private\n * @since 3.0.0\n */\n _onMapperEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * Return a container scoped to a particular mapper.\n *\n * @example Container#as\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method Container#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} A container scoped to a particular mapper.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n proxiedMapperMethods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Create a new mapper and register it in this container.\n *\n * @example Container#defineMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: { foo: 'bar' }\n * })\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(UserMapper.foo)\n *\n * @method Container#defineMapper\n * @param {string} name Name under which to register the new {@link Mapper}.\n * {@link Mapper#name} will be set to this value.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Container#mapperClass} when creating the new {@link Mapper}.\n * @returns {Mapper} The newly created instance of {@link Mapper}.\n * @see Container#as\n * @since 3.0.0\n */\n defineMapper (name, opts) {\n // For backwards compatibility with defineResource\n if (utils.isObject(name)) {\n opts = name\n name = opts.name\n }\n if (!utils.isString(name)) {\n throw utils.err(`${DOMAIN}#defineMapper`, 'name')(400, 'string', name)\n }\n\n // Default values for arguments\n opts || (opts = {})\n // Set Mapper#name\n opts.name = name\n opts.relations || (opts.relations = {})\n\n // Check if the user is overriding the datastore's default mapperClass\n const mapperClass = opts.mapperClass || this.mapperClass\n delete opts.mapperClass\n\n // Apply the datastore's defaults to the options going into the mapper\n utils.fillIn(opts, this.mapperDefaults)\n\n // Instantiate a mapper\n const mapper = this._mappers[name] = new mapperClass(opts) // eslint-disable-line\n mapper.relations || (mapper.relations = {})\n // Make sure the mapper's name is set\n mapper.name = name\n // All mappers in this datastore will share adapters\n mapper._adapters = this.getAdapters()\n\n mapper.datastore = this\n\n mapper.on('all', (...args) => this._onMapperEvent(name, ...args))\n mapper.defineRelations()\n\n return mapper\n },\n\n defineResource (name, opts) {\n console.warn('DEPRECATED: defineResource is deprecated, use defineMapper instead')\n return this.defineMapper(name, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Container#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n */\n getAdapter (name) {\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Container#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || this.mapperDefaults.defaultAdapter\n },\n\n /**\n * Return the registered adapters of this container.\n *\n * @method Container#getAdapters\n * @returns {Adapter}\n * @since 3.0.0\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Return the mapper registered under the specified name.\n *\n * @example Container#getMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * store.getMapper('profile') // throws Error, there is no mapper with name \"profile\"\n *\n * @method Container#getMapper\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapper (name) {\n const mapper = this.getMapperByName(name)\n if (!mapper) {\n throw utils.err(`${DOMAIN}#getMapper`, name)(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Return the mapper registered under the specified name.\n * Doesn't throw error if mapper doesn't exist.\n *\n * @example Container#getMapperByName\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(store.getMapper('profile')) // Does NOT throw an error\n *\n * @method Container#getMapperByName\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapperByName (name) {\n return this._mappers[name]\n },\n\n /**\n * Register an adapter on this container under the given name. Adapters\n * registered on a container are shared by all mappers in the container.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n *\n * @method Container#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for all Mappers in this container.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.mapperDefaults.defaultAdapter = name\n utils.forOwn(this._mappers, function (mapper) {\n mapper.defaultAdapter = name\n })\n }\n }\n}\n\nproxiedMapperMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getMapper(name)[method](...args)\n }\n})\n\nComponent.extend(props)\n\n/**\n * Create a subclass of this Container:\n * @example Container.extend\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomContainerClass extends Container {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customContainer = new CustomContainerClass()\n * console.log(customContainer.foo())\n * console.log(CustomContainerClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherContainerClass = Container.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherContainer = new OtherContainerClass()\n * console.log(otherContainer.foo())\n * console.log(OtherContainerClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherContainerClass () {\n * Container.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Container.extend({\n * constructor: AnotherContainerClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherContainer = new AnotherContainerClass()\n * console.log(anotherContainer.created_at)\n * console.log(anotherContainer.foo())\n * console.log(AnotherContainerClass.beep())\n *\n * @method Container.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Container class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport './decorators'\nimport Collection from './Collection'\n\nconst DOMAIN = 'LinkedCollection'\n\n/**\n * Extends {@link Collection}. Used by a {@link DataStore} to implement an\n * Identity Map.\n *\n * ```javascript\n * import {LinkedCollection} from 'js-data'\n * ```\n *\n * @class LinkedCollection\n * @extends Collection\n * @param {Array} [records] Initial set of records to insert into the\n * collection. See {@link Collection}.\n * @param {Object} [opts] Configuration options. See {@link Collection}.\n * @returns {Mapper}\n */\nfunction LinkedCollection (records, opts) {\n utils.classCallCheck(this, LinkedCollection)\n // Make sure this collection has somewhere to store \"added\" timestamps\n Object.defineProperties(this, {\n _added: {\n value: {}\n },\n datastore: {\n writable: true,\n value: undefined\n }\n })\n\n Collection.call(this, records, opts)\n\n // Make sure this collection has a reference to a datastore\n if (!this.datastore) {\n throw utils.err(`new ${DOMAIN}`, 'opts.datastore')(400, 'DataStore', this.datastore)\n }\n}\n\nexport default Collection.extend({\n constructor: LinkedCollection,\n\n _addMeta (record, timestamp) {\n // Track when this record was added\n this._added[this.recordId(record)] = timestamp\n\n if (utils.isFunction(record._set)) {\n record._set('$', timestamp)\n }\n },\n\n _clearMeta (record) {\n delete this._added[this.recordId(record)]\n if (utils.isFunction(record._set)) {\n record._set('$') // unset\n }\n },\n\n _onRecordEvent (...args) {\n Collection.prototype._onRecordEvent.apply(this, args)\n const event = args[0]\n // This is a very brute force method\n // Lots of room for optimization\n if (utils.isString(event) && event.indexOf('change') === 0) {\n this.updateIndexes(args[1])\n }\n },\n\n add (records, opts) {\n const mapper = this.mapper\n const timestamp = new Date().getTime()\n const singular = utils.isObject(records) && !utils.isArray(records)\n\n if (singular) {\n records = [records]\n }\n records = Collection.prototype.add.call(this, records, opts)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.addLinkedRecords(records)\n })\n }\n\n records.forEach((record) => this._addMeta(record, timestamp))\n\n return singular ? records[0] : records\n },\n\n remove (idOrRecord, opts) {\n const mapper = this.mapper\n const record = Collection.prototype.remove.call(this, idOrRecord, opts)\n if (record) {\n this._clearMeta(record)\n }\n\n if (mapper.relationList.length && record) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, [record])\n })\n }\n\n return record\n },\n\n removeAll (query, opts) {\n const mapper = this.mapper\n const records = Collection.prototype.removeAll.call(this, query, opts)\n records.forEach(this._clearMeta, this)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, records)\n })\n }\n\n return records\n }\n})\n\n/**\n * Create a subclass of this LinkedCollection:\n *\n * @example LinkedCollection.extend\n * // Normally you would do: import {LinkedCollection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {LinkedCollection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomLinkedCollectionClass extends LinkedCollection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customLinkedCollection = new CustomLinkedCollectionClass()\n * console.log(customLinkedCollection.foo())\n * console.log(CustomLinkedCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherLinkedCollectionClass = LinkedCollection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherLinkedCollection = new OtherLinkedCollectionClass()\n * console.log(otherLinkedCollection.foo())\n * console.log(OtherLinkedCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherLinkedCollectionClass () {\n * LinkedCollection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * LinkedCollection.extend({\n * constructor: AnotherLinkedCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherLinkedCollection = new AnotherLinkedCollectionClass()\n * console.log(anotherLinkedCollection.created_at)\n * console.log(anotherLinkedCollection.foo())\n * console.log(AnotherLinkedCollectionClass.beep())\n *\n * @method LinkedCollection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this LinkedCollection class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\nimport {proxiedMapperMethods, Container} from './Container'\nimport LinkedCollection from './LinkedCollection'\n\nconst DOMAIN = 'DataStore'\nconst proxiedCollectionMethods = [\n /**\n * Wrapper for {@link LinkedCollection#add}.\n *\n * @example DataStore#add\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n *\n * // Add one book to the in-memory store:\n * store.add('book', { id: 1, title: 'Respect your Data' })\n * // Add multiple books to the in-memory store:\n * store.add('book', [\n * { id: 2, title: 'Easy data recipes' },\n * { id: 3, title: 'Active Record 101' }\n * ])\n *\n * @fires DataStore#add\n * @method DataStore#add\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Object[]|Record|Record[])} data See {@link LinkedCollection#add}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#add}.\n * @returns {(Object|Object[]|Record|Record[])} See {@link LinkedCollection#add}.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n 'add',\n\n /**\n * Wrapper for {@link LinkedCollection#between}.\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = store.between('user', 18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = store.between('user', [18], [30], { index: 'age' })\n *\n * @method DataStore#between\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Array} leftKeys See {@link LinkedCollection#between}.\n * @param {Array} rightKeys See {@link LinkedCollection#between}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#between}.\n * @returns {Object[]|Record[]} See {@link LinkedCollection#between}.\n * @see LinkedCollection#between\n * @see Collection#between\n * @since 3.0.0\n */\n 'between',\n\n /**\n * Wrapper for {@link LinkedCollection#createIndex}.\n *\n * @example\n * // Index users by age\n * store.createIndex('user', 'age')\n *\n * @example\n * // Index users by status and role\n * store.createIndex('user', 'statusAndRole', ['status', 'role'])\n *\n * @method DataStore#createIndex\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {string} name See {@link LinkedCollection#createIndex}.\n * @param {string[]} [fieldList] See {@link LinkedCollection#createIndex}.\n * @see LinkedCollection#createIndex\n * @see Collection#createIndex\n * @since 3.0.0\n */\n 'createIndex',\n\n /**\n * Wrapper for {@link LinkedCollection#filter}.\n *\n * @example DataStore#filter\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = store.filter('post', function (post) { return post.id % 2 === 0 })\n *\n * @method DataStore#filter\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Function)} [queryOrFn={}] See {@link LinkedCollection#filter}.\n * @param {Object} [thisArg] See {@link LinkedCollection#filter}.\n * @returns {Array} See {@link LinkedCollection#filter}.\n * @see LinkedCollection#filter\n * @see Collection#filter\n * @since 3.0.0\n */\n 'filter',\n\n /**\n * Wrapper for {@link LinkedCollection#get}.\n *\n * @example DataStore#get\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * console.log(store.get('post', 1)) // {...}\n * console.log(store.get('post', 2)) // undefined\n *\n * @method DataStore#get\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link LinkedCollection#get}.\n * @returns {(Object|Record)} See {@link LinkedCollection#get}.\n * @see LinkedCollection#get\n * @see Collection#get\n * @since 3.0.0\n */\n 'get',\n\n /**\n * Wrapper for {@link LinkedCollection#getAll}.\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = store.getAll('post', 'draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = store.getAll('post', ['draft'], ['inReview'], { index: 'status' })\n *\n * @method DataStore#getAll\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {...Array} [keyList] See {@link LinkedCollection#getAll}.\n * @param {Object} [opts] See {@link LinkedCollection#getAll}.\n * @returns {Array} See {@link LinkedCollection#getAll}.\n * @see LinkedCollection#getAll\n * @see Collection#getAll\n * @since 3.0.0\n */\n 'getAll',\n\n /**\n * Wrapper for {@link LinkedCollection#prune}.\n *\n * @method DataStore#prune\n * @param {Object} [opts] See {@link LinkedCollection#prune}.\n * @returns {Array} See {@link LinkedCollection#prune}.\n * @see LinkedCollection#prune\n * @see Collection#prune\n * @since 3.0.0\n */\n 'prune',\n\n /**\n * Wrapper for {@link LinkedCollection#query}.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * store.query('user')\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method DataStore#query\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @returns {Query} See {@link LinkedCollection#query}.\n * @see LinkedCollection#query\n * @see Collection#query\n * @since 3.0.0\n */\n 'query',\n\n /**\n * Wrapper for {@link LinkedCollection#toJSON}.\n *\n * @example\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * title: { type: 'string' }\n * }\n * }\n * })\n * store.add('post', [\n * { id: 1, status: 'published', title: 'Respect your Data' },\n * { id: 2, status: 'draft', title: 'Connecting to a data source' }\n * ])\n * console.log(store.toJSON('post'))\n * const draftsJSON = store.query('post')\n * .filter({ status: 'draft' })\n * .mapCall('toJSON')\n * .run()\n *\n * @method DataStore#toJSON\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Object} [opts] See {@link LinkedCollection#toJSON}.\n * @returns {Array} See {@link LinkedCollection#toJSON}.\n * @see LinkedCollection#toJSON\n * @see Collection#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Wrapper for {@link LinkedCollection#unsaved}.\n *\n * @method DataStore#unsaved\n * @returns {Array} See {@link LinkedCollection#unsaved}.\n * @see LinkedCollection#unsaved\n * @see Collection#unsaved\n * @since 3.0.0\n */\n 'unsaved'\n]\nconst ownMethodsForScoping = [\n 'addToCache',\n 'cachedFind',\n 'cachedFindAll',\n 'cacheFind',\n 'cacheFindAll',\n 'hashQuery'\n]\n\nconst safeSetProp = function (record, field, value) {\n if (record && record._set) {\n record._set(`props.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nconst safeSetLink = function (record, field, value) {\n if (record && record._set) {\n record._set(`links.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nconst cachedFn = function (name, hashOrId, opts) {\n const cached = this._completedQueries[name][hashOrId]\n if (utils.isFunction(cached)) {\n return cached(name, hashOrId, opts)\n }\n return cached\n}\n\nconst DATASTORE_DEFAULTS = {\n /**\n * Whether in-memory relations should be unlinked from records after they are\n * destroyed.\n *\n * @default true\n * @name DataStore#unlinkOnDestroy\n * @since 3.0.0\n * @type {boolean}\n */\n unlinkOnDestroy: true,\n\n /**\n * Whether to use the pending query if a `find` request for the specified\n * record is currently underway. Can be set to `true`, `false`, or to a\n * function that returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFind\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFind: true,\n\n /**\n * Whether to use the pending query if a `findAll` request for the given query\n * is currently underway. Can be set to `true`, `false`, or to a function that\n * returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFindAll\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFindAll: true\n}\n\n/**\n * The `DataStore` class is an extension of {@link Container}. Not only does\n * `DataStore` manage mappers, but also collections. `DataStore` implements the\n * asynchronous {@link Mapper} methods, such as {@link Mapper#find} and\n * {@link Mapper#create}. If you use the asynchronous `DataStore` methods\n * instead of calling them directly on the mappers, then the results of the\n * method calls will be inserted into the store's collections. You can think of\n * a `DataStore` as an [Identity Map](https://en.wikipedia.org/wiki/Identity_map_pattern)\n * for the [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)\n * (the Mappers).\n *\n * ```javascript\n * import {DataStore} from 'js-data'\n * ```\n *\n * @example\n * import {DataStore} from 'js-data'\n * import HttpAdapter from 'js-data-http'\n * const store = new DataStore()\n *\n * // DataStore#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n *\n * // DataStore#as returns the store scoped to a particular Mapper.\n * const UserStore = store.as('user')\n *\n * // Call \"find\" on \"UserMapper\" (Stateless ORM)\n * UserMapper.find(1).then((user) => {\n * // retrieved a \"user\" record via the http adapter, but that's it\n *\n * // Call \"find\" on \"store\" targeting \"user\" (Stateful DataStore)\n * return store.find('user', 1) // same as \"UserStore.find(1)\"\n * }).then((user) => {\n * // not only was a \"user\" record retrieved, but it was added to the\n * // store's \"user\" collection\n * const cachedUser = store.getCollection('user').get(1)\n * console.log(user === cachedUser) // true\n * })\n *\n * @class DataStore\n * @extends Container\n * @param {Object} [opts] Configuration options. See {@link Container}.\n * @param {boolean} [opts.collectionClass={@link LinkedCollection}] See {@link DataStore#collectionClass}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {boolean} [opts.unlinkOnDestroy=true] See {@link DataStore#unlinkOnDestroy}.\n * @param {boolean|Function} [opts.usePendingFind=true] See {@link DataStore#usePendingFind}.\n * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link DataStore#usePendingFindAll}.\n * @returns {DataStore}\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/working-with-the-datastore\",\"Working with the DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/jsdata-and-the-browser\",\"Notes on using JSData in the Browser\"]\n */\nfunction DataStore (opts) {\n utils.classCallCheck(this, DataStore)\n\n opts || (opts = {})\n // Fill in any missing options with the defaults\n utils.fillIn(opts, DATASTORE_DEFAULTS)\n Container.call(this, opts)\n\n this.collectionClass = this.collectionClass || LinkedCollection\n this._collections = {}\n this._pendingQueries = {}\n this._completedQueries = {}\n}\n\nconst props = {\n constructor: DataStore,\n\n _callSuper (method, ...args) {\n return this.constructor.__super__.prototype[method].apply(this, args)\n },\n\n /**\n * Internal method used to handle Mapper responses.\n *\n * @method DataStore#_end\n * @private\n * @param {string} name Name of the {@link LinkedCollection} to which to\n * add the data.\n * @param {Object} result The result from a Mapper.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object|Array)} Result.\n */\n _end (name, result, opts) {\n let data = opts.raw ? result.data : result\n if (data && utils.isFunction(this.addToCache)) {\n data = this.addToCache(name, data, opts)\n if (opts.raw) {\n result.data = data\n } else {\n result = data\n }\n }\n return result\n },\n\n /**\n * Register a new event listener on this DataStore.\n *\n * Proxy for {@link Container#on}. If an event was emitted by a Mapper or\n * Collection in the DataStore, then the name of the Mapper or Collection will\n * be prepended to the arugments passed to the provided event handler.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * store.on('add', (mapperName, records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * store.on('change', (mapperName, record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method DataStore#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n */\n\n /**\n * Used to bind to events emitted by collections in this store.\n *\n * @method DataStore#_onCollectionEvent\n * @private\n * @param {string} name Name of the collection that emitted the event.\n * @param {...*} [args] Args passed to {@link Collection#emit}.\n */\n _onCollectionEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * This method takes the data received from {@link DataStore#find},\n * {@link DataStore#findAll}, {@link DataStore#update}, etc., and adds the\n * data to the store. _You don't need to call this method directly._\n *\n * If you're using the http adapter and your response data is in an unexpected\n * format, you may need to override this method so the right data gets added\n * to the store.\n *\n * @example\n * const store = new DataStore({\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return DataStore.prototype.addToCache.call(this, mapperName, data, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return super.addToCache(mapperName, data, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#addToCache\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {*} data Data from which data should be selected for add.\n * @param {Object} [opts] Configuration options.\n */\n addToCache (name, data, opts) {\n return this.getCollection(name).add(data, opts)\n },\n\n /**\n * Return the store scoped to a particular mapper/collection pair.\n *\n * @example DataStore.as\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method DataStore#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} The store, scoped to a particular Mapper/Collection pair.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n const methods = ownMethodsForScoping\n .concat(proxiedMapperMethods)\n .concat(proxiedCollectionMethods)\n\n methods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n props.getCollection = {\n writable: true,\n value () {\n return original.getCollection(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Retrieve a cached `find` result, if any. This method is called during\n * {@link DataStore#find} to determine if {@link Mapper#find} needs to be\n * called. If this method returns `undefined` then {@link Mapper#find} will\n * be called. Otherwise {@link DataStore#find} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFind.call(this, mapperName, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cachedFind(mapperName, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cachedFind: cachedFn,\n\n /**\n * Retrieve a cached `findAll` result, if any. This method is called during\n * {@link DataStore#findAll} to determine if {@link Mapper#findAll} needs to be\n * called. If this method returns `undefined` then {@link Mapper#findAll} will\n * be called. Otherwise {@link DataStore#findAll} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return super.cachedFindAll(mapperName, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cachedFindAll: cachedFn,\n\n /**\n * Mark a {@link Mapper#find} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `find` entry is\n * added it means subsequent calls to the same Resource with the same `id`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#get} instead of delegating to {@link Mapper#find}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cacheFind.call(this, mapperName, data, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cacheFind(mapperName, data, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {*} data The result to cache.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cacheFind (name, data, id, opts) {\n this._completedQueries[name][id] = (name, id, opts) => this.get(name, id)\n },\n\n /**\n * Mark a {@link Mapper#findAll} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `findAll` entry is\n * added it means subsequent calls to the same Resource with the same `query`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#filter} instead of delegating to {@link Mapper#findAll}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, data, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return super.cachedFindAll(mapperName, data, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {*} data The result to cache.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cacheFindAll (name, data, hash, opts) {\n this._completedQueries[name][hash] = (name, hash, opts) => this.filter(name, utils.fromJson(hash))\n },\n\n /**\n * Remove __all__ records from the in-memory store and reset\n * {@link DataStore#_completedQueries}.\n *\n * @method DataStore#clear\n * @returns {Object} Object containing all records that were in the store.\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n clear () {\n const removed = {}\n utils.forOwn(this._collections, (collection, name) => {\n removed[name] = collection.removeAll()\n this._completedQueries[name] = {}\n })\n return removed\n },\n\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~beforeCreateListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreate\n * @see DataStore~beforeCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback DataStore~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see DataStore#event:beforeCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~afterCreateListener} for how to listen for this event.\n *\n * @event DataStore#afterCreate\n * @see DataStore~afterCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback DataStore~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see DataStore#event:afterCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}. Adds the created record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book {\"author_id\":1234,...}\n * store.create('book', {\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }).then((book) => {\n * console.log(book.id) // 120392\n * console.log(book.title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreate\n * @fires DataStore#afterCreate\n * @fires DataStore#add\n * @method DataStore#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} record Passed to {@link Mapper#create}.\n * @param {Object} [opts] Passed to {@link Mapper#create}. See\n * {@link Mapper#create} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n create (name, record, opts) {\n opts || (opts = {})\n return this._callSuper('create', name, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~beforeCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreateMany\n * @see DataStore~beforeCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback DataStore~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see DataStore#event:beforeCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~afterCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterCreateMany\n * @see DataStore~afterCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback DataStore~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see DataStore#event:afterCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}. Adds the created records to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book [{\"author_id\":1234,...},{...}]\n * store.createMany('book', [{\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }, {\n * author_id: 1234,\n * edition: 'Second Edition',\n * title: 'Respect your Data'\n * }]).then((books) => {\n * console.log(books[0].id) // 142394\n * console.log(books[0].title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreateMany\n * @fires DataStore#afterCreateMany\n * @fires DataStore#add\n * @method DataStore#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Array} records Passed to {@link Mapper#createMany}.\n * @param {Object} [opts] Passed to {@link Mapper#createMany}. See\n * {@link Mapper#createMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n createMany (name, records, opts) {\n opts || (opts = {})\n return this._callSuper('createMany', name, records, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n defineMapper (name, opts) {\n // Complexity of this method is beyond simply using => functions to bind context\n const self = this\n const mapper = Container.prototype.defineMapper.call(self, name, opts)\n self._pendingQueries[name] = {}\n self._completedQueries[name] = {}\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n\n // The datastore uses a subclass of Collection that is \"datastore-aware\"\n const collection = self._collections[name] = new self.collectionClass(null, { // eslint-disable-line\n // Make sure the collection has somewhere to store \"added\" timestamps\n _added: {},\n // Give the collection a reference to this datastore\n datastore: self,\n // The mapper tied to the collection\n mapper\n })\n\n const schema = mapper.schema || {}\n const properties = schema.properties || {}\n // TODO: Make it possible index nested properties?\n utils.forOwn(properties, function (opts, prop) {\n if (opts.indexed) {\n collection.createIndex(prop)\n }\n })\n\n // Create a secondary index on the \"added\" timestamps of records in the\n // collection\n collection.createIndex('addedTimestamps', ['$'], {\n fieldGetter (obj) {\n return collection._added[collection.recordId(obj)]\n }\n })\n\n collection.on('all', function (...args) {\n self._onCollectionEvent(name, ...args)\n })\n\n const idAttribute = mapper.idAttribute\n\n mapper.relationList.forEach(function (def) {\n const relation = def.relation\n const localField = def.localField\n const path = `links.${localField}`\n const foreignKey = def.foreignKey\n const type = def.type\n const updateOpts = { index: foreignKey }\n let descriptor\n\n const getter = function () { return this._get(path) }\n\n if (type === belongsToType) {\n if (!collection.indexes[foreignKey]) {\n collection.createIndex(foreignKey)\n }\n\n descriptor = {\n get: getter,\n // e.g. profile.user = someUser\n // or comment.post = somePost\n set (record) {\n // e.g. const otherUser = profile.user\n const currentParent = this._get(path)\n // e.g. profile.user === someUser\n if (record === currentParent) {\n return currentParent\n }\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n\n // e.g. profile.user !== someUser\n // or comment.post !== somePost\n if (currentParent) {\n // e.g. otherUser.profile = undefined\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n // e.g. remove comment from otherPost.comments\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n if (record) {\n // e.g. profile.user = someUser\n const relatedIdAttribute = def.getRelation().idAttribute\n const relatedId = utils.get(record, relatedIdAttribute)\n\n // Prefer store record\n if (relatedId !== undefined && this._get('$')) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n // e.g. profile.user = someUser\n // or comment.post = somePost\n safeSetLink(this, localField, record)\n safeSetProp(this, foreignKey, relatedId)\n collection.updateIndex(this, updateOpts)\n\n // Update (set) inverse relation\n if (inverseDef.type === hasOneType) {\n // e.g. someUser.profile = profile\n safeSetLink(record, inverseDef.localField, this)\n } else if (inverseDef.type === hasManyType) {\n // e.g. add comment to somePost.comments\n const children = utils.get(record, inverseDef.localField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n } else {\n // Unset in-memory link only\n // e.g. profile.user = undefined\n // or comment.post = undefined\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n\n let foreignKeyDescriptor = Object.getOwnPropertyDescriptor(mapper.recordClass.prototype, foreignKey)\n if (!foreignKeyDescriptor) {\n foreignKeyDescriptor = {\n enumerable: true\n }\n }\n const originalGet = foreignKeyDescriptor.get\n foreignKeyDescriptor.get = function () {\n if (originalGet) {\n return originalGet.call(this)\n }\n return this._get(`props.${foreignKey}`)\n }\n const originalSet = foreignKeyDescriptor.set\n foreignKeyDescriptor.set = function (value) {\n if (originalSet) {\n originalSet.call(this, value)\n }\n const currentParent = utils.get(this, localField)\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n const currentParentId = currentParent ? utils.get(currentParent, def.getRelation().idAttribute) : undefined\n\n if (currentParent && currentParentId !== undefined && currentParentId !== value) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n\n safeSetProp(this, foreignKey, value)\n collection.updateIndex(this, updateOpts)\n\n if ((value === undefined || value === null)) {\n if (currentParentId !== undefined) {\n // Unset locals\n utils.set(this, localField, undefined)\n }\n } else if (this._get('$')) {\n const storeRecord = self.get(relation, value)\n if (storeRecord) {\n utils.set(this, localField, storeRecord)\n }\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, foreignKey, foreignKeyDescriptor)\n } else if (type === hasManyType) {\n const localKeys = def.localKeys\n const foreignKeys = def.foreignKeys\n\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n\n descriptor = {\n get () {\n let current = getter.call(this)\n if (!current) {\n this._set(path, [])\n }\n return getter.call(this)\n },\n // e.g. post.comments = someComments\n // or user.groups = someGroups\n // or group.users = someUsers\n set (records) {\n if (records && !utils.isArray(records)) {\n records = [records]\n }\n const id = utils.get(this, idAttribute)\n const relatedIdAttribute = def.getRelation().idAttribute\n const inverseDef = def.getInverse(mapper)\n const inverseLocalField = inverseDef.localField\n const current = this._get(path) || []\n const toLink = []\n const toLinkIds = {}\n\n if (records) {\n records.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n const currentParent = utils.get(record, inverseLocalField)\n if (currentParent && currentParent !== this) {\n const currentChildrenOfParent = utils.get(currentParent, localField)\n // e.g. somePost.comments.remove(comment)\n if (relatedId === undefined) {\n utils.remove(currentChildrenOfParent, (child) => child === record)\n } else {\n utils.remove(currentChildrenOfParent, (child) => child === record || relatedId === utils.get(child, relatedIdAttribute))\n }\n }\n if (relatedId !== undefined) {\n if (this._get('$')) {\n // Prefer store record\n record = self.get(relation, relatedId) || record\n }\n // e.g. toLinkIds[comment.id] = comment\n toLinkIds[relatedId] = record\n }\n toLink.push(record)\n })\n }\n\n // e.g. post.comments = someComments\n if (foreignKey) {\n current.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(record) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update (unset) inverse relation\n if (records) {\n // e.g. comment.post_id = undefined\n safeSetProp(record, foreignKey, undefined)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n }\n // e.g. comment.post = undefined\n safeSetLink(record, inverseLocalField, undefined)\n }\n })\n toLink.forEach((record) => {\n // Update (set) inverse relation\n // e.g. comment.post_id = post.id\n safeSetProp(record, foreignKey, id)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n // e.g. comment.post = post\n safeSetLink(record, inverseLocalField, this)\n })\n } else if (localKeys) {\n // Update locals\n // e.g. group.users = someUsers\n // Update (set) inverse relation\n const ids = toLink.map((child) => utils.get(child, relatedIdAttribute)).filter((id) => id !== undefined)\n // e.g. group.user_ids = [1,2,3,...]\n utils.set(this, localKeys, ids)\n // Update (unset) inverse relation\n if (inverseDef.foreignKeys) {\n current.forEach((child) => {\n const relatedId = utils.get(child, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(child) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update inverse relation\n // safeSetLink(child, inverseLocalField, undefined)\n const parents = utils.get(child, inverseLocalField) || []\n // e.g. someUser.groups.remove(group)\n if (id === undefined) {\n utils.remove(parents, (parent) => parent === this)\n } else {\n utils.remove(parents, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n }\n })\n toLink.forEach((child) => {\n // Update (set) inverse relation\n const parents = utils.get(child, inverseLocalField)\n // e.g. someUser.groups.push(group)\n if (id === undefined) {\n utils.noDupeAdd(parents, this, (parent) => parent === this)\n } else {\n utils.noDupeAdd(parents, this, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n })\n }\n } else if (foreignKeys) {\n // e.g. user.groups = someGroups\n // Update (unset) inverse relation\n current.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n // e.g. someGroup.user_ids.remove(user.id)\n utils.remove(ids, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n // e.g. someGroup.users.remove(user)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n // Update (set) inverse relation\n toLink.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n utils.noDupeAdd(ids, id, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n }\n\n this._set(path, toLink)\n return toLink\n }\n }\n } else if (type === hasOneType) {\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n descriptor = {\n get: getter,\n // e.g. user.profile = someProfile\n set (record) {\n const current = this._get(path)\n if (record === current) {\n return current\n }\n const inverseLocalField = def.getInverse(mapper).localField\n if (record) {\n // Update (unset) inverse relation\n if (current) {\n safeSetProp(current, foreignKey, undefined)\n self.getCollection(relation).updateIndex(current, updateOpts)\n safeSetLink(current, inverseLocalField, undefined)\n }\n const relatedId = utils.get(record, def.getRelation().idAttribute)\n // Prefer store record\n if (relatedId !== undefined) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n safeSetLink(this, localField, record)\n\n // Update (set) inverse relation\n safeSetProp(record, foreignKey, utils.get(this, idAttribute))\n self.getCollection(relation).updateIndex(record, updateOpts)\n safeSetLink(record, inverseLocalField, this)\n } else {\n // Unset locals\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n }\n\n if (descriptor) {\n descriptor.enumerable = def.enumerable === undefined ? false : def.enumerable\n if (def.get) {\n let origGet = descriptor.get\n descriptor.get = function () {\n return def.get(def, this, (...args) => origGet.apply(this, args))\n }\n }\n if (def.set) {\n let origSet = descriptor.set\n descriptor.set = function (related) {\n return def.set(def, this, related, (value) => origSet.call(this, value === undefined ? related : value))\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, localField, descriptor)\n }\n })\n\n return mapper\n },\n\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~beforeDestroyListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroy\n * @see DataStore~beforeDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback DataStore~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see DataStore#event:beforeDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~afterDestroyListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroy\n * @see DataStore~afterDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback DataStore~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see DataStore#event:afterDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}. Removes any destroyed record from the\n * in-memory store. Clears out any {@link DataStore#_completedQueries} entries\n * associated with the provided `id`.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is no longer in the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n *\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroy\n * @fires DataStore#afterDestroy\n * @fires DataStore#remove\n * @method DataStore#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#destroy}.\n * @param {Object} [opts] Passed to {@link Mapper#destroy}. See\n * {@link Mapper#destroy} for more configuration options.\n * @returns {Promise} Resolves when the destroy operation completes.\n * @since 3.0.0\n */\n destroy (name, id, opts) {\n opts || (opts = {})\n return this._callSuper('destroy', name, id, opts).then((result) => {\n const record = this.getCollection(name).remove(id, opts)\n\n if (record && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n utils.set(record, def.localField, undefined)\n })\n }\n\n if (opts.raw) {\n result.data = record\n } else {\n result = record\n }\n delete this._pendingQueries[name][id]\n delete this._completedQueries[name][id]\n return result\n })\n },\n\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroyAll\n * @see DataStore~beforeDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback DataStore~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see DataStore#event:beforeDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~afterDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroyAll\n * @see DataStore~afterDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback DataStore~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see DataStore#event:afterDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}. Removes any destroyed records from\n * the in-memory store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is gone from the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroyAll\n * @fires DataStore#afterDestroyAll\n * @fires DataStore#remove\n * @method DataStore#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper#destroyAll}.\n * @param {Object} [opts] Passed to {@link Mapper#destroyAll}. See\n * {@link Mapper#destroyAll} for more configuration options.\n * @returns {Promise} Resolves when the delete completes.\n * @since 3.0.0\n */\n destroyAll (name, query, opts) {\n opts || (opts = {})\n return this._callSuper('destroyAll', name, query, opts).then((result) => {\n const records = this.getCollection(name).removeAll(query, opts)\n\n if (records && records.length && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n records.forEach((record) => {\n utils.set(record, def.localField, undefined)\n })\n })\n }\n\n if (opts.raw) {\n result.data = records\n } else {\n result = records\n }\n const hash = this.hashQuery(name, query, opts)\n delete this._pendingQueries[name][hash]\n delete this._completedQueries[name][hash]\n return result\n })\n },\n\n eject (name, id, opts) {\n console.warn('DEPRECATED: \"eject\" is deprecated, use \"remove\" instead')\n return this.remove(name, id, opts)\n },\n\n ejectAll (name, query, opts) {\n console.warn('DEPRECATED: \"ejectAll\" is deprecated, use \"removeAll\" instead')\n return this.removeAll(name, query, opts)\n },\n\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~beforeFindListener} for how to listen for this event.\n *\n * @event DataStore#beforeFind\n * @see DataStore~beforeFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback DataStore~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see DataStore#event:beforeFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~afterFindListener} for how to listen for this event.\n *\n * @event DataStore#afterFind\n * @see DataStore~afterFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback DataStore~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see DataStore#event:afterFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}. Adds any found record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /book/1234\n * store.find('book', 1234).then((book) => {\n * // The book record is now in the in-memory store\n * console.log(store.get('book', 1234) === book) // true\n * })\n *\n * @fires DataStore#beforeFind\n * @fires DataStore#afterFind\n * @fires DataStore#add\n * @method DataStore#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#find}.\n * @param {Object} [opts] Passed to {@link Mapper#find}.\n * @param {boolean|Function} [opts.usePendingFind] See {@link DataStore#usePendingFind}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n find (name, id, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const pendingQuery = this._pendingQueries[name][id]\n const usePendingFind = opts.usePendingFind === undefined ? this.usePendingFind : opts.usePendingFind\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFind) ? usePendingFind.call(this, name, id, opts) : usePendingFind)) {\n return pendingQuery\n }\n const item = this.cachedFind(name, id, opts)\n let promise\n\n if (opts.force || !item) {\n promise = this._pendingQueries[name][id] = this._callSuper('find', name, id, opts).then((result) => {\n delete this._pendingQueries[name][id]\n result = this._end(name, result, opts)\n this.cacheFind(name, result, id, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][id]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(item)\n }\n return promise\n },\n\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~beforeFindAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeFindAll\n * @see DataStore~beforeFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback DataStore~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see DataStore#event:beforeFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~afterFindAllListener} for how to listen for this event.\n *\n * @event DataStore#afterFindAll\n * @see DataStore~afterFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback DataStore~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see DataStore#event:afterFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#findAll}. Adds any found records to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('movie')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /movie?rating=PG\n * store.find('movie', { rating: 'PG' }).then((movies) => {\n * // The movie records are now in the in-memory store\n * console.log(store.filter('movie'))\n * })\n *\n * @fires DataStore#beforeFindAll\n * @fires DataStore#afterFindAll\n * @fires DataStore#add\n * @method DataStore#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper.findAll}.\n * @param {Object} [opts] Passed to {@link Mapper.findAll}.\n * @param {boolean|Function} [opts.usePendingFindAll] See {@link DataStore#usePendingFindAll}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n findAll (name, query, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const hash = this.hashQuery(name, query, opts)\n const pendingQuery = this._pendingQueries[name][hash]\n const usePendingFindAll = opts.usePendingFindAll === undefined ? this.usePendingFindAll : opts.usePendingFindAll\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFindAll) ? usePendingFindAll.call(this, name, query, opts) : usePendingFindAll)) {\n return pendingQuery\n }\n\n const items = this.cachedFindAll(name, hash, opts)\n let promise\n\n if (opts.force || !items) {\n promise = this._pendingQueries[name][hash] = this._callSuper('findAll', name, query, opts).then((result) => {\n delete this._pendingQueries[name][hash]\n result = this._end(name, result, opts)\n this.cacheFindAll(name, result, hash, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][hash]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(items)\n }\n return promise\n },\n\n /**\n * Return the {@link LinkedCollection} with the given name, if for some\n * reason you need a direct reference to the collection.\n *\n * @method DataStore#getCollection\n * @param {string} name Name of the {@link LinkedCollection} to retrieve.\n * @returns {LinkedCollection}\n * @since 3.0.0\n * @throws {Error} Thrown if the specified {@link LinkedCollection} does not\n * exist.\n */\n getCollection (name) {\n const collection = this._collections[name]\n if (!collection) {\n throw utils.err(`${DOMAIN}#getCollection`, name)(404, 'collection')\n }\n return collection\n },\n\n /**\n * Hashing function used to cache {@link DataStore#find} and\n * {@link DataStore#findAll} requests. This method simply JSONifies the\n * `query` argument passed to {@link DataStore#find} or\n * {@link DataStore#findAll}.\n *\n * Override this method for custom hashing behavior.\n * @method DataStore#hashQuery\n * @param {string} name The `name` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @param {Object} query The `query` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @returns {string} The JSONified `query`.\n * @since 3.0.0\n */\n hashQuery (name, query, opts) {\n return utils.toJson(query)\n },\n\n inject (name, records, opts) {\n console.warn('DEPRECATED: \"inject\" is deprecated, use \"add\" instead')\n return this.add(name, records, opts)\n },\n\n /**\n * Wrapper for {@link LinkedCollection#remove}. Removes the specified\n * {@link Record} from the store.\n *\n * @example DataStore#remove\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n * console.log(store.getAll('book').length)\n * store.add('book', { id: 1234 })\n * console.log(store.getAll('book').length)\n * store.remove('book', 1234)\n * console.log(store.getAll('book').length)\n *\n * @fires DataStore#remove\n * @method DataStore#remove\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {string|number} id The primary key of the {@link Record} to remove.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n remove (name, id, opts) {\n const record = this.getCollection(name).remove(id, opts)\n if (record) {\n this.removeRelated(name, [record], opts)\n }\n return record\n },\n\n /**\n * Wrapper for {@link LinkedCollection#removeAll}. Removes the selected\n * {@link Record}s from the store.\n *\n * @example DataStore#removeAll\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('movie')\n * console.log(store.getAll('movie').length)\n * store.add('movie', [{ id: 3, rating: 'R' }, { id: 4, rating: 'PG-13' })\n * console.log(store.getAll('movie').length)\n * store.removeAll('movie', { rating: 'R' })\n * console.log(store.getAll('movie').length)\n *\n * @fires DataStore#remove\n * @method DataStore#removeAll\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}s, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n removeAll (name, query, opts) {\n const records = this.getCollection(name).removeAll(query, opts)\n if (records.length) {\n this.removeRelated(name, records, opts)\n }\n return records\n },\n\n /**\n * Remove from the store {@link Record}s that are related to the provided\n * {@link Record}(s).\n *\n * @fires DataStore#remove\n * @method DataStore#removeRelated\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Record|Record[]} records {@link Record}s whose relations are to be\n * removed.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record}(s) to remove\n * from the store.\n * @since 3.0.0\n */\n removeRelated (name, records, opts) {\n if (!utils.isArray(records)) {\n records = [records]\n }\n utils.forEachRelation(this.getMapper(name), opts, (def, optsCopy) => {\n records.forEach((record) => {\n let relatedData\n let query\n if (def.foreignKey && (def.type === hasOneType || def.type === hasManyType)) {\n query = { [def.foreignKey]: def.getForeignKey(record) }\n } else if (def.type === hasManyType && def.localKeys) {\n query = {\n where: {\n [def.getRelation().idAttribute]: {\n 'in': utils.get(record, def.localKeys)\n }\n }\n }\n } else if (def.type === hasManyType && def.foreignKeys) {\n query = {\n where: {\n [def.foreignKeys]: {\n 'contains': def.getForeignKey(record)\n }\n }\n }\n } else if (def.type === belongsToType) {\n relatedData = this.remove(def.relation, def.getForeignKey(record), optsCopy)\n }\n if (query) {\n relatedData = this.removeAll(def.relation, query, optsCopy)\n }\n if (relatedData) {\n if (utils.isArray(relatedData) && !relatedData.length) {\n return\n }\n if (def.type === hasOneType) {\n relatedData = relatedData[0]\n }\n def.setLocalField(record, relatedData)\n }\n })\n })\n },\n\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~beforeUpdateListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdate\n * @see DataStore~beforeUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback DataStore~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see DataStore#event:beforeUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~afterUpdateListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdate\n * @see DataStore~afterUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback DataStore~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see DataStore#event:afterUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}. Adds the updated {@link Record} to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post/1234 {\"status\":\"published\"}\n * store.update('post', 1, { status: 'published' }).then((post) => {\n * // The post record has also been updated in the in-memory store\n * console.log(store.get('post', 1234))\n * })\n *\n * @fires DataStore#beforeUpdate\n * @fires DataStore#afterUpdate\n * @fires DataStore#add\n * @method DataStore#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#update}.\n * @param {Object} record Passed to {@link Mapper#update}.\n * @param {Object} [opts] Passed to {@link Mapper#update}. See\n * {@link Mapper#update} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n update (name, id, record, opts) {\n opts || (opts = {})\n return this._callSuper('update', name, id, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateAll\n * @see DataStore~beforeUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback DataStore~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see DataStore#event:beforeUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~afterUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateAll\n * @see DataStore~afterUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback DataStore~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see DataStore#event:afterUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post?author_id=1234 {\"status\":\"published\"}\n * store.updateAll('post', { author_id: 1234 }, { status: 'published' }).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.filter('posts', { author_id: 1234 }))\n * })\n *\n * @fires DataStore#beforeUpdateAll\n * @fires DataStore#afterUpdateAll\n * @fires DataStore#add\n * @method DataStore#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props Passed to {@link Mapper#updateAll}.\n * @param {Object} [query] Passed to {@link Mapper#updateAll}.\n * @param {Object} [opts] Passed to {@link Mapper#updateAll}. See\n * {@link Mapper#updateAll} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateAll (name, props, query, opts) {\n opts || (opts = {})\n return this._callSuper('updateAll', name, query, props, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateMany\n * @see DataStore~beforeUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback DataStore~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see DataStore#event:beforeUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~afterUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateMany\n * @see DataStore~afterUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback DataStore~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see DataStore#event:afterUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post [{\"id\":3,status\":\"published\"},{\"id\":4,status\":\"published\"}]\n * store.updateMany('post', [\n * { id: 3, status: 'published' },\n * { id: 4, status: 'published' }\n * ]).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.getAll('post', 3, 4))\n * })\n *\n * @fires DataStore#beforeUpdateMany\n * @fires DataStore#afterUpdateMany\n * @fires DataStore#add\n * @method DataStore#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records Passed to {@link Mapper#updateMany}.\n * @param {Object} [opts] Passed to {@link Mapper#updateMany}. See\n * {@link Mapper#updateMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateMany (name, records, opts) {\n opts || (opts = {})\n return this._callSuper('updateMany', name, records, opts)\n .then((result) => this._end(name, result, opts))\n }\n}\n\nproxiedCollectionMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getCollection(name)[method](...args)\n }\n})\n\nexport default Container.extend(props)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link DataStore~changeListener} on how to listen for this event.\n *\n * @event DataStore#change\n * @see DataStore~changeListener\n */\n\n/**\n * Callback signature for the {@link DataStore#event:change} event.\n *\n * @example\n * function onChange (mapperName, record, changes) {\n * // do something\n * }\n * store.on('change', onChange)\n *\n * @callback DataStore~changeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record} record The Record that changed.\n * @param {Object} changes The changes.\n * @see DataStore#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the in-memory store. See\n * {@link DataStore~addListener} on how to listen for this event.\n *\n * @event DataStore#add\n * @see DataStore~addListener\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n */\n\n/**\n * Callback signature for the {@link DataStore#event:add} event.\n *\n * @example\n * function onAdd (mapperName, recordOrRecords) {\n * // do something\n * }\n * store.on('add', onAdd)\n *\n * @callback DataStore~addListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} The Record or Records that were added.\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the in-memory store. See\n * {@link DataStore~removeListener} for how to listen for this event.\n *\n * @event DataStore#remove\n * @see DataStore~removeListener\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n */\n\n/**\n * Callback signature for the {@link DataStore#event:remove} event.\n *\n * @example\n * function onRemove (mapperName, recordsOrRecords) {\n * // do something\n * }\n * store.on('remove', onRemove)\n *\n * @callback DataStore~removeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} Record or Records that were removed.\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this DataStore:\n * @example DataStore.extend\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomDataStoreClass extends DataStore {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customDataStore = new CustomDataStoreClass()\n * console.log(customDataStore.foo())\n * console.log(CustomDataStoreClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherDataStoreClass = DataStore.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherDataStore = new OtherDataStoreClass()\n * console.log(otherDataStore.foo())\n * console.log(OtherDataStoreClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherDataStoreClass () {\n * DataStore.call(this)\n * this.created_at = new Date().getTime()\n * }\n * DataStore.extend({\n * constructor: AnotherDataStoreClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherDataStore = new AnotherDataStoreClass()\n * console.log(anotherDataStore.created_at)\n * console.log(anotherDataStore.foo())\n * console.log(AnotherDataStoreClass.beep())\n *\n * @method DataStore.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this DataStore class.\n * @since 3.0.0\n */\n","/**\n * Registered as `js-data` in NPM and Bower.\n *\n * Also available from CDN.JS and JSDelivr.\n *\n * @module js-data\n *\n * @example Install from NPM\n * npm i --save js-data@beta\n * @example Install from Bower\n * bower i --save js-data@3.0.0-beta.1\n * @example Install from CDN.JS\n * \n * @example Install from JSDelivr\n * \n * @example Load into your app via script tag\n * \n * \n * @example Load into your app via CommonJS\n * var JSData = require('js-data');\n * @example Load into your app via ES2015 Modules\n * import * as JSData from 'js-data';\n * @example Load into your app via AMD\n * define('myApp', ['js-data'], function (JSData) { ... })\n */\n\n/**\n * Describes the version of this `JSData` object.\n *\n * @example\n * console.log(JSData.version.full) // \"3.0.0-beta.1\"\n *\n * @name version\n * @memberof module:js-data\n * @property {string} full The full semver value.\n * @property {number} major The major version number.\n * @property {number} minor The minor version number.\n * @property {number} patch The patch version number.\n * @property {(string|boolean)} alpha The alpha version value, otherwise `false`\n * if the current version is not alpha.\n * @property {(string|boolean)} beta The beta version value, otherwise `false`\n * if the current version is not beta.\n * @since 2.0.0\n * @type {Object}\n */\nexport const version = '<%= version %>'\n\n/**\n * JSData's utility methods.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @name module:js-data.utils\n * @property {Function} Promise See {@link utils.Promise}.\n * @see utils\n * @since 3.0.0\n * @type {Object}\n */\nimport utils from './utils'\n\n/**\n * JSData's {@link Collection} class.\n *\n * @example\n * import {Collection} from 'js-data'\n * const collection = new Collection()\n *\n * @name module:js-data.Collection\n * @see Collection\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#collection\",\"Components of JSData: Collection\"]\n * @type {Constructor}\n */\nimport Collection from './Collection'\n\n/**\n * JSData's {@link Component} class. Most components in JSData extend this\n * class.\n *\n * @example\n * import {Component} from 'js-data'\n * // Make a custom component.\n * const MyComponent = Component.extend({\n * myMethod (someArg) { ... }\n * })\n *\n * @name module:js-data.Component\n * @see Component\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Component from './Component'\n\n/**\n * JSData's {@link Container} class. Defines and manages {@link Mapper}s. Used\n * in Node.js and in the browser, though in the browser you may want to use\n * {@link DataStore} instead.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n *\n * @name module:js-data.Container\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#container\",\"Components of JSData: Container\"]\n * @type {Constructor}\n */\nimport {Container} from './Container'\n\n/**\n * JSData's {@link DataStore} class. Primarily for use in the browser. In\n * Node.js you probably want to use {@link Container} instead.\n *\n * @example\n * import {DataStore} from 'js-data'\n * const store = new DataStore()\n *\n * @name module:js-data.DataStore\n * @see DataStore\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @type {Constructor}\n */\nimport DataStore from './DataStore'\n\n/**\n * JSData's {@link Index} class, based on [mindex]{@link https://github.com/internalfx/mindex}.\n *\n * @name module:js-data.Index\n * @see Index\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Index from '../lib/mindex/index'\n\n/**\n * JSData's {@link LinkedCollection} class. Used by the {@link DataStore}\n * component. If you need to create a collection manually, you should probably\n * use the {@link Collection} class.\n *\n * @name module:js-data.LinkedCollection\n * @see DataStore\n * @see LinkedCollection\n * @since 3.0.0\n * @type {Constructor}\n */\nimport LinkedCollection from './LinkedCollection'\n\n/**\n * JSData's {@link Mapper} class. The core of the ORM.\n *\n * @example Recommended use\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @example Create Mapper manually\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @name module:js-data.Mapper\n * @see Container\n * @see Mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @type {Constructor}\n */\nimport Mapper from './Mapper'\n\n/**\n * JSData's {@link Query} class. Used by the {@link Collection} component.\n *\n * @name module:js-data.Query\n * @see Query\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Query from './Query'\n\n/**\n * JSData's {@link Record} class.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n *\n * @name module:js-data.Record\n * @see Record\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#record\",\"Components of JSData: Record\"]\n * @type {Constructor}\n */\nimport Record from './Record'\n\n/**\n * JSData's {@link Schema} class. Implements http://json-schema.org/draft-04.\n *\n * @example\n * import {Container, Schema} from 'js-data'\n * const userSchema = new Schema({\n * properties: {\n * id: { type: 'string' },\n * name: { type: 'string' }\n * }\n * })\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: userSchema\n * })\n *\n * @name module:js-data.Schema\n * @see Schema\n * @see http://json-schema.org/\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#schema\",\"Components of JSData: schema\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/schemas\",\"JSData's Schema Syntax\"]\n * @type {Constructor}\n */\nimport Schema from './Schema'\n\n/**\n * JSData's {@link Settable} class.\n *\n * @example\n * import {Settable} from 'js-data'\n * const obj = new Settable()\n * obj.set('secret', 'value')\n * console.log(JSON.stringify(obj)) // {}\n *\n * @name module:js-data.Settable\n * @see Settable\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Settable from './Settable'\n\nexport * from './decorators'\n\nexport {\n Collection,\n Component,\n Container,\n DataStore,\n Index,\n LinkedCollection,\n Mapper,\n Query,\n Record,\n Schema,\n Settable,\n utils\n}\n"],"names":["DOMAIN","Component","Query","Schema","Record","_belongsTo","_hasMany","_hasOne","Mapper","Collection","LinkedCollection","props"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["../src/utils.js","../src/Settable.js","../src/Component.js","../src/Query.js","../lib/mindex/_utils.js","../lib/mindex/index.js","../src/Collection.js","../src/Relation.js","../src/Relation/BelongsTo.js","../src/Relation/HasMany.js","../src/Relation/HasOne.js","../src/relations.js","../src/decorators.js","../src/Record.js","../src/Schema.js","../src/Mapper.js","../src/Container.js","../src/LinkedCollection.js","../src/DataStore.js","../src/index.js"],"sourcesContent":["/**\n * Utility methods used by JSData.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @namespace utils\n * @type {Object}\n */\n\nconst DOMAIN = 'utils'\n\nconst INFINITY = 1 / 0\nconst MAX_INTEGER = 1.7976931348623157e+308\nconst BOOL_TAG = '[object Boolean]'\nconst DATE_TAG = '[object Date]'\nconst FUNC_TAG = '[object Function]'\nconst NUMBER_TAG = '[object Number]'\nconst OBJECT_TAG = '[object Object]'\nconst REGEXP_TAG = '[object RegExp]'\nconst STRING_TAG = '[object String]'\nconst objToString = Object.prototype.toString\nconst PATH = /^(.+)\\.(.+)$/\n\nconst ERRORS = {\n '400' () { return `expected: ${arguments[0]}, found: ${arguments[2] ? arguments[1] : typeof arguments[1]}` },\n '404' () { return `${arguments[0]} not found` }\n}\n\nconst toInteger = function (value) {\n if (!value) {\n return 0\n }\n // Coerce to number\n value = +value\n if (value === INFINITY || value === -INFINITY) {\n const sign = (value < 0 ? -1 : 1)\n return sign * MAX_INTEGER\n }\n const remainder = value % 1\n return value === value ? (remainder ? value - remainder : value) : 0 // eslint-disable-line\n}\n\nconst toStr = function (value) {\n return objToString.call(value)\n}\n\nconst isPlainObject = function (value) {\n return (!!value && typeof value === 'object' && value.constructor === Object)\n}\n\nconst mkdirP = function (object, path) {\n if (!path) {\n return object\n }\n const parts = path.split('.')\n parts.forEach(function (key) {\n if (!object[key]) {\n object[key] = {}\n }\n object = object[key]\n })\n return object\n}\n\nconst utils = {\n /**\n * Reference to the Promise constructor used by JSData. Defaults to\n * `window.Promise` or `global.Promise`.\n *\n * @example Make JSData use a different `Promise` constructor\n * import Promise from 'bluebird'\n * import {utils} from 'js-data'\n * utils.Promise = Promise\n *\n * @name utils.Promise\n * @since 3.0.0\n * @type {Function}\n */\n Promise: Promise,\n\n /**\n * Shallow copy properties that meet the following criteria from `src` to\n * `dest`:\n *\n * - own enumerable\n * - not a function\n * - does not start with \"_\"\n *\n * @method utils._\n * @param {Object} dest Destination object.\n * @param {Object} src Source object.\n * @private\n * @since 3.0.0\n */\n _ (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (key && dest[key] === undefined && !utils.isFunction(value) && key.indexOf('_') !== 0) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Recursively iterates over relations found in `opts.with`.\n *\n * @method utils._forRelation\n * @param {Object} opts Configuration options.\n * @param {Relation} def Relation definition.\n * @param {Function} fn Callback function.\n * @param {*} [thisArg] Execution context for the callback function.\n * @private\n * @since 3.0.0\n */\n _forRelation (opts, def, fn, thisArg) {\n const relationName = def.relation\n let containedName = null\n let index\n opts || (opts = {})\n opts.with || (opts.with = [])\n\n if ((index = utils._getIndex(opts.with, relationName)) >= 0) {\n containedName = relationName\n } else if ((index = utils._getIndex(opts.with, def.localField)) >= 0) {\n containedName = def.localField\n }\n\n if (opts.withAll) {\n fn.call(thisArg, def, {})\n return\n } else if (!containedName) {\n return\n }\n let optsCopy = {}\n utils.fillIn(optsCopy, def.getRelation())\n utils.fillIn(optsCopy, opts)\n optsCopy.with = opts.with.slice()\n optsCopy._activeWith = optsCopy.with.splice(index, 1)[0]\n optsCopy.with.forEach(function (relation, i) {\n if (relation && relation.indexOf(containedName) === 0 && relation.length >= containedName.length && relation[containedName.length] === '.') {\n optsCopy.with[i] = relation.substr(containedName.length + 1)\n } else {\n optsCopy.with[i] = ''\n }\n })\n fn.call(thisArg, def, optsCopy)\n },\n\n /**\n * Find the index of a relation in the given list\n *\n * @method utils._getIndex\n * @param {string[]} list List to search.\n * @param {string} relation Relation to find.\n * @private\n * @returns {number}\n */\n _getIndex (list, relation) {\n let index = -1\n list.forEach(function (_relation, i) {\n if (_relation === relation) {\n index = i\n return false\n } else if (utils.isObject(_relation)) {\n if (_relation.relation === relation) {\n index = i\n return false\n }\n }\n })\n return index\n },\n\n /**\n * Define hidden (non-enumerable), writable properties on `target` from the\n * provided `props`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {}\n * utils.addHiddenPropsToTarget(Cat.prototype, {\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat.say() // \"meow\"\n *\n * @method utils.addHiddenPropsToTarget\n * @param {Object} target That to which `props` should be added.\n * @param {Object} props Properties to be added to `target`.\n * @since 3.0.0\n */\n addHiddenPropsToTarget (target, props) {\n const map = {}\n Object.keys(props).forEach(function (propName) {\n const descriptor = Object.getOwnPropertyDescriptor(props, propName)\n\n descriptor.enumerable = false\n map[propName] = descriptor\n })\n Object.defineProperties(target, map)\n },\n\n /**\n * Return whether the two objects are deeply different.\n *\n * @example\n * import {utils} from 'js-data'\n * utils.areDifferent({}, {}) // false\n * utils.areDifferent({ a: 1 }, { a: 1 }) // false\n * utils.areDifferent({ foo: 'bar' }, {}) // true\n *\n * @method utils.areDifferent\n * @param {Object} a Base object.\n * @param {Object} b Comparison object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Whether the two objects are deeply different.\n * @see utils.diffObjects\n * @since 3.0.0\n */\n areDifferent (newObject, oldObject, opts) {\n opts || (opts = {})\n const diff = utils.diffObjects(newObject, oldObject, opts)\n const diffCount = Object.keys(diff.added).length +\n Object.keys(diff.removed).length +\n Object.keys(diff.changed).length\n return diffCount > 0\n },\n\n /**\n * Verified that the given constructor is being invoked via `new`, as opposed\n * to just being called like a normal function.\n *\n * @example\n * import {utils} from 'js-data'\n * function Cat () {\n * utils.classCallCheck(this, Cat)\n * }\n * const cat = new Cat() // this is ok\n * Cat() // this throws an error\n *\n * @method utils.classCallCheck\n * @param {*} instance Instance that is being constructed.\n * @param {Constructor} ctor Constructor function used to construct the\n * instance.\n * @since 3.0.0\n * @throws {Error} Throws an error if the constructor is being improperly\n * invoked.\n */\n classCallCheck (instance, ctor) {\n if (!(instance instanceof ctor)) {\n throw utils.err(`${ctor.name}`)(500, 'Cannot call a class as a function')\n }\n },\n\n /**\n * Deep copy a value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' } }\n * const b = utils.copy(a)\n * a === b // false\n * utils.areDifferent(a, b) // false\n *\n * @param {*} from Value to deep copy.\n * @param {*} [to] Destination object for the copy operation.\n * @param {*} [stackFrom] For internal use.\n * @param {*} [stackTo] For internal use.\n * @param {string[]|RegExp[]} [blacklist] List of strings or RegExp of\n * properties to skip.\n * @param {boolean} [plain] Whether to make a plain copy (don't try to use\n * original prototype).\n * @returns {*} Deep copy of `from`.\n * @since 3.0.0\n */\n copy (from, to, stackFrom, stackTo, blacklist, plain) {\n if (!to) {\n to = from\n if (from) {\n if (utils.isArray(from)) {\n to = utils.copy(from, [], stackFrom, stackTo, blacklist, plain)\n } else if (utils.isDate(from)) {\n to = new Date(from.getTime())\n } else if (utils.isRegExp(from)) {\n to = new RegExp(from.source, from.toString().match(/[^\\/]*$/)[0])\n to.lastIndex = from.lastIndex\n } else if (utils.isObject(from)) {\n if (plain) {\n to = utils.copy(from, {}, stackFrom, stackTo, blacklist, plain)\n } else {\n to = utils.copy(from, Object.create(Object.getPrototypeOf(from)), stackFrom, stackTo, blacklist, plain)\n }\n }\n }\n } else {\n if (from === to) {\n throw utils.err(`${DOMAIN}.copy`)(500, 'Cannot copy! Source and destination are identical.')\n }\n\n stackFrom = stackFrom || []\n stackTo = stackTo || []\n\n if (utils.isObject(from)) {\n let index = stackFrom.indexOf(from)\n if (index !== -1) {\n return stackTo[index]\n }\n\n stackFrom.push(from)\n stackTo.push(to)\n }\n\n let result\n if (utils.isArray(from)) {\n let i\n to.length = 0\n for (i = 0; i < from.length; i++) {\n result = utils.copy(from[i], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[i])) {\n stackFrom.push(from[i])\n stackTo.push(result)\n }\n to.push(result)\n }\n } else {\n if (utils.isArray(to)) {\n to.length = 0\n } else {\n utils.forOwn(to, function (value, key) {\n delete to[key]\n })\n }\n for (var key in from) {\n if (from.hasOwnProperty(key)) {\n if (utils.isBlacklisted(key, blacklist)) {\n continue\n }\n result = utils.copy(from[key], null, stackFrom, stackTo, blacklist, plain)\n if (utils.isObject(from[key])) {\n stackFrom.push(from[key])\n stackTo.push(result)\n }\n to[key] = result\n }\n }\n }\n }\n return to\n },\n\n /**\n * Recursively shallow fill in own enumerable properties from `source` to\n * `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"bip\"}\n *\n * @method utils.deepFillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n deepFillIn (dest, source) {\n if (source) {\n utils.forOwn(source, function (value, key) {\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepFillIn(existing, value)\n } else if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n }\n return dest\n },\n\n /**\n * Recursively shallow copy enumerable properties from `source` to `dest`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.deepFillIn(b, a)\n * console.log(b) // {\"foo\":{\"bar\":\"baz\"},\"beep\":\"boop\"}\n *\n * @method utils.deepMixIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.fillIn\n * @see utils.deepFillIn\n * @since 3.0.0\n */\n deepMixIn (dest, source) {\n if (source) {\n for (var key in source) {\n const value = source[key]\n const existing = dest[key]\n if (isPlainObject(value) && isPlainObject(existing)) {\n utils.deepMixIn(existing, value)\n } else {\n dest[key] = value\n }\n }\n }\n return dest\n },\n\n /**\n * Return a diff of the base object to the comparison object.\n *\n * @example\n * import {utils} from 'js-data'\n * const oldObject = { foo: 'bar', a: 1234 }\n * const newObject = { beep: 'boop', a: 5678 }\n * const diff = utils.diffObjects(oldObject, newObject)\n * console.log(diff.added) // {\"beep\":\"boop\"}\n * console.log(diff.changed) // {\"a\":5678}\n * console.log(diff.removed) // {\"foo\":undefined}\n *\n * @method utils.diffObjects\n * @param {Object} newObject Comparison object.\n * @param {Object} oldObject Base object.\n * @param {Object} [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} The diff from the base object to the comparison object.\n * @see utils.areDifferent\n * @since 3.0.0\n */\n diffObjects (newObject, oldObject, opts) {\n opts || (opts = {})\n let equalsFn = opts.equalsFn\n let blacklist = opts.ignore\n const diff = {\n added: {},\n changed: {},\n removed: {}\n }\n if (!utils.isFunction(equalsFn)) {\n equalsFn = utils.deepEqual\n }\n\n const newKeys = Object.keys(newObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n const oldKeys = Object.keys(oldObject).filter(function (key) {\n return !utils.isBlacklisted(key, blacklist)\n })\n\n // Check for properties that were added or changed\n newKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (equalsFn(oldValue, newValue)) {\n return\n }\n if (oldValue === undefined) {\n diff.added[key] = newValue\n } else {\n diff.changed[key] = newValue\n }\n })\n\n // Check for properties that were removed\n oldKeys.forEach(function (key) {\n const oldValue = oldObject[key]\n const newValue = newObject[key]\n if (newValue === undefined && oldValue !== undefined) {\n diff.removed[key] = undefined\n }\n })\n\n return diff\n },\n\n /**\n * Return whether the two values are equal according to the `==` operator.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.equal(1,1)) // true\n * console.log(utils.equal(1,'1')) // true\n * console.log(utils.equal(93, 66)) // false\n *\n * @method utils.equal\n * @param {*} a First value in the comparison.\n * @param {*} b Second value in the comparison.\n * @returns {boolean} Whether the two values are equal according to `==`.\n * @since 3.0.0\n */\n equal (a, b) {\n return a == b // eslint-disable-line\n },\n\n /**\n * Produce a factory function for making Error objects with the provided\n * metadata. Used throughout the various js-data components.\n *\n * @example\n * import {utils} from 'js-data'\n * const errorFactory = utils.err('domain', 'target')\n * const error400 = errorFactory(400, 'expected type', 'actual type')\n * console.log(error400) // [Error: [domain:target] expected: expected type, found: string\nhttp://www.js-data.io/v3.0/docs/errors#400]\n * @method utils.err\n * @param {string} domain Namespace.\n * @param {string} target Target.\n * @returns {Function} Factory function.\n * @since 3.0.0\n */\n err (domain, target) {\n return function (code) {\n const prefix = `[${domain}:${target}] `\n let message = ERRORS[code].apply(null, Array.prototype.slice.call(arguments, 1))\n message = `${prefix}${message}\nhttp://www.js-data.io/v3.0/docs/errors#${code}`\n return new Error(message)\n }\n },\n\n /**\n * Add eventing capabilities into the target object.\n *\n * @example\n * import {utils} from 'js-data'\n * const user = { name: 'John' }\n * utils.eventify(user)\n * user.on('foo', () => console.log(arguments))\n * user.emit('foo', 1, 'bar') // should log to console values (1, \"bar\")\n *\n * @method utils.eventify\n * @param {Object} target Target object.\n * @param {Function} [getter] Custom getter for retrieving the object's event\n * listeners.\n * @param {Function} [setter] Custom setter for setting the object's event\n * listeners.\n * @since 3.0.0\n */\n eventify (target, getter, setter) {\n target = target || this\n let _events = {}\n if (!getter && !setter) {\n getter = function () { return _events }\n setter = function (value) { _events = value }\n }\n Object.defineProperties(target, {\n emit: {\n value (...args) {\n const events = getter.call(this) || {}\n const type = args.shift()\n let listeners = events[type] || []\n let i\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n listeners = events.all || []\n args.unshift(type)\n for (i = 0; i < listeners.length; i++) {\n listeners[i].f.apply(listeners[i].c, args)\n }\n }\n },\n off: {\n value (type, func) {\n const events = getter.call(this)\n const listeners = events[type]\n if (!listeners) {\n setter.call(this, {})\n } else if (func) {\n for (let i = 0; i < listeners.length; i++) {\n if (listeners[i].f === func) {\n listeners.splice(i, 1)\n break\n }\n }\n } else {\n listeners.splice(0, listeners.length)\n }\n }\n },\n on: {\n value (type, func, thisArg) {\n if (!getter.call(this)) {\n setter.call(this, {})\n }\n const events = getter.call(this)\n events[type] = events[type] || []\n events[type].push({\n c: thisArg,\n f: func\n })\n }\n }\n })\n },\n\n /**\n * Used for sublcassing. Invoke this method in the context of a superclass to\n * to produce a subclass based on `props` and `classProps`.\n *\n * @example\n * import {utils} from 'js-data'\n * function Animal () {}\n * Animal.extend = utils.extend\n * const Cat = Animal.extend({\n * say () {\n * console.log('meow')\n * }\n * })\n * const cat = new Cat()\n * cat instanceof Animal // true\n * cat instanceof Cat // true\n * cat.say() // \"meow\"\n *\n * @method utils.extend\n * @param {Object} props Instance properties for the subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to use as the subclass.\n * @param {Object} props Static properties for the subclass.\n * @returns {Constructor} A new subclass.\n * @since 3.0.0\n */\n extend (props, classProps) {\n const superClass = this\n let subClass\n\n props || (props = {})\n classProps || (classProps = {})\n\n if (props.hasOwnProperty('constructor')) {\n subClass = props.constructor\n delete props.constructor\n } else {\n subClass = function (...args) {\n utils.classCallCheck(this, subClass)\n superClass.apply(this, args)\n }\n }\n\n // Setup inheritance of instance members\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n configurable: true,\n enumerable: false,\n value: subClass,\n writable: true\n }\n })\n\n const obj = Object\n // Setup inheritance of static members\n if (obj.setPrototypeOf) {\n obj.setPrototypeOf(subClass, superClass)\n } else if (classProps.strictEs6Class) {\n subClass.__proto__ = superClass // eslint-disable-line\n } else {\n utils.forOwn(superClass, function (value, key) {\n subClass[key] = value\n })\n }\n if (!subClass.hasOwnProperty('__super__')) {\n Object.defineProperty(subClass, '__super__', {\n configurable: true,\n value: superClass\n })\n }\n\n utils.addHiddenPropsToTarget(subClass.prototype, props)\n utils.fillIn(subClass, classProps)\n\n return subClass\n },\n\n /**\n * Shallow copy own enumerable properties from `src` to `dest` that are on\n * `src` but are missing from `dest.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: 'bar', beep: 'boop' }\n * const b = { beep: 'bip' }\n * utils.fillIn(b, a)\n * console.log(b) // {\"foo\":\"bar\",\"beep\":\"bip\"}\n *\n * @method utils.fillIn\n * @param {Object} dest The destination object.\n * @param {Object} source The source object.\n * @see utils.deepFillIn\n * @see utils.deepMixIn\n * @since 3.0.0\n */\n fillIn (dest, src) {\n utils.forOwn(src, function (value, key) {\n if (!dest.hasOwnProperty(key) || dest[key] === undefined) {\n dest[key] = value\n }\n })\n },\n\n /**\n * Find the last index of an item in an array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = { name: 'John', age: 20 }\n * const sara = { name: 'Sara', age: 25 }\n * const dan = { name: 'Dan', age: 20 }\n * const users = [john, sara, dan]\n *\n * console.log(utils.findIndex(users, (user) => user.age === 25)) // 1\n * console.log(utils.findIndex(users, (user) => user.age > 19)) // 2\n * console.log(utils.findIndex(users, (user) => user.name === 'John')) // 0\n * console.log(utils.findIndex(users, (user) => user.name === 'Jimmy')) // -1\n *\n * @method utils.findIndex\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n * @returns {number} Index if found or -1 if not found.\n * @since 3.0.0\n */\n findIndex (array, fn) {\n let index = -1\n if (!array) {\n return index\n }\n array.forEach(function (record, i) {\n if (fn(record)) {\n index = i\n return false\n }\n })\n return index\n },\n\n /**\n * Recursively iterate over a {@link Mapper}'s relations according to\n * `opts.with`.\n *\n * @method utils.forEachRelation\n * @param {Mapper} mapper Mapper.\n * @param {Object} opts Configuration options.\n * @param {Function} fn Callback function.\n * @param {*} thisArg Execution context for the callback function.\n * @since 3.0.0\n */\n forEachRelation (mapper, opts, fn, thisArg) {\n const relationList = mapper.relationList || []\n if (!relationList.length) {\n return\n }\n relationList.forEach(function (def) {\n utils._forRelation(opts, def, fn, thisArg)\n })\n },\n\n /**\n * Iterate over an object's own enumerable properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { b: 1, c: 4 }\n * let sum = 0\n * utils.forOwn(a, function (value, key) {\n * sum += value\n * })\n * console.log(sum) // 5\n *\n * @method utils.forOwn\n * @param {Object} object The object whose properties are to be enumerated.\n * @param {Function} fn Iteration function.\n * @param {Object} [thisArg] Content to which to bind `fn`.\n * @since 3.0.0\n */\n forOwn (obj, fn, thisArg) {\n const keys = Object.keys(obj)\n const len = keys.length\n let i\n for (i = 0; i < len; i++) {\n fn.call(thisArg, obj[keys[i]], keys[i], obj)\n }\n },\n\n /**\n * Proxy for `JSON.parse`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = utils.fromJson('{\"name\" : \"John\"}')\n * console.log(a) // { name: 'John' }\n *\n * @method utils.fromJson\n * @param {string} json JSON to parse.\n * @returns {Object} Parsed object.\n * @see utils.toJson\n * @since 3.0.0\n */\n fromJson (json) {\n return utils.isString(json) ? JSON.parse(json) : json\n },\n\n /**\n * Retrieve the specified property from the given object. Supports retrieving\n * nested properties.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: { bar: 'baz' }, beep: 'boop' }\n * console.log(utils.get(a, 'beep')) // \"boop\"\n * console.log(utils.get(a, 'foo.bar')) // \"baz\"\n *\n * @method utils.get\n * @param {Object} object Object from which to retrieve a property's value.\n * @param {string} prop Property to retrieve.\n * @returns {*} Value of the specified property.\n * @see utils.set\n * @since 3.0.0\n */\n 'get': function (object, prop) {\n if (!prop) {\n return\n }\n const parts = prop.split('.')\n const last = parts.pop()\n\n while (prop = parts.shift()) { // eslint-disable-line\n object = object[prop]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n return object[last]\n },\n\n /**\n * Return the superclass for the given instance or subclass. If an instance is\n * provided, then finds the parent class of the instance's constructor.\n *\n * @example\n * import {utils} from 'js-data'\n * // using ES2015 classes\n * class Foo {}\n * class Bar extends Foo {}\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * // using Function constructor with utils.extend\n * function Foo () {}\n * Foo.extend = utils.extend\n * const Bar = Foo.extend()\n * const barInstance = new Bar()\n * let baseType = utils.getSuper(barInstance)\n * console.log(Foo === baseType) // true\n *\n * @method utils.getSuper\n * @param {Object|Function} instance Instance or constructor.\n * @param {boolean} [isCtor=false] Whether `instance` is a constructor.\n * @returns {Constructor} The superclass (grandparent constructor).\n * @since 3.0.0\n */\n getSuper (instance, isCtor) {\n const ctor = isCtor ? instance : instance.constructor\n if (ctor.hasOwnProperty('__super__')) {\n return ctor.__super__\n }\n return Object.getPrototypeOf(ctor) || ctor.__proto__ // eslint-disable-line\n },\n\n /**\n * Return the intersection of two arrays.\n *\n * @example\n * import {utils} from 'js-data'\n * const arrA = ['green', 'red', 'blue', 'red']\n * const arrB = ['green', 'yellow', 'red']\n * const intersected = utils.intersection(arrA, arrB)\n *\n * console.log(intersected) // ['green', 'red'])\n *\n * @method utils.intersection\n * @param {Array} array1 First array.\n * @param {Array} array2 Second array.\n * @returns {Array} Array of elements common to both arrays.\n * @since 3.0.0\n */\n intersection (array1, array2) {\n if (!array1 || !array2) {\n return []\n }\n const result = []\n let item\n let i\n const len = array1.length\n for (i = 0; i < len; i++) {\n item = array1[i]\n if (result.indexOf(item) !== -1) {\n continue\n }\n if (array2.indexOf(item) !== -1) {\n result.push(item)\n }\n }\n return result\n },\n\n /**\n * Proxy for `Array.isArray`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = [1,2,3,4,5]\n * const b = { foo: \"bar\" }\n * console.log(utils.isArray(a)) // true\n * console.log(utils.isArray(b)) // false\n *\n * @method utils.isArray\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an array.\n * @since 3.0.0\n */\n isArray: Array.isArray,\n\n /**\n * Return whether `prop` is matched by any string or regular expression in\n * `blacklist`.\n *\n * @example\n * import {utils} from 'js-data'\n * const blacklist = [/^\\$hashKey/g, /^_/g, 'id']\n * console.log(utils.isBlacklisted(\"$hashKey\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"id\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"_myProp\", blacklist)) // true\n * console.log(utils.isBlacklisted(\"my_id\", blacklist)) // false\n *\n * @method utils.isBlacklisted\n * @param {string} prop The name of a property to check.\n * @param {Array} blacklist Array of strings and regular expressions.\n * @returns {boolean} Whether `prop` was matched.\n * @since 3.0.0\n */\n isBlacklisted (prop, blacklist) {\n if (!blacklist || !blacklist.length) {\n return false\n }\n let matches\n for (var i = 0; i < blacklist.length; i++) {\n if ((toStr(blacklist[i]) === REGEXP_TAG && blacklist[i].test(prop)) || blacklist[i] === prop) {\n matches = prop\n return !!matches\n }\n }\n return !!matches\n },\n\n /**\n * Return whether the provided value is a boolean.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = true\n * const b = { foo: \"bar\" }\n * console.log(utils.isBoolean(a)) // true\n * console.log(utils.isBoolean(b)) // false\n *\n * @method utils.isBoolean\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a boolean.\n * @since 3.0.0\n */\n isBoolean (value) {\n return toStr(value) === BOOL_TAG\n },\n\n /**\n * Return whether the provided value is a date.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = new Date()\n * const b = { foo: \"bar\" }\n * console.log(utils.isDate(a)) // true\n * console.log(utils.isDate(b)) // false\n *\n * @method utils.isDate\n * @param {*} value The value to test.\n * @returns {Date} Whether the provided value is a date.\n * @since 3.0.0\n */\n isDate (value) {\n return (value && typeof value === 'object' && toStr(value) === DATE_TAG)\n },\n\n /**\n * Return whether the provided value is a function.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = function (){ console.log('foo bar')}\n * const b = { foo: \"bar\" }\n * console.log(utils.isFunction(a)) // true\n * console.log(utils.isFunction(b)) // false\n *\n * @method utils.isFunction\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a function.\n * @since 3.0.0\n */\n isFunction (value) {\n return typeof value === 'function' || (value && toStr(value) === FUNC_TAG)\n },\n\n /**\n * Return whether the provided value is an integer.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = 1.25\n * const c = '1'\n * console.log(utils.isInteger(a)) // true\n * console.log(utils.isInteger(b)) // false\n * console.log(utils.isInteger(c)) // false\n *\n * @method utils.isInteger\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an integer.\n * @since 3.0.0\n */\n isInteger (value) {\n return toStr(value) === NUMBER_TAG && value == toInteger(value) // eslint-disable-line\n },\n\n /**\n * Return whether the provided value is `null`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = null\n * const b = { foo: \"bar\" }\n * console.log(utils.isNull(a)) // true\n * console.log(utils.isNull(b)) // false\n *\n * @method utils.isNull\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is `null`.\n * @since 3.0.0\n */\n isNull (value) {\n return value === null\n },\n\n /**\n * Return whether the provided value is a number.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = 1\n * const b = -1.25\n * const c = '1'\n * console.log(utils.isNumber(a)) // true\n * console.log(utils.isNumber(b)) // true\n * console.log(utils.isNumber(c)) // false\n *\n * @method utils.isNumber\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a number.\n * @since 3.0.0\n */\n isNumber (value) {\n const type = typeof value\n return type === 'number' || (value && type === 'object' && toStr(value) === NUMBER_TAG)\n },\n\n /**\n * Return whether the provided value is an object.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\" }\n * const b = 'foo bar'\n * console.log(utils.isObject(a)) // true\n * console.log(utils.isObject(b)) // false\n *\n * @method utils.isObject\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is an object.\n * @since 3.0.0\n */\n isObject (value) {\n return toStr(value) === OBJECT_TAG\n },\n\n /**\n * Return whether the provided value is a regular expression.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = /^\\$.+$/ig\n * const b = new RegExp('^\\$.+$', 'ig')\n * const c = { foo: \"bar\" }\n * console.log(utils.isRegExp(a)) // true\n * console.log(utils.isRegExp(b)) // true\n * console.log(utils.isRegExp(c)) // false\n *\n * @method utils.isRegExp\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a regular expression.\n * @since 3.0.0\n */\n isRegExp (value) {\n return toStr(value) === REGEXP_TAG\n },\n\n /**\n * Return whether the provided value is a string or a number.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isSorN('')) // true\n * console.log(utils.isSorN(-1.65)) // true\n * console.log(utils.isSorN('my string')) // true\n * console.log(utils.isSorN({})) // false\n * console.log(utils.isSorN([1,2,4])) // false\n *\n * @method utils.isSorN\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string or a number.\n * @since 3.0.0\n */\n isSorN (value) {\n return utils.isString(value) || utils.isNumber(value)\n },\n\n /**\n * Return whether the provided value is a string.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('')) // true\n * console.log(utils.isString('my string')) // true\n * console.log(utils.isString(100)) // false\n * console.log(utils.isString([1,2,4])) // false\n *\n * @method utils.isString\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a string.\n * @since 3.0.0\n */\n isString (value) {\n return typeof value === 'string' || (value && typeof value === 'object' && toStr(value) === STRING_TAG)\n },\n\n /**\n * Return whether the provided value is a `undefined`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = undefined\n * const b = { foo: \"bar\"}\n * console.log(utils.isUndefined(a)) // true\n * console.log(utils.isUndefined(b.baz)) // true\n * console.log(utils.isUndefined(b)) // false\n * console.log(utils.isUndefined(b.foo)) // false\n *\n * @method utils.isUndefined\n * @param {*} value The value to test.\n * @returns {boolean} Whether the provided value is a `undefined`.\n * @since 3.0.0\n */\n isUndefined (value) {\n return value === undefined\n },\n\n /**\n * Mix in logging capabilities to the target.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { foo: \"bar\"}\n *\n * // Add standard logging to an object\n * utils.logify(a)\n * a.log('info', 'test log info') // output 'test log info' to console.\n *\n * // Toggle debug output of an object\n * a.dbg('test debug output') // does not output because debug is off.\n * a.debug = true\n * a.dbg('test debug output') // output 'test debug output' to console.\n *\n * @method utils.logify\n * @param {*} target The target.\n * @since 3.0.0\n */\n logify (target) {\n utils.addHiddenPropsToTarget(target, {\n dbg (...args) {\n if (utils.isFunction(this.log)) {\n this.log('debug', ...args)\n }\n },\n log (level, ...args) {\n if (level && !args.length) {\n args.push(level)\n level = 'debug'\n }\n if (level === 'debug' && !this.debug) {\n return\n }\n const prefix = `${level.toUpperCase()}: (${this.name || this.constructor.name})`\n if (utils.isFunction(console[level])) {\n console[level](prefix, ...args)\n } else {\n console.log(prefix, ...args)\n }\n }\n })\n },\n\n /**\n * Adds the given record to the provided array only if it's not already in the\n * array.\n *\n * @example\n * import {utils} from 'js-data'\n * const colors = ['red', 'green', 'yellow']\n *\n * console.log(colors.length) // 3\n * utils.noDupeAdd(colors, 'red')\n * console.log(colors.length) // 3, red already exists\n *\n * utils.noDupeAdd(colors, 'blue')\n * console.log(colors.length) // 4, blue was added\n *\n * @method utils.noDupeAdd\n * @param {Array} array The array.\n * @param {*} record The value to add.\n * @param {Function} fn Callback function passed to {@link utils.findIndex}.\n * @since 3.0.0\n */\n noDupeAdd (array, record, fn) {\n if (!array) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index < 0) {\n array.push(record)\n }\n },\n\n /**\n * Return a shallow copy of the provided object, minus the properties\n * specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.omit(a, ['$hashKey'])\n * console.log(b) // { name: 'John' }\n *\n * @method utils.omit\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to skip.\n * @returns {Object} Shallow copy of `props`, minus `keys`.\n * @since 3.0.0\n */\n omit (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) === -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a shallow copy of the provided object, but only include the\n * properties specified in `keys`.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John', $hashKey: 1214910 }\n *\n * let b = utils.pick(a, ['$hashKey'])\n * console.log(b) // { $hashKey: 1214910 }\n *\n * @method utils.pick\n * @param {Object} props The object to copy.\n * @param {string[]} keys Array of strings, representing properties to keep.\n * @returns {Object} Shallow copy of `props`, but only including `keys`.\n * @since 3.0.0\n */\n pick (props, keys) {\n const _props = {}\n utils.forOwn(props, function (value, key) {\n if (keys.indexOf(key) !== -1) {\n _props[key] = value\n }\n })\n return _props\n },\n\n /**\n * Return a plain copy of the given value.\n *\n * @example\n * import {utils} from 'js-data'\n * const a = { name: 'John' }\n * let b = utils.plainCopy(a)\n * console.log(a === b) // false\n *\n * @method utils.plainCopy\n * @param {*} value The value to copy.\n * @returns {*} Plain copy of `value`.\n * @see utils.copy\n * @since 3.0.0\n */\n plainCopy (value) {\n return utils.copy(value, undefined, undefined, undefined, undefined, true)\n },\n\n /**\n * Shortcut for `utils.Promise.reject(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.reject(\"Testing static reject\").then(function(data) {\n * // not called\n * }).catch(function(reason) {\n * console.log(reason); // \"Testing static reject\"\n * })\n *\n * @method utils.reject\n * @param {*} [value] Value with which to reject the Promise.\n * @returns {Promise} Promise reject with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n reject (value) {\n return utils.Promise.reject(value)\n },\n\n /**\n * Remove the last item found in array according to the given checker function.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const colors = ['red', 'green', 'yellow', 'red']\n * utils.remove(colors, (color) => color === 'red')\n * console.log(colors) // ['red', 'green', 'yellow']\n *\n * @method utils.remove\n * @param {Array} array The array to search.\n * @param {Function} fn Checker function.\n */\n remove (array, fn) {\n if (!array || !array.length) {\n return\n }\n const index = this.findIndex(array, fn)\n if (index >= 0) {\n array.splice(index, 1) // todo should this be recursive?\n }\n },\n\n /**\n * Shortcut for `utils.Promise.resolve(value)`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * utils.resolve(\"Testing static resolve\").then(function(data) {\n * console.log(data); // \"Testing static resolve\"\n * }).catch(function(reason) {\n * // not called\n * })\n *\n * @param {*} [value] Value with which to resolve the Promise.\n * @returns {Promise} Promise resolved with `value`.\n * @see utils.Promise\n * @since 3.0.0\n */\n resolve (value) {\n return utils.Promise.resolve(value)\n },\n\n /**\n * Set the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n * // set value by key\n * utils.set(john, 'id', 98)\n * console.log(john.id) // 98\n *\n * // set value by path\n * utils.set(john, 'parent.id', 20)\n * console.log(john.parent.id) // 20\n *\n * // set value by path/value map\n * utils.set(john, {\n * 'id': 1098,\n * 'parent': { id: 1020 },\n * 'parent.age': '55'\n * })\n * console.log(john.id) // 1098\n * console.log(john.parent.id) // 1020\n * console.log(john.parent.age) // 55\n *\n * @method utils.set\n * @param {Object} object The object on which to set a property.\n * @param {(string|Object)} path The key or path to the property. Can also\n * pass in an object of path/value pairs, which will all be set on the target\n * object.\n * @param {*} [value] The value to set.\n */\n set: function (object, path, value) {\n if (utils.isObject(path)) {\n utils.forOwn(path, function (value, _path) {\n utils.set(object, _path, value)\n })\n } else {\n const parts = PATH.exec(path)\n if (parts) {\n mkdirP(object, parts[1])[parts[2]] = value\n } else {\n object[path] = value\n }\n }\n },\n\n /**\n * Check whether the two provided objects are deeply equal.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const objA = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * const objB = {\n * name: 'John',\n * id: 27,\n * nested: {\n * item: 'item 1',\n * colors: ['red', 'green', 'blue']\n * }\n * }\n *\n * console.log(utils.deepEqual(a,b)) // true\n * objB.nested.colors.add('yellow') // make a change to a nested object's array\n * console.log(utils.deepEqual(a,b)) // false\n *\n * @method utils.deepEqual\n * @param {Object} a First object in the comparison.\n * @param {Object} b Second object in the comparison.\n * @returns {boolean} Whether the two provided objects are deeply equal.\n * @see utils.equal\n * @since 3.0.0\n */\n deepEqual (a, b) {\n if (a === b) {\n return true\n }\n let _equal = true\n if (utils.isObject(a) && utils.isObject(b)) {\n utils.forOwn(a, function (value, key) {\n _equal = _equal && utils.deepEqual(value, b[key])\n })\n if (!_equal) {\n return _equal\n }\n utils.forOwn(b, function (value, key) {\n _equal = _equal && utils.deepEqual(value, a[key])\n })\n } else if (utils.isArray(a) && utils.isArray(b)) {\n a.forEach(function (value, i) {\n _equal = _equal && utils.deepEqual(value, b[i])\n if (!_equal) {\n return false\n }\n })\n } else {\n return false\n }\n return _equal\n },\n\n /**\n * Proxy for `JSON.stringify`.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const a = { name: 'John' }\n * let jsonVal = utils.toJson(a)\n * console.log(jsonVal) // '{\"name\" : \"John\"}'\n *\n * @method utils.toJson\n * @param {*} value Value to serialize to JSON.\n * @returns {string} JSON string.\n * @see utils.fromJson\n * @since 3.0.0\n */\n toJson: JSON.stringify,\n\n /**\n * Unset the value at the provided key or path.\n *\n * @example\n * import {utils} from 'js-data'\n *\n * const john = {\n * name: 'John',\n * age: 25,\n * parent: {\n * name: 'John's Mom',\n * age: 50\n * }\n * }\n *\n * utils.unset(john, age)\n * utils.unset(john, parent.age)\n *\n * console.log(john.age) // null\n * console.log(john.parent.age) // null\n *\n * @method utils.unset\n * @param {Object} object The object from which to delete the property.\n * @param {string} path The key or path to the property.\n * @see utils.set\n * @since 3.0.0\n */\n unset (object, path) {\n const parts = path.split('.')\n const last = parts.pop()\n\n while (path = parts.shift()) { // eslint-disable-line\n object = object[path]\n if (object == null) { // eslint-disable-line\n return\n }\n }\n\n object[last] = undefined\n },\n\n}\n\nexport const safeSetProp = function (record, field, value) {\n if (record && record._set) {\n record._set(`props.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nexport const safeSetLink = function (record, field, value) {\n if (record && record._set) {\n record._set(`links.${field}`, value)\n } else {\n utils.set(record, field, value)\n }\n}\n\nexport default utils\n","import utils from './utils'\n\n/**\n * A base class which gives instances private properties.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Settable.extend} for an example of using {@link Settable} as a\n * base class.\n *\n *```javascript\n * import {Settable} from 'js-data'\n * ```\n *\n * @class Settable\n * @returns {Settable} A new {@link Settable} instance.\n * @since 3.0.0\n */\nexport default function Settable () {\n const _props = {}\n Object.defineProperties(this, {\n /**\n * Get a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method Settable#_get\n * @param {string} key The property to retrieve.\n * @returns {*} The value of the property.\n * @since 3.0.0\n */\n _get: { value (key) { return utils.get(_props, key) } },\n\n /**\n * Set a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_set\n * @param {(string|Object)} key The key or path to the property. Can also\n * pass in an object of key/value pairs, which will all be set on the instance.\n * @param {*} [value] The value to set.\n * @since 3.0.0\n */\n _set: { value (key, value) { return utils.set(_props, key, value) } },\n\n /**\n * Unset a private property of this instance.\n *\n * __Don't use the method unless you know what you're doing.__\n *\n * @method __Don't use the method unless you know what you're doing.__#_unset\n * @param {string} key The property to unset.\n * @since 3.0.0\n */\n _unset: { value (key) { return utils.unset(_props, key) } }\n })\n}\n\n/**\n * Create a subclass of this Settable:\n *\n * @example Settable.extend\n * // Normally you would do: import {Settable} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Settable} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSettableClass extends Settable {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSettable = new CustomSettableClass()\n * console.log(customSettable.foo())\n * console.log(CustomSettableClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSettableClass = Settable.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSettable = new OtherSettableClass()\n * console.log(otherSettable.foo())\n * console.log(OtherSettableClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSettableClass () {\n * Settable.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Settable.extend({\n * constructor: AnotherSettableClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSettable = new AnotherSettableClass()\n * console.log(anotherSettable.created_at)\n * console.log(anotherSettable.foo())\n * console.log(AnotherSettableClass.beep())\n *\n * @method Settable.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Settable class.\n * @since 3.0.0\n */\nSettable.extend = utils.extend\n","import utils from './utils'\nimport Settable from './Settable'\n\n/**\n * The base class from which all JSData components inherit some basic\n * functionality.\n *\n * Typically you won't instantiate this class directly, but you may find it\n * useful as an abstract class for your own components.\n *\n * See {@link Component.extend} for an example of using {@link Component} as a\n * base class.\n *\n *```javascript\n * import {Component} from 'js-data'\n * ```\n *\n * @class Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @returns {Component} A new {@link Component} instance.\n * @since 3.0.0\n */\nfunction Component (opts) {\n Settable.call(this)\n opts || (opts = {})\n\n /**\n * Whether to enable debug-level logs for this component. Anything that\n * extends `Component` inherits this option and the corresponding logging\n * functionality.\n *\n * @example Component#debug\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const component = new Component()\n * component.log('debug', 'some message') // nothing gets logged\n * // Display debug logs:\n * component.debug = true\n * component.log('debug', 'other message') // this DOES get logged\n *\n * @default false\n * @name Component#debug\n * @since 3.0.0\n * @type {boolean}\n */\n this.debug = opts.hasOwnProperty('debug') ? !!opts.debug : false\n\n /**\n * Event listeners attached to this Component. __Do not modify.__ Use\n * {@link Component#on} and {@link Component#off} instead.\n *\n * @name Component#_listeners\n * @instance\n * @since 3.0.0\n * @type {Object}\n */\n Object.defineProperty(this, '_listeners', { value: {}, writable: true })\n}\n\nexport default Settable.extend({\n constructor: Component\n})\n\n/**\n * Create a subclass of this Component:\n *\n * @example Component.extend\n * // Normally you would do: import {Component} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Component} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomComponentClass extends Component {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customComponent = new CustomComponentClass()\n * console.log(customComponent.foo())\n * console.log(CustomComponentClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherComponentClass = Component.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherComponent = new OtherComponentClass()\n * console.log(otherComponent.foo())\n * console.log(OtherComponentClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherComponentClass () {\n * Component.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Component.extend({\n * constructor: AnotherComponentClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherComponent = new AnotherComponentClass()\n * console.log(anotherComponent.created_at)\n * console.log(anotherComponent.foo())\n * console.log(AnotherComponentClass.beep())\n *\n * @method Component.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Component class.\n * @since 3.0.0\n */\nComponent.extend = utils.extend\n\n/**\n * Log the provided values at the \"debug\" level. Debug-level logs are only\n * logged if {@link Component#debug} is `true`.\n *\n * `.dbg(...)` is shorthand for `.log('debug', ...)`.\n *\n * @method Component#dbg\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\n/**\n * Log the provided values. By default sends values to `console[level]`.\n * Debug-level logs are only logged if {@link Component#debug} is `true`.\n *\n * Will attempt to use appropriate `console` methods if they are available.\n *\n * @method Component#log\n * @param {string} level Log level.\n * @param {...*} [args] Values to log.\n * @since 3.0.0\n */\nutils.logify(Component.prototype)\n\n/**\n * Register a new event listener on this Component.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * collection.on('add', (records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * post.on('change', (record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method Component#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n/**\n * Remove an event listener from this Component. If no listener is provided,\n * then all listeners for the specified event will be removed. If no event is\n * specified then all listeners for all events will be removed.\n *\n * @example\n * // Remove a particular listener for a particular event\n * collection.off('add', handler)\n *\n * @example\n * // Remove all listeners for a particular event\n * record.off('change')\n *\n * @example\n * // Remove all listeners to all events\n * store.off()\n *\n * @method Component#off\n * @param {string} [event] Name of event to unsubsribe to.\n * @param {Function} [listener] Listener to remove.\n * @since 3.0.0\n */\n/**\n * Trigger an event on this Component.\n *\n * @example Component#emit\n * // import {Collection, DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, DataStore} = JSData\n *\n * const collection = new Collection()\n * collection.on('foo', function (msg) {\n * console.log(msg)\n * })\n * collection.emit('foo', 'bar')\n *\n * const store = new DataStore()\n * store.on('beep', function (msg) {\n * console.log(msg)\n * })\n * store.emit('beep', 'boop')\n *\n * @method Component#emit\n * @param {string} event Name of event to emit.\n * @param {...*} [args] Arguments to pass to any listeners.\n * @since 3.0.0\n */\nutils.eventify(\n Component.prototype,\n function () {\n return this._listeners\n },\n function (value) {\n this._listeners = value\n }\n)\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Query'\nconst INDEX_ERR = 'Index inaccessible after first operation'\n\n// Reserved words used by JSData's Query Syntax\nconst reserved = {\n limit: '',\n offset: '',\n orderBy: '',\n skip: '',\n sort: '',\n where: ''\n}\n\n// Used by our JavaScript implementation of the LIKE operator\nconst escapeRegExp = /([.*+?^=!:${}()|[\\]\\/\\\\])/g\nconst percentRegExp = /%/g\nconst underscoreRegExp = /_/g\nconst escape = function (pattern) {\n return pattern.replace(escapeRegExp, '\\\\$1')\n}\n\n/**\n * A class used by the {@link Collection} class to build queries to be executed\n * against the collection's data. An instance of `Query` is returned by\n * {@link Collection#query}. Query instances are typically short-lived, and you\n * shouldn't have to create them yourself. Just use {@link Collection#query}.\n *\n * ```javascript\n * import {Query} from 'js-data'\n * ```\n *\n * @example\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const drafts = store.query('post').filter({ status: 'draft' }).limit(2).run()\n * console.log(drafts)\n *\n * @class Query\n * @extends Component\n * @param {Collection} collection The collection on which this query operates.\n * @since 3.0.0\n */\nfunction Query (collection) {\n utils.classCallCheck(this, Query)\n\n /**\n * The {@link Collection} on which this query operates.\n *\n * @name Query#collection\n * @since 3.0.0\n * @type {Collection}\n */\n this.collection = collection\n\n /**\n * The current data result of this query.\n *\n * @name Query#data\n * @since 3.0.0\n * @type {Array}\n */\n this.data = null\n}\n\nexport default Component.extend({\n constructor: Query,\n\n _applyWhereFromObject (where) {\n const fields = []\n const ops = []\n const predicates = []\n utils.forOwn(where, (clause, field) => {\n if (!utils.isObject(clause)) {\n clause = {\n '==': clause\n }\n }\n utils.forOwn(clause, (expr, op) => {\n fields.push(field)\n ops.push(op)\n predicates.push(expr)\n })\n })\n return {\n fields,\n ops,\n predicates\n }\n },\n\n _applyWhereFromArray (where) {\n const groups = []\n where.forEach((_where, i) => {\n if (utils.isString(_where)) {\n return\n }\n const prev = where[i - 1]\n const parser = utils.isArray(_where) ? this._applyWhereFromArray : this._applyWhereFromObject\n const group = parser.call(this, _where)\n if (prev === 'or') {\n group.isOr = true\n }\n groups.push(group)\n })\n groups.isArray = true\n return groups\n },\n\n _testObjectGroup (keep, first, group, item) {\n let i\n const fields = group.fields\n const ops = group.ops\n const predicates = group.predicates\n const len = ops.length\n for (i = 0; i < len; i++) {\n let op = ops[i]\n const isOr = op.charAt(0) === '|'\n op = isOr ? op.substr(1) : op\n const expr = this.evaluate(utils.get(item, fields[i]), op, predicates[i])\n if (expr !== undefined) {\n keep = first ? expr : (isOr ? keep || expr : keep && expr)\n }\n first = false\n }\n return { keep, first }\n },\n\n _testArrayGroup (keep, first, groups, item) {\n let i\n const len = groups.length\n for (i = 0; i < len; i++) {\n const group = groups[i]\n const parser = group.isArray ? this._testArrayGroup : this._testObjectGroup\n const result = parser.call(this, true, true, group, item)\n if (groups[i - 1]) {\n if (group.isOr) {\n keep = keep || result.keep\n } else {\n keep = keep && result.keep\n }\n } else {\n keep = result.keep\n }\n first = result.first\n }\n return { keep, first }\n },\n\n /**\n * Find all entities between two boundaries.\n *\n * @example Get the users ages 18 to 30.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between(18, 30, { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @example Same as above.\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const filteredUsers = store.query('user').between([18], [30], { index: 'age' }).run()\n * console.log(filteredUsers)\n *\n * @method Query#between\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include entities\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#between`)(500, 'Cannot access index')\n }\n this.data = this.collection.getIndex(opts.index).between(leftKeys, rightKeys, opts)\n return this\n },\n\n /**\n * The comparison function used by the {@link Query} class.\n *\n * @method Query#compare\n * @param {Array} orderBy An orderBy clause used for sorting and sub-sorting.\n * @param {number} index The index of the current orderBy clause being used.\n * @param {*} a The first item in the comparison.\n * @param {*} b The second item in the comparison.\n * @returns {number} -1 if `b` should preceed `a`. 0 if `a` and `b` are equal.\n * 1 if `a` should preceed `b`.\n * @since 3.0.0\n */\n compare (orderBy, index, a, b) {\n const def = orderBy[index]\n let cA = utils.get(a, def[0])\n let cB = utils.get(b, def[0])\n if (cA && utils.isString(cA)) {\n cA = cA.toUpperCase()\n }\n if (cB && utils.isString(cB)) {\n cB = cB.toUpperCase()\n }\n if (a === undefined) {\n a = null\n }\n if (b === undefined) {\n b = null\n }\n if (def[1].toUpperCase() === 'DESC') {\n const temp = cB\n cB = cA\n cA = temp\n }\n if (cA < cB) {\n return -1\n } else if (cA > cB) {\n return 1\n } else {\n if (index < orderBy.length - 1) {\n return this.compare(orderBy, index + 1, a, b)\n } else {\n return 0\n }\n }\n },\n\n /**\n * Predicate evaluation function used by the {@link Query} class.\n *\n * @method Query#evaluate\n * @param {*} value The value to evaluate.\n * @param {string} op The operator to use in this evaluation.\n * @param {*} predicate The predicate to use in this evaluation.\n * @returns {boolean} Whether the value passed the evaluation or not.\n * @since 3.0.0\n */\n evaluate (value, op, predicate) {\n const ops = this.constructor.ops\n if (ops[op]) {\n return ops[op](value, predicate)\n }\n if (op.indexOf('like') === 0) {\n return this.like(predicate, op.substr(4)).exec(value) !== null\n } else if (op.indexOf('notLike') === 0) {\n return this.like(predicate, op.substr(7)).exec(value) === null\n }\n },\n\n /**\n * Find the record or records that match the provided query or are accepted by\n * the provided filter function.\n *\n * @example Get the draft posts by authors younger than 30\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * let results = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * age: {\n * '<': 30\n * }\n * }\n * }).run()\n * console.log(results)\n *\n * @example Use a custom filter function\n * const posts = query.filter(function (post) {\n * return post.isReady()\n * }).run()\n *\n * @method Query#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Function} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n filter (query, thisArg) {\n /**\n * Selection query as defined by JSData's [Query Syntax][querysyntax].\n *\n * [querysyntax]: http://www.js-data.io/v3.0/docs/query-syntax\n *\n * @example Empty \"findAll\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * store.findAll('post').then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @example Empty \"filter\" query\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = store.filter('post')\n * console.log(posts) // [...]\n *\n * @example Complex \"filter\" query\n * const PAGE_SIZE = 2\n * let currentPage = 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * { author: 'Peter', age: 25, status: 'deleted', id: 6 },\n * { author: 'Sally', age: 21, status: 'draft', id: 7 },\n * { author: 'Jim', age: 27, status: 'draft', id: 8 },\n * { author: 'Jim', age: 27, status: 'published', id: 9 },\n * { author: 'Jason', age: 55, status: 'published', id: 10 }\n * ]\n * store.add('post', posts)\n * // Retrieve a filtered page of blog posts\n * // Would typically replace filter with findAll\n * store.filter('post', {\n * where: {\n * status: {\n * // WHERE status = 'published'\n * '==': 'published'\n * },\n * author: {\n * // AND author IN ('bob', 'alice')\n * 'in': ['bob', 'alice'],\n * // OR author IN ('karen')\n * '|in': ['karen']\n * }\n * },\n * orderBy: [\n * // ORDER BY date_published DESC,\n * ['date_published', 'DESC'],\n * // ORDER BY title ASC\n * ['title', 'ASC']\n * ],\n * // LIMIT 2\n * limit: PAGE_SIZE,\n * // SKIP 4\n * offset: PAGE_SIZE * (currentPage - 1)\n * })\n *\n * @namespace query\n * @property {number} [limit] See {@link query.limit}.\n * @property {number} [offset] See {@link query.offset}.\n * @property {string|Array[]} [orderBy] See {@link query.orderBy}.\n * @property {number} [skip] Alias for {@link query.offset}.\n * @property {string|Array[]} [sort] Alias for {@link query.orderBy}.\n * @property {Object} [where] See {@link query.where}.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/query-syntax\",\"JSData's Query Syntax\"]\n */\n query || (query = {})\n this.getData()\n if (utils.isObject(query)) {\n let where = {}\n\n /**\n * Filtering criteria. Records that do not meet this criteria will be exluded\n * from the result.\n *\n * @example Return posts where author is at least 32 years old\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * where: {\n * age: {\n * '>=': 30\n * }\n * }\n * })\n * console.log(results)\n *\n * @name query.where\n * @type {Object}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isObject(query.where) || utils.isArray(query.where)) {\n where = query.where\n }\n utils.forOwn(query, function (value, key) {\n if (!(key in reserved) && !(key in where)) {\n where[key] = {\n '==': value\n }\n }\n })\n let groups\n\n // Apply filter for each field\n if (utils.isObject(where) && Object.keys(where).length !== 0) {\n groups = this._applyWhereFromArray([where])\n } else if (utils.isArray(where)) {\n groups = this._applyWhereFromArray(where)\n }\n\n if (groups) {\n this.data = this.data.filter((item, i) => this._testArrayGroup(true, true, groups, item).keep)\n }\n\n // Sort\n let orderBy = query.orderBy || query.sort\n\n if (utils.isString(orderBy)) {\n orderBy = [\n [orderBy, 'ASC']\n ]\n }\n if (!utils.isArray(orderBy)) {\n orderBy = null\n }\n\n /**\n * Determines how records should be ordered in the result.\n *\n * @example Order posts by `author` then by `id` descending \n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 5 },\n * { author: 'Sally', age: 31, id: 6 },\n * { author: 'Mike', age: 32, id: 7 },\n * { author: 'Adam', age: 33, id: 8 },\n * { author: 'Adam', age: 33, id: 9 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * orderBy:[['author','ASC'],['id','DESC']]\n * })\n * console.log(results)\n *\n * @name query.orderBy\n * @type {string|Array[]}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (orderBy) {\n let index = 0\n orderBy.forEach(function (def, i) {\n if (utils.isString(def)) {\n orderBy[i] = [def, 'ASC']\n }\n })\n this.data.sort((a, b) => this.compare(orderBy, index, a, b))\n }\n\n /**\n * Number of records to skip.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n *\n * @name query.offset\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.skip)) {\n this.skip(query.skip)\n } else if (utils.isNumber(query.offset)) {\n this.skip(query.offset)\n }\n\n /**\n * Maximum number of records to retrieve.\n *\n * @example Retrieve the first \"page\" of blog posts using findAll\n * const PAGE_SIZE = 10\n * let currentPage = 1\n * PostMapper.findAll({\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * @example Retrieve the last \"page\" of blog posts using filter\n * const PAGE_SIZE = 5\n * let currentPage = 2\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, id: 1 },\n * { author: 'Sally', age: 31, id: 2 },\n * { author: 'Mike', age: 32, id: 3 },\n * { author: 'Adam', age: 33, id: 4 },\n * { author: 'Adam', age: 33, id: 5 },\n * { author: 'Peter', age: 25, id: 6 },\n * { author: 'Sally', age: 21, id: 7 },\n * { author: 'Jim', age: 27, id: 8 },\n * { author: 'Jim', age: 27, id: 9 },\n * { author: 'Jason', age: 55, id: 10 }\n * ]\n * store.add('post', posts)\n * store.filter('post', {\n * offset: PAGE_SIZE * (currentPage 1)\n * limit: PAGE_SIZE\n * })\n *\n * console.log(results)\n * @name query.limit\n * @type {number}\n * @see http://www.js-data.io/v3.0/docs/query-syntax\n * @since 3.0.0\n */\n if (utils.isNumber(query.limit)) {\n this.limit(query.limit)\n }\n } else if (utils.isFunction(query)) {\n this.data = this.data.filter(query, thisArg)\n }\n return this\n },\n\n /**\n * Iterate over all entities.\n *\n * @method Query#forEach\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n forEach (forEachFn, thisArg) {\n this.getData().forEach(forEachFn, thisArg)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided key.\n *\n * @example Get the entity whose primary key is 25.\n * const entities = query.get(25).run()\n *\n * @example Same as above.\n * const entities = query.get([25]).run()\n *\n * @example Get all users who are active and have the \"admin\" role.\n * const activeAdmins = query.get(['active', 'admin'], {\n * index: 'activityAndRoles'\n * }).run()\n *\n * @example Get all entities that match a certain weather condition.\n * const niceDays = query.get(['sunny', 'humid', 'calm'], {\n * index: 'weatherConditions'\n * }).run()\n *\n * @method Query#get\n * @param {Array} keyList Key(s) defining the entity to retrieve. If\n * `keyList` is not an array (i.e. for a single-value key), it will be\n * wrapped in an array.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.string] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n get (keyList, opts) {\n keyList || (keyList = [])\n opts || (opts = {})\n if (this.data) {\n throw utils.err(`${DOMAIN}#get`)(500, INDEX_ERR)\n }\n if (keyList && !utils.isArray(keyList)) {\n keyList = [keyList]\n }\n if (!keyList.length) {\n this.getData()\n return this\n }\n this.data = this.collection.getIndex(opts.index).get(keyList)\n return this\n },\n\n /**\n * Find the entity or entities that match the provided keyLists.\n *\n * @example Get the posts where \"status\" is \"draft\" or \"inReview\".\n * const posts = query.getAll('draft', 'inReview', { index: 'status' }).run()\n *\n * @example Same as above.\n * const posts = query.getAll(['draft'], ['inReview'], { index: 'status' }).run()\n *\n * @method Query#getAll\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * entities matching each keyList will be retrieved. If no keyLists are\n * provided, all entities will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n getAll (...args) {\n let opts = {}\n if (this.data) {\n throw utils.err(`${DOMAIN}#getAll`)(500, INDEX_ERR)\n }\n if (!args.length || args.length === 1 && utils.isObject(args[0])) {\n this.getData()\n return this\n } else if (args.length && utils.isObject(args[args.length - 1])) {\n opts = args[args.length - 1]\n args.pop()\n }\n const collection = this.collection\n const index = collection.getIndex(opts.index)\n this.data = []\n args.forEach((keyList) => {\n this.data = this.data.concat(index.get(keyList))\n })\n return this\n },\n\n /**\n * Return the current data result of this query.\n *\n * @method Query#getData\n * @returns {Array} The data in this query.\n * @since 3.0.0\n */\n getData () {\n if (!this.data) {\n this.data = this.collection.index.getAll()\n }\n return this.data\n },\n\n /**\n * Implementation used by the `like` operator. Takes a pattern and flags and\n * returns a `RegExp` instance that can test strings.\n *\n * @method Query#like\n * @param {string} pattern Testing pattern.\n * @param {string} flags Flags for the regular expression.\n * @returns {RegExp} Regular expression for testing strings.\n * @since 3.0.0\n */\n like (pattern, flags) {\n return new RegExp(`^${(escape(pattern).replace(percentRegExp, '.*').replace(underscoreRegExp, '.'))}$`, flags)\n },\n\n /**\n * Limit the result.\n *\n * @example Get only the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').limit(2).run()\n * console.log(results)\n *\n * @method Query#limit\n * @param {number} num The maximum number of entities to keep in the result.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n limit (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#limit`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n this.data = data.slice(0, Math.min(data.length, num))\n return this\n },\n\n /**\n * Apply a mapping function to the result data.\n *\n * @example\n * // Return the age of all users\n * const store = new JSData.DataStore()\n * store.defineMapper('user')\n * const users = [\n * { name: 'Peter', age: 25, id: 1 },\n * { name: 'Jim', age: 19, id: 2 },\n * { name: 'Mike', age: 17, id: 3 },\n * { name: 'Alan', age: 29, id: 4 },\n * { name: 'Katie', age: 33, id: 5 }\n * ]\n * store.add('post', posts)\n * const ages = store.query('user').map((user) => {\n * return user.age\n * }).run()\n * console.log(ages)\n *\n * @method Query#map\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n map (mapFn, thisArg) {\n this.data = this.getData().map(mapFn, thisArg)\n return this\n },\n\n /**\n * Return the result of calling the specified function on each item in this\n * collection's main index.\n *\n * @example\n * const stringAges = UserCollection.query().mapCall('toString').run()\n *\n * @method Query#mapCall\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n mapCall (funcName, ...args) {\n this.data = this.getData().map(function (item) {\n return item[funcName](...args)\n })\n return this\n },\n\n /**\n * Complete the execution of the query and return the resulting data.\n *\n * @method Query#run\n * @returns {Array} The result of executing this query.\n * @since 3.0.0\n */\n run () {\n const data = this.data\n this.data = null\n return data\n },\n\n /**\n * Skip a number of results.\n *\n * @example Get all but the first 2 posts.\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'draft', id: 2 },\n * { author: 'Mike', age: 32, status: 'draft', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'draft', id: 5 }\n * ]\n * store.add('post', posts)\n * const results = store.query('post').skip(2).run()\n * console.log(results)\n *\n * @method Query#skip\n * @param {number} num The number of entities to skip.\n * @returns {Query} A reference to itself for chaining.\n * @since 3.0.0\n */\n skip (num) {\n if (!utils.isNumber(num)) {\n throw utils.err(`${DOMAIN}#skip`, 'num')(400, 'number', num)\n }\n const data = this.getData()\n if (num < data.length) {\n this.data = data.slice(num)\n } else {\n this.data = []\n }\n return this\n }\n}, {\n /**\n * The filtering operators supported by {@link Query#filter}, and which are\n * implemented by adapters (for the most part).\n *\n * @example Variant 1\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * status: 'published',\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n *\n * @example Variant 2\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * }\n * },\n * limit: 2\n * })\n *\n * console.log(publishedPosts)\n *\n * @example Variant 3\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * status: 'published'\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Variant 4\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const publishedPosts = store.query('post').filter({\n * where: {\n * status: {\n * '==': 'published'\n * }\n * }\n * }).limit(2).run()\n *\n * console.log(publishedPosts)\n *\n * @example Multiple operators\n *\n * const store = new JSData.DataStore()\n * store.defineMapper('post')\n * const posts = [\n * { author: 'John', age: 30, status: 'published', id: 1 },\n * { author: 'Sally', age: 31, status: 'published', id: 2 },\n * { author: 'Mike', age: 32, status: 'published', id: 3 },\n * { author: 'Adam', age: 33, status: 'deleted', id: 4 },\n * { author: 'Adam', age: 33, status: 'published', id: 5 }\n * ]\n * store.add('post', posts)\n *\n * const myPublishedPosts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'published'\n * },\n * user_id: {\n * '==': currentUser.id\n * }\n * }\n * })\n *\n * console.log(myPublishedPosts)\n *\n * @name Query.ops\n * @property {Function} == Equality operator.\n * @property {Function} != Inequality operator.\n * @property {Function} > Greater than operator.\n * @property {Function} >= Greater than (inclusive) operator.\n * @property {Function} < Less than operator.\n * @property {Function} <= Less than (inclusive) operator.\n * @property {Function} isectEmpty Operator that asserts that the intersection\n * between two arrays is empty.\n * @property {Function} isectNotEmpty Operator that asserts that the\n * intersection between two arrays is __not__ empty.\n * @property {Function} in Operator that asserts whether a value is in an\n * array.\n * @property {Function} notIn Operator that asserts whether a value is __not__\n * in an array.\n * @property {Function} contains Operator that asserts whether an array\n * contains a value.\n * @property {Function} notContains Operator that asserts whether an array\n * does __not__ contain a value.\n * @since 3.0.0\n * @type {Object}\n */\n ops: {\n '=': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '==': function (value, predicate) {\n return value == predicate // eslint-disable-line\n },\n '===': function (value, predicate) {\n return value === predicate\n },\n '!=': function (value, predicate) {\n return value != predicate // eslint-disable-line\n },\n '!==': function (value, predicate) {\n return value !== predicate\n },\n '>': function (value, predicate) {\n return value > predicate\n },\n '>=': function (value, predicate) {\n return value >= predicate\n },\n '<': function (value, predicate) {\n return value < predicate\n },\n '<=': function (value, predicate) {\n return value <= predicate\n },\n 'isectEmpty': function (value, predicate) {\n return !utils.intersection((value || []), (predicate || [])).length\n },\n 'isectNotEmpty': function (value, predicate) {\n return utils.intersection((value || []), (predicate || [])).length\n },\n 'in': function (value, predicate) {\n return predicate.indexOf(value) !== -1\n },\n 'notIn': function (value, predicate) {\n return predicate.indexOf(value) === -1\n },\n 'contains': function (value, predicate) {\n return (value || []).indexOf(predicate) !== -1\n },\n 'notContains': function (value, predicate) {\n return (value || []).indexOf(predicate) === -1\n }\n }\n})\n\n/**\n * Create a subclass of this Query:\n * @example Query.extend\n * // Normally you would do: import {Query} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Query} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomQueryClass extends Query {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customQuery = new CustomQueryClass()\n * console.log(customQuery.foo())\n * console.log(CustomQueryClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherQueryClass = Query.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherQuery = new OtherQueryClass()\n * console.log(otherQuery.foo())\n * console.log(OtherQueryClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherQueryClass (collection) {\n * Query.call(this, collection)\n * this.created_at = new Date().getTime()\n * }\n * Query.extend({\n * constructor: AnotherQueryClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherQuery = new AnotherQueryClass()\n * console.log(anotherQuery.created_at)\n * console.log(anotherQuery.foo())\n * console.log(AnotherQueryClass.beep())\n *\n * @method Query.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Query class.\n * @since 3.0.0\n */\n","export function sort (a, b, hashCode) {\n // Short-circuit comparison if a and b are strictly equal\n // This is absolutely necessary for indexed objects that\n // don't have the idAttribute field\n if (a === b) {\n return 0\n }\n if (hashCode) {\n a = hashCode(a)\n b = hashCode(b)\n }\n if ((a === null && b === null) || (a === undefined && b === undefined)) {\n return -1\n }\n\n if (a === null || a === undefined) {\n return -1\n }\n\n if (b === null || b === undefined) {\n return 1\n }\n\n if (a < b) {\n return -1\n }\n\n if (a > b) {\n return 1\n }\n\n return 0\n}\n\nexport function insertAt (array, index, value) {\n array.splice(index, 0, value)\n return array\n}\n\nexport function removeAt (array, index) {\n array.splice(index, 1)\n return array\n}\n\nexport function binarySearch (array, value, field) {\n let lo = 0\n let hi = array.length\n let compared\n let mid\n\n while (lo < hi) {\n mid = ((lo + hi) / 2) | 0\n compared = sort(value, array[mid], field)\n if (compared === 0) {\n return {\n found: true,\n index: mid\n }\n } else if (compared < 0) {\n hi = mid\n } else {\n lo = mid + 1\n }\n }\n\n return {\n found: false,\n index: hi\n }\n}\n","// Copyright (c) 2015, InternalFX.\n\n// Permission to use, copy, modify, and/or distribute this software for any purpose with or\n// without fee is hereby granted, provided that the above copyright notice and this permission\n// notice appear in all copies.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO\n// THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT\n// SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR\n// ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION\n// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE\n// USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// Modifications\n// Copyright 2015-2016 Jason Dobry\n//\n// Summary of modifications:\n// Reworked dependencies so as to re-use code already in js-data\n// Removed unused code\nimport utils from '../../src/utils'\nimport {binarySearch, insertAt, removeAt} from './_utils'\n\nexport default function Index (fieldList, opts) {\n utils.classCallCheck(this, Index)\n fieldList || (fieldList = [])\n\n if (!utils.isArray(fieldList)) {\n throw new Error('fieldList must be an array.')\n }\n\n opts || (opts = {})\n this.fieldList = fieldList\n this.fieldGetter = opts.fieldGetter\n this.hashCode = opts.hashCode\n this.isIndex = true\n this.keys = []\n this.values = []\n}\n\nutils.addHiddenPropsToTarget(Index.prototype, {\n 'set' (keyList, value) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n let dataLocation = binarySearch(this.values[pos.index], value, this.hashCode)\n if (!dataLocation.found) {\n insertAt(this.values[pos.index], dataLocation.index, value)\n }\n } else {\n insertAt(this.keys, pos.index, key)\n insertAt(this.values, pos.index, [value])\n }\n } else {\n if (pos.found) {\n this.values[pos.index].set(keyList, value)\n } else {\n insertAt(this.keys, pos.index, key)\n let newIndex = new Index([], { hashCode: this.hashCode })\n newIndex.set(keyList, value)\n insertAt(this.values, pos.index, newIndex)\n }\n }\n },\n\n 'get' (keyList) {\n if (!utils.isArray(keyList)) {\n keyList = [keyList]\n }\n\n let key = keyList.shift() || undefined\n let pos = binarySearch(this.keys, key)\n\n if (keyList.length === 0) {\n if (pos.found) {\n if (this.values[pos.index].isIndex) {\n return this.values[pos.index].getAll()\n } else {\n return this.values[pos.index].slice()\n }\n } else {\n return []\n }\n } else {\n if (pos.found) {\n return this.values[pos.index].get(keyList)\n } else {\n return []\n }\n }\n },\n\n getAll (opts) {\n opts || (opts = {})\n let results = []\n const values = this.values\n if (opts.order === 'desc') {\n for (let i = values.length - 1; i >= 0; i--) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n } else {\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n if (value.isIndex) {\n results = results.concat(value.getAll(opts))\n } else {\n results = results.concat(value)\n }\n }\n }\n return results\n },\n\n visitAll (cb, thisArg) {\n this.values.forEach(function (value) {\n if (value.isIndex) {\n value.visitAll(cb, thisArg)\n } else {\n value.forEach(cb, thisArg)\n }\n })\n },\n\n between (leftKeys, rightKeys, opts) {\n opts || (opts = {})\n if (!utils.isArray(leftKeys)) {\n leftKeys = [leftKeys]\n }\n if (!utils.isArray(rightKeys)) {\n rightKeys = [rightKeys]\n }\n utils.fillIn(opts, {\n leftInclusive: true,\n rightInclusive: false,\n limit: undefined,\n offset: 0\n })\n\n let results = this._between(leftKeys, rightKeys, opts)\n\n if (opts.limit) {\n return results.slice(opts.offset, opts.limit + opts.offset)\n } else {\n return results.slice(opts.offset)\n }\n },\n\n _between (leftKeys, rightKeys, opts) {\n let results = []\n\n let leftKey = leftKeys.shift()\n let rightKey = rightKeys.shift()\n\n let pos\n\n if (leftKey !== undefined) {\n pos = binarySearch(this.keys, leftKey)\n } else {\n pos = {\n found: false,\n index: 0\n }\n }\n\n if (leftKeys.length === 0) {\n if (pos.found && opts.leftInclusive === false) {\n pos.index += 1\n }\n\n for (let i = pos.index; i < this.keys.length; i += 1) {\n if (rightKey !== undefined) {\n if (opts.rightInclusive) {\n if (this.keys[i] > rightKey) { break }\n } else {\n if (this.keys[i] >= rightKey) { break }\n }\n }\n\n if (this.values[i].isIndex) {\n results = results.concat(this.values[i].getAll())\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n } else {\n for (let i = pos.index; i < this.keys.length; i += 1) {\n let currKey = this.keys[i]\n if (currKey > rightKey) { break }\n\n if (this.values[i].isIndex) {\n if (currKey === leftKey) {\n results = results.concat(this.values[i]._between(utils.copy(leftKeys), rightKeys.map(function () { return undefined }), opts))\n } else if (currKey === rightKey) {\n results = results.concat(this.values[i]._between(leftKeys.map(function () { return undefined }), utils.copy(rightKeys), opts))\n } else {\n results = results.concat(this.values[i].getAll())\n }\n } else {\n results = results.concat(this.values[i])\n }\n\n if (opts.limit) {\n if (results.length >= (opts.limit + opts.offset)) {\n break\n }\n }\n }\n }\n\n if (opts.limit) {\n return results.slice(0, opts.limit + opts.offset)\n } else {\n return results\n }\n },\n\n peek () {\n if (this.values.length) {\n if (this.values[0].isIndex) {\n return this.values[0].peek()\n } else {\n return this.values[0]\n }\n }\n return []\n },\n\n clear () {\n this.keys = []\n this.values = []\n },\n\n insertRecord (data) {\n let keyList = this.fieldList.map(function (field) {\n if (utils.isFunction(field)) {\n return field(data) || undefined\n } else {\n return data[field] || undefined\n }\n })\n this.set(keyList, data)\n },\n\n removeRecord (data) {\n let removed\n const isUnique = this.hashCode(data) !== undefined\n this.values.forEach((value, i) => {\n if (value.isIndex) {\n if (value.removeRecord(data)) {\n if (value.keys.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n } else {\n let dataLocation = {}\n if (this.keys[i] === undefined || !isUnique) {\n for (let j = value.length - 1; j >= 0; j--) {\n if (value[j] === data) {\n dataLocation = {\n found: true,\n index: j\n }\n break\n }\n }\n } else if (isUnique) {\n dataLocation = binarySearch(value, data, this.hashCode)\n }\n if (dataLocation.found) {\n removeAt(value, dataLocation.index)\n if (value.length === 0) {\n removeAt(this.keys, i)\n removeAt(this.values, i)\n }\n removed = true\n return false\n }\n }\n })\n return removed ? data : undefined\n },\n\n updateRecord (data) {\n const removed = this.removeRecord(data)\n if (removed !== undefined) {\n this.insertRecord(data)\n }\n }\n})\n","import utils from './utils'\nimport Component from './Component'\nimport Query from './Query'\nimport Index from '../lib/mindex/index'\n\nconst DOMAIN = 'Collection'\n\nconst COLLECTION_DEFAULTS = {\n /**\n * Whether to call {@link Record#commit} on records that are added to the\n * collection and already exist in the collection.\n *\n * @name Collection#commitOnMerge\n * @type {boolean}\n * @default true\n */\n commitOnMerge: true,\n\n /**\n * Field to be used as the unique identifier for records in this collection.\n * Defaults to `\"id\"` unless {@link Collection#mapper} is set, in which case\n * this will default to {@link Mapper#idAttribute}.\n *\n * @name Collection#idAttribute\n * @type {string}\n * @default \"id\"\n */\n idAttribute: 'id',\n\n /**\n * What to do when inserting a record into this Collection that shares a\n * primary key with a record already in this Collection.\n *\n * Possible values:\n * merge\n * replace\n *\n * Merge:\n *\n * Recursively shallow copy properties from the new record onto the existing\n * record.\n *\n * Replace:\n *\n * Shallow copy top-level properties from the new record onto the existing\n * record. Any top-level own properties of the existing record that are _not_\n * on the new record will be removed.\n *\n * @name Collection#onConflict\n * @type {string}\n * @default \"merge\"\n */\n onConflict: 'merge'\n}\n\n/**\n * An ordered set of {@link Record} instances.\n *\n * @example Collection#constructor\n * // import {Collection, Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const user1 = new Record({ id: 1 })\n * const user2 = new Record({ id: 2 })\n * const UserCollection = new Collection([user1, user2])\n * console.log(UserCollection.get(1) === user1)\n *\n * @class Collection\n * @extends Component\n * @param {Array} [records] Initial set of records to insert into the\n * collection.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.commitOnMerge] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.idAttribute] See {@link Collection#idAttribute}.\n * @param {string} [opts.onConflict=\"merge\"] See {@link Collection#onConflict}.\n * @param {string} [opts.mapper] See {@link Collection#mapper}.\n * @since 3.0.0\n */\nfunction Collection (records, opts) {\n utils.classCallCheck(this, Collection)\n Component.call(this, opts)\n\n if (records && !utils.isArray(records)) {\n opts = records\n records = []\n }\n if (utils.isString(opts)) {\n opts = { idAttribute: opts }\n }\n\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * Default Mapper for this collection. Optional. If a Mapper is provided, then\n * the collection will use the {@link Mapper#idAttribute} setting, and will\n * wrap records in {@link Mapper#recordClass}.\n *\n * @example Collection#mapper\n * // Normally you would do: import {Collection, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection, Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const myMapper = new MyMapperClass({ name: 'myMapper' })\n * const collection = new Collection(null, { mapper: myMapper })\n *\n * @name Collection#mapper\n * @type {Mapper}\n * @default null\n * @since 3.0.0\n */\n mapper: {\n value: undefined,\n writable: true\n },\n // Query class used by this collection\n queryClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(COLLECTION_DEFAULTS))\n\n if (!this.queryClass) {\n this.queryClass = Query\n }\n\n const idAttribute = this.recordId()\n\n Object.defineProperties(this, {\n /**\n * The main index, which uses @{link Collection#recordId} as the key.\n *\n * @name Collection#index\n * @type {Index}\n */\n index: {\n value: new Index([idAttribute], {\n hashCode (obj) {\n return utils.get(obj, idAttribute)\n }\n })\n },\n\n /**\n * Object that holds the secondary indexes of this collection.\n *\n * @name Collection#indexes\n * @type {Object.}\n */\n indexes: {\n value: {}\n }\n })\n\n // Insert initial data into the collection\n if (utils.isObject(records) || (utils.isArray(records) && records.length)) {\n this.add(records)\n }\n}\n\nexport default Component.extend({\n constructor: Collection,\n\n /**\n * Used to bind to events emitted by records in this Collection.\n *\n * @method Collection#_onRecordEvent\n * @since 3.0.0\n * @private\n * @param {...*} [arg] Args passed to {@link Collection#emit}.\n */\n _onRecordEvent (...args) {\n this.emit(...args)\n },\n\n /**\n * Insert the provided record or records.\n *\n * If a record is already in the collection then the provided record will\n * either merge with or replace the existing record based on the value of the\n * `onConflict` option.\n *\n * The collection's secondary indexes will be updated as each record is\n * visited.\n *\n * @method Collection#add\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} data The record or records to insert.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}.\n * @param {string} [opts.onConflict] See {@link Collection#onConflict}.\n * @returns {(Object|Object[]|Record|Record[])} The added record or records.\n */\n add (records, opts) {\n // Default values for arguments\n opts || (opts = {})\n\n // Fill in \"opts\" with the Collection's configuration\n utils._(opts, this)\n records = this.beforeAdd(records, opts) || records\n\n // Track whether just one record or an array of records is being inserted\n let singular = false\n const idAttribute = this.recordId()\n if (!utils.isArray(records)) {\n if (utils.isObject(records)) {\n records = [records]\n singular = true\n } else {\n throw utils.err(`${DOMAIN}#add`, 'records')(400, 'object or array', records)\n }\n }\n\n // Map the provided records to existing records.\n // New records will be inserted. If any records map to existing records,\n // they will be merged into the existing records according to the onConflict\n // option.\n records = records.map((record) => {\n let id = this.recordId(record)\n // Grab existing record if there is one\n const existing = id === undefined ? id : this.get(id)\n // If the currently visited record is just a reference to an existing\n // record, then there is nothing to be done. Exit early.\n if (record === existing) {\n return existing\n }\n\n if (existing) {\n // Here, the currently visited record corresponds to a record already\n // in the collection, so we need to merge them\n const onConflict = opts.onConflict || this.onConflict\n if (onConflict === 'merge') {\n utils.deepMixIn(existing, record)\n } else if (onConflict === 'replace') {\n utils.forOwn(existing, (value, key) => {\n if (key !== idAttribute && record[key] === undefined) {\n existing[key] = undefined\n }\n })\n existing.set(record)\n } else {\n throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)\n }\n record = existing\n if (opts.commitOnMerge && utils.isFunction(record.commit)) {\n record.commit()\n }\n // Update all indexes in the collection\n this.updateIndexes(record)\n } else {\n // Here, the currently visted record does not correspond to any record\n // in the collection, so (optionally) instantiate this record and insert\n // it into the collection\n record = this.mapper ? this.mapper.createRecord(record, opts) : record\n this.index.insertRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.insertRecord(record)\n })\n if (record && utils.isFunction(record.on)) {\n record.on('all', this._onRecordEvent, this)\n }\n }\n return record\n })\n // Finally, return the inserted data\n const result = singular ? records[0] : records\n this.emit('add', result)\n return this.afterAdd(records, opts, result) || result\n },\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then {@link Collection#add} will return that same value.\n *\n * @method Collection#method\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} result The record or records\n * that were added to this Collection by {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n afterAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}. If this method returns\n * a value then {@link Collection#remove} will return that same value.\n *\n * @method Collection#afterRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n * @param {Object} record The result that will be returned by {@link Collection#remove}.\n */\n afterRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}. If this method\n * returns a value then {@link Collection#removeAll} will return that same\n * value.\n *\n * @method Collection#afterRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n * @param {Object} records The result that will be returned by {@link Collection#removeAll}.\n */\n afterRemoveAll () {},\n\n /**\n * Lifecycle hook called by {@link Collection#add}. If this method returns a\n * value then the `records` argument in {@link Collection#add} will be\n * re-assigned to the returned value.\n *\n * @method Collection#beforeAdd\n * @since 3.0.0\n * @param {(Object|Object[]|Record|Record[])} records The `records` argument passed to {@link Collection#add}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#add}.\n */\n beforeAdd () {},\n\n /**\n * Lifecycle hook called by {@link Collection#remove}.\n *\n * @method Collection#beforeRemove\n * @since 3.0.0\n * @param {(string|number)} id The `id` argument passed to {@link Collection#remove}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#remove}.\n */\n beforeRemove () {},\n\n /**\n * Lifecycle hook called by {@link Collection#removeAll}.\n *\n * @method Collection#beforeRemoveAll\n * @since 3.0.0\n * @param {Object} query The `query` argument passed to {@link Collection#removeAll}.\n * @param {Object} opts The `opts` argument passed to {@link Collection#removeAll}.\n */\n beforeRemoveAll () {},\n\n /**\n * Find all records between two boundaries.\n *\n * Shortcut for `collection.query().between(18, 30, { index: 'age' }).run()`\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = collection.between(18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = collection.between([18], [30], { index: 'age' })\n *\n * @method Collection#between\n * @since 3.0.0\n * @param {Array} leftKeys Keys defining the left boundary.\n * @param {Array} rightKeys Keys defining the right boundary.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @param {boolean} [opts.leftInclusive=true] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.rightInclusive=false] Whether to include records\n * on the left boundary.\n * @param {boolean} [opts.limit] Limit the result to a certain number.\n * @param {boolean} [opts.offset] The number of resulting records to skip.\n * @returns {Object[]|Record[]} The result.\n */\n between (leftKeys, rightKeys, opts) {\n return this.query().between(leftKeys, rightKeys, opts).run()\n },\n\n /**\n * Create a new secondary index on the contents of the collection.\n *\n * @example\n * // Index users by age\n * collection.createIndex('age')\n *\n * @example\n * // Index users by status and role\n * collection.createIndex('statusAndRole', ['status', 'role'])\n *\n * @method Collection#createIndex\n * @since 3.0.0\n * @param {string} name The name of the new secondary index.\n * @param {string[]} [fieldList] Array of field names to use as the key or\n * compound key of the new secondary index. If no fieldList is provided, then\n * the name will also be the field that is used to index the collection.\n */\n createIndex (name, fieldList, opts) {\n if (utils.isString(name) && fieldList === undefined) {\n fieldList = [name]\n }\n opts || (opts = {})\n opts.hashCode || (opts.hashCode = (obj) => this.recordId(obj))\n const index = this.indexes[name] = new Index(fieldList, opts)\n this.index.visitAll(index.insertRecord, index)\n },\n\n /**\n * Find the record or records that match the provided query or pass the\n * provided filter function.\n *\n * Shortcut for `collection.query().filter(queryOrFn[, thisArg]).run()`\n *\n * @example Collection#filter\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const collection = new Collection([\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = collection.filter({\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = collection.filter(function (post) {\n * return post.id % 2 === 0\n * })\n *\n * @method Collection#filter\n * @param {(Object|Function)} [queryOrFn={}] Selection query or filter\n * function.\n * @param {Object} [thisArg] Context to which to bind `queryOrFn` if\n * `queryOrFn` is a function.\n * @returns {Array} The result.\n * @see query\n * @since 3.0.0\n */\n filter (query, thisArg) {\n return this.query().filter(query, thisArg).run()\n },\n\n /**\n * Iterate over all records.\n *\n * @example\n * collection.forEach(function (record) {\n * // do something\n * })\n *\n * @method Collection#forEach\n * @since 3.0.0\n * @param {Function} forEachFn Iteration function.\n * @param {*} [thisArg] Context to which to bind `forEachFn`.\n * @returns {Array} The result.\n */\n forEach (cb, thisArg) {\n this.index.visitAll(cb, thisArg)\n },\n\n /**\n * Get the record with the given id.\n *\n * @method Collection#get\n * @since 3.0.0\n * @param {(string|number)} id The primary key of the record to get.\n * @returns {(Object|Record)} The record with the given id.\n */\n get (id) {\n const instances = this.query().get(id).run()\n return instances.length ? instances[0] : undefined\n },\n\n /**\n * Find the record or records that match the provided keyLists.\n *\n * Shortcut for `collection.query().getAll(keyList1, keyList2, ...).run()`\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = collection.getAll('draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = collection.getAll(['draft'], ['inReview'], { index: 'status' })\n *\n * @method Collection#getAll\n * @since 3.0.0\n * @param {...Array} [keyList] Provide one or more keyLists, and all\n * records matching each keyList will be retrieved. If no keyLists are\n * provided, all records will be returned.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] Name of the secondary index to use in the\n * query. If no index is specified, the main index is used.\n * @returns {Array} The result.\n */\n getAll (...args) {\n return this.query().getAll(...args).run()\n },\n\n /**\n * Return the index with the given name. If no name is provided, return the\n * main index. Throws an error if the specified index does not exist.\n *\n * @method Collection#getIndex\n * @since 3.0.0\n * @param {string} [name] The name of the index to retrieve.\n */\n getIndex (name) {\n const index = name ? this.indexes[name] : this.index\n if (!index) {\n throw utils.err(`${DOMAIN}#getIndex`, name)(404, 'index')\n }\n return index\n },\n\n /**\n * Limit the result.\n *\n * Shortcut for `collection.query().limit(maximumNumber).run()`\n *\n * @example\n * const posts = collection.limit(10)\n *\n * @method Collection#limit\n * @since 3.0.0\n * @param {number} num The maximum number of records to keep in the result.\n * @returns {Array} The result.\n */\n limit (num) {\n return this.query().limit(num).run()\n },\n\n /**\n * Apply a mapping function to all records.\n *\n * @example\n * const names = collection.map(function (user) {\n * return user.name\n * })\n *\n * @method Collection#map\n * @since 3.0.0\n * @param {Function} mapFn Mapping function.\n * @param {*} [thisArg] Context to which to bind `mapFn`.\n * @returns {Array} The result of the mapping.\n */\n map (cb, thisArg) {\n const data = []\n this.index.visitAll(function (value) {\n data.push(cb.call(thisArg, value))\n })\n return data\n },\n\n /**\n * Return the result of calling the specified function on each record in this\n * collection's main index.\n *\n * @method Collection#mapCall\n * @since 3.0.0\n * @param {string} funcName Name of function to call\n * @parama {...*} [args] Remaining arguments to be passed to the function.\n * @returns {Array} The result.\n */\n mapCall (funcName, ...args) {\n const data = []\n this.index.visitAll(function (record) {\n data.push(record[funcName](...args))\n })\n return data\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#prune\n * @param {Object} [opts] Configuration options, passed to {@link Collection#removeAll}.\n * @since 3.0.0\n * @returns {Array} The removed records, if any.\n */\n prune (opts) {\n return this.removeAll(this.unsaved(), opts)\n },\n\n /**\n * Create a new query to be executed against the contents of the collection.\n * The result will be all or a subset of the contents of the collection.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * collection.query()\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method Collection#query\n * @since 3.0.0\n * @returns {Query} New query object.\n */\n query () {\n const Ctor = this.queryClass\n return new Ctor(this)\n },\n\n /**\n * Return the primary key of the given, or if no record is provided, return the\n * name of the field that holds the primary key of records in this Collection.\n *\n * @method Collection#recordId\n * @since 3.0.0\n * @param {(Object|Record)} [record] The record whose primary key is to be\n * returned.\n * @returns {(string|number)} Primary key or name of field that holds primary\n * key.\n */\n recordId (record) {\n if (record) {\n return utils.get(record, this.recordId())\n }\n return this.mapper ? this.mapper.idAttribute : this.idAttribute\n },\n\n /**\n * Reduce the data in the collection to a single value and return the result.\n *\n * @example\n * const totalVotes = collection.reduce(function (prev, record) {\n * return prev + record.upVotes + record.downVotes\n * }, 0)\n *\n * @method Collection#reduce\n * @since 3.0.0\n * @param {Function} cb Reduction callback.\n * @param {*} initialValue Initial value of the reduction.\n * @returns {*} The result.\n */\n reduce (cb, initialValue) {\n const data = this.getAll()\n return data.reduce(cb, initialValue)\n },\n\n /**\n * Remove the record with the given id from this Collection.\n *\n * @method Collection#remove\n * @since 3.0.0\n * @param {(string|number|object|Record)} idOrRecord The primary key of the\n * record to be removed, or a reference to the record that is to be removed.\n * @param {Object} [opts] Configuration options.\n * @returns {Object|Record} The removed record, if any.\n */\n remove (idOrRecord, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemove(idOrRecord, opts)\n let record = utils.isSorN(idOrRecord) ? this.get(idOrRecord) : idOrRecord\n\n // The record is in the collection, remove it\n if (utils.isObject(record)) {\n record = this.index.removeRecord(record)\n if (record) {\n utils.forOwn(this.indexes, function (index, name) {\n index.removeRecord(record)\n })\n if (utils.isFunction(record.off)) {\n record.off('all', this._onRecordEvent, this)\n if (!opts.silent) {\n this.emit('remove', record)\n }\n }\n }\n }\n return this.afterRemove(idOrRecord, opts, record) || record\n },\n\n /**\n * Remove from this collection the given records or the records selected by\n * the given \"query\".\n *\n * @method Collection#removeAll\n * @since 3.0.0\n * @param {Object|Object[]|Record[]} [queryOrRecords={}] Records to be removed or selection query. See {@link query}.\n * @param {Object} [queryOrRecords.where] See {@link query.where}.\n * @param {number} [queryOrRecords.offset] See {@link query.offset}.\n * @param {number} [queryOrRecords.limit] See {@link query.limit}.\n * @param {string|Array[]} [queryOrRecords.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object[]|Record[])} The removed records, if any.\n */\n removeAll (queryOrRecords, opts) {\n // Default values for arguments\n opts || (opts = {})\n this.beforeRemoveAll(queryOrRecords, opts)\n let records = utils.isArray(queryOrRecords) ? queryOrRecords.slice() : this.filter(queryOrRecords)\n\n // Remove each selected record from the collection\n const optsCopy = utils.plainCopy(opts)\n optsCopy.silent = true\n records = records\n .map((record) => this.remove(record, optsCopy))\n .filter((record) => record)\n if (!opts.silent) {\n this.emit('remove', records)\n }\n return this.afterRemoveAll(queryOrRecords, opts, records) || records\n },\n\n /**\n * Skip a number of results.\n *\n * Shortcut for `collection.query().skip(numberToSkip).run()`\n *\n * @example\n * const posts = collection.skip(10)\n *\n * @method Collection#skip\n * @since 3.0.0\n * @param {number} num The number of records to skip.\n * @returns {Array} The result.\n */\n skip (num) {\n return this.query().skip(num).run()\n },\n\n /**\n * Return the plain JSON representation of all items in this collection.\n * Assumes records in this collection have a toJSON method.\n *\n * @method Collection#toJSON\n * @since 3.0.0\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation.\n * @returns {Array} The records.\n */\n toJSON (opts) {\n return this.mapCall('toJSON', opts)\n },\n\n /**\n * Return all \"unsaved\" (not uniquely identifiable) records in this colleciton.\n *\n * @method Collection#unsaved\n * @since 3.0.0\n * @returns {Array} The unsaved records, if any.\n */\n unsaved (opts) {\n return this.index.get()\n },\n\n /**\n * Update a record's position in a single index of this collection. See\n * {@link Collection#updateIndexes} to update a record's position in all\n * indexes at once.\n *\n * @method Collection#updateIndex\n * @since 3.0.0\n * @param {Object} record The record to update.\n * @param {Object} [opts] Configuration options.\n * @param {string} [opts.index] The index in which to update the record's\n * position. If you don't specify an index then the record will be updated\n * in the main index.\n */\n updateIndex (record, opts) {\n opts || (opts = {})\n this.getIndex(opts.index).updateRecord(record)\n },\n\n /**\n * Updates all indexes in this collection for the provided record. Has no\n * effect if the record is not in the collection.\n *\n * @method Collection#updateIndexes\n * @since 3.0.0\n * @param {Object} record TODO\n */\n updateIndexes (record) {\n this.index.updateRecord(record)\n utils.forOwn(this.indexes, function (index, name) {\n index.updateRecord(record)\n })\n }\n})\n\n/**\n * Fired when a record changes. Only works for records that have tracked changes.\n * See {@link Collection~changeListener} on how to listen for this event.\n *\n * @event Collection#change\n * @see Collection~changeListener\n */\n\n/**\n * Callback signature for the {@link Collection#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * collection.on('change', onChange)\n *\n * @callback Collection~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Collection#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the Collection. See\n * {@link Collection~addListener} on how to listen for this event.\n *\n * @event Collection#add\n * @see Collection~addListener\n * @see Collection#event:add\n * @see Collection#add\n */\n\n/**\n * Callback signature for the {@link Collection#event:add} event.\n *\n * @example\n * function onAdd (recordOrRecords) {\n * // do something\n * }\n * collection.on('add', onAdd)\n *\n * @callback Collection~addListener\n * @param {Record|Record[]} The Record or Records that were added.\n * @see Collection#event:add\n * @see Collection#add\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the Collection. See\n * {@link Collection~removeListener} for how to listen for this event.\n *\n * @event Collection#remove\n * @see Collection~removeListener\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n */\n\n/**\n * Callback signature for the {@link Collection#event:remove} event.\n *\n * @example\n * function onRemove (recordsOrRecords) {\n * // do something\n * }\n * collection.on('remove', onRemove)\n *\n * @callback Collection~removeListener\n * @param {Record|Record[]} Record or Records that were removed.\n * @see Collection#event:remove\n * @see Collection#remove\n * @see Collection#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Collection:\n * @example Collection.extend\n * // Normally you would do: import {Collection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Collection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomCollectionClass extends Collection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customCollection = new CustomCollectionClass()\n * console.log(customCollection.foo())\n * console.log(CustomCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherCollectionClass = Collection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherCollection = new OtherCollectionClass()\n * console.log(otherCollection.foo())\n * console.log(OtherCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherCollectionClass () {\n * Collection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Collection.extend({\n * constructor: AnotherCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherCollection = new AnotherCollectionClass()\n * console.log(anotherCollection.created_at)\n * console.log(anotherCollection.foo())\n * console.log(AnotherCollectionClass.beep())\n *\n * @method Collection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Collection class.\n * @since 3.0.0\n */\n","import utils from './utils'\n\n// TODO: remove this when the rest of the project is cleaned\nexport const belongsToType = 'belongsTo'\nexport const hasManyType = 'hasMany'\nexport const hasOneType = 'hasOne'\n\nconst DOMAIN = 'Relation'\n\nexport function Relation (relatedMapper, options = {}) {\n utils.classCallCheck(this, Relation)\n\n options.type = this.constructor.TYPE_NAME\n this.validateOptions(relatedMapper, options)\n\n if (typeof relatedMapper === 'object') {\n Object.defineProperty(this, 'relatedMapper', { value: relatedMapper })\n }\n\n Object.defineProperty(this, 'inverse', { writable: true })\n utils.fillIn(this, options)\n}\n\nRelation.extend = utils.extend\n\nutils.addHiddenPropsToTarget(Relation.prototype, {\n get canAutoAddLinks () {\n return this.add === undefined || !!this.add\n },\n\n get relatedCollection () {\n return this.mapper.datastore.getCollection(this.relation)\n },\n\n validateOptions (related, opts) {\n const DOMAIN_ERR = `new ${DOMAIN}`\n\n const localField = opts.localField\n if (!localField) {\n throw utils.err(DOMAIN_ERR, 'opts.localField')(400, 'string', localField)\n }\n\n const foreignKey = opts.foreignKey = opts.foreignKey || opts.localKey\n if (!foreignKey && (opts.type === belongsToType || opts.type === hasOneType)) {\n throw utils.err(DOMAIN_ERR, 'opts.foreignKey')(400, 'string', foreignKey)\n }\n\n if (utils.isString(related)) {\n opts.relation = related\n if (!utils.isFunction(opts.getRelation)) {\n throw utils.err(DOMAIN_ERR, 'opts.getRelation')(400, 'function', opts.getRelation)\n }\n } else if (related) {\n opts.relation = related.name\n } else {\n throw utils.err(DOMAIN_ERR, 'related')(400, 'Mapper or string', related)\n }\n },\n\n assignTo (mapper) {\n this.name = mapper.name\n Object.defineProperty(this, 'mapper', { value: mapper })\n\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n mapper.relationFields || Object.defineProperty(mapper, 'relationFields', { value: [] })\n mapper.relationList.push(this)\n mapper.relationFields.push(this.localField)\n },\n\n canFindLinkFor () {\n return !!(this.foreignKey || this.localKey)\n },\n\n getRelation () {\n return this.relatedMapper\n },\n\n getForeignKey (record) {\n return utils.get(record, this.mapper.idAttribute)\n },\n\n setForeignKey (record, relatedRecord) {\n if (!record || !relatedRecord) {\n return\n }\n\n this._setForeignKey(record, relatedRecord)\n },\n\n _setForeignKey (record, relatedRecords) {\n const idAttribute = this.mapper.idAttribute\n\n if (!utils.isArray(relatedRecords)) {\n relatedRecords = [relatedRecords]\n }\n\n relatedRecords.forEach((relatedRecord) => {\n utils.set(relatedRecord, this.foreignKey, utils.get(record, idAttribute))\n })\n },\n\n getLocalField (record) {\n return utils.get(record, this.localField)\n },\n\n setLocalField (record, relatedData) {\n return utils.set(record, this.localField, relatedData)\n },\n\n getInverse (mapper) {\n if (!this.inverse) {\n this.findInverseRelation(mapper)\n }\n\n return this.inverse\n },\n\n findInverseRelation (mapper) {\n this.getRelation().relationList.forEach((def) => {\n if (def.getRelation() === mapper && this.isInversedTo(def)) {\n this.inverse = def\n return true\n }\n })\n },\n\n isInversedTo (def) {\n return !def.foreignKey || def.foreignKey === this.foreignKey\n },\n\n addLinkedRecords (records) {\n const datastore = this.mapper.datastore\n\n records.forEach((record) => {\n let relatedData = this.getLocalField(record)\n\n if (utils.isFunction(this.add)) {\n relatedData = this.add(datastore, this, record)\n } else if (relatedData) {\n relatedData = this.linkRecord(record, relatedData)\n }\n\n const isEmptyLinks = !relatedData || utils.isArray(relatedData) && !relatedData.length\n\n if (isEmptyLinks && this.canFindLinkFor(record)) {\n relatedData = this.findExistingLinksFor(record)\n }\n\n if (relatedData) {\n this.setLocalField(record, relatedData)\n }\n })\n },\n\n removeLinkedRecords (relatedMapper, records) {\n const localField = this.localField\n records.forEach((record) => {\n utils.set(record, localField, undefined)\n })\n },\n\n linkRecord (record, relatedRecord) {\n const relatedId = utils.get(relatedRecord, this.mapper.idAttribute)\n\n if (relatedId === undefined) {\n const unsaved = this.relatedCollection.unsaved()\n if (unsaved.indexOf(relatedRecord) === -1) {\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n } else {\n if (relatedRecord !== this.relatedCollection.get(relatedId)) {\n this.setForeignKey(record, relatedRecord)\n\n if (this.canAutoAddLinks) {\n relatedRecord = this.relatedCollection.add(relatedRecord)\n }\n }\n }\n\n return relatedRecord\n },\n\n // e.g. user hasMany post via \"foreignKey\", so find all posts of user\n findExistingLinksByForeignKey (id) {\n if (id === undefined || id === null) {\n return\n }\n return this.relatedCollection.filter({\n [this.foreignKey]: id\n })\n }\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const BelongsToRelation = Relation.extend({\n getForeignKey (record) {\n return utils.get(record, this.foreignKey)\n },\n\n _setForeignKey (record, relatedRecord) {\n utils.set(record, this.foreignKey, utils.get(relatedRecord, this.getRelation().idAttribute))\n },\n\n findExistingLinksFor (record) {\n // console.log('\\tBelongsTo#findExistingLinksFor', record)\n if (!record) {\n return\n }\n const relatedId = utils.get(record, this.foreignKey)\n if (relatedId !== undefined && relatedId !== null) {\n return this.relatedCollection.get(relatedId)\n }\n }\n}, {\n TYPE_NAME: 'belongsTo'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasManyRelation = Relation.extend({\n validateOptions (related, opts) {\n Relation.prototype.validateOptions.call(this, related, opts)\n\n const { localKeys, foreignKeys, foreignKey } = opts\n\n if (!foreignKey && !localKeys && !foreignKeys) {\n throw utils.err('new Relation', 'opts.')(400, 'string', foreignKey)\n }\n },\n\n canFindLinkFor (record) {\n const hasForeignKeys = this.foreignKey || this.foreignKeys\n return !!(hasForeignKeys || (this.localKeys && utils.get(record, this.localKeys)))\n },\n\n linkRecord (record, relatedRecords) {\n const relatedCollection = this.relatedCollection\n const canAutoAddLinks = this.canAutoAddLinks\n const foreignKey = this.foreignKey\n const unsaved = this.relatedCollection.unsaved()\n\n return relatedRecords.map((relatedRecord) => {\n const relatedId = relatedCollection.recordId(relatedRecord)\n\n if ((relatedId === undefined && unsaved.indexOf(relatedRecord) === -1) || relatedRecord !== relatedCollection.get(relatedId)) {\n if (foreignKey) {\n // TODO: slow, could be optimized? But user loses hook\n this.setForeignKey(record, relatedRecord)\n }\n if (canAutoAddLinks) {\n relatedRecord = relatedCollection.add(relatedRecord)\n }\n }\n\n return relatedRecord\n })\n },\n\n findExistingLinksFor (record) {\n const id = utils.get(record, this.mapper.idAttribute)\n const ids = this.localKeys ? utils.get(record, this.localKeys) : null\n let records\n\n if (id !== undefined && this.foreignKey) {\n records = this.findExistingLinksByForeignKey(id)\n } else if (this.localKeys && ids) {\n records = this.findExistingLinksByLocalKeys(ids)\n } else if (id !== undefined && this.foreignKeys) {\n records = this.findExistingLinksByForeignKeys(id)\n }\n\n if (records && records.length) {\n return records\n }\n },\n\n // e.g. user hasMany group via \"foreignKeys\", so find all users of a group\n findExistingLinksByLocalKeys (ids) {\n return this.relatedCollection.filter({\n where: {\n [this.mapper.idAttribute]: {\n 'in': ids\n }\n }\n })\n },\n\n // e.g. group hasMany user via \"localKeys\", so find all groups that own a user\n findExistingLinksByForeignKeys (id) {\n return this.relatedCollection.filter({\n where: {\n [this.foreignKeys]: {\n 'contains': id\n }\n }\n })\n }\n}, {\n TYPE_NAME: 'hasMany'\n})\n","import utils from '../utils'\nimport { Relation } from '../Relation'\n\nexport const HasOneRelation = Relation.extend({\n findExistingLinksFor (relatedMapper, record) {\n const recordId = utils.get(record, relatedMapper.idAttribute)\n const records = this.findExistingLinksByForeignKey(recordId)\n\n if (records && records.length) {\n return records[0]\n }\n }\n}, {\n TYPE_NAME: 'hasOne'\n})\n","import { Relation } from './Relation'\nimport { BelongsToRelation } from './Relation/BelongsTo'\nimport { HasManyRelation } from './Relation/HasMany'\nimport { HasOneRelation } from './Relation/HasOne'\n\n[BelongsToRelation, HasManyRelation, HasOneRelation].forEach(function (RelationType) {\n Relation[RelationType.TYPE_NAME] = function (related, options) {\n return new RelationType(related, options)\n }\n})\n\nexport { belongsToType, hasManyType, hasOneType, Relation } from './Relation'\n","import { Relation } from './relations'\n\nexport { belongsToType, hasManyType, hasOneType } from './relations'\n/**\n * BelongsTo relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.belongsTo\n * @method\n * @param {Mapper} related The relation the target belongs to.\n * @param {Object} opts Configuration options.\n * @param {string} opts.foreignKey The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const belongsTo = function (related, opts) {\n return function (mapper) {\n Relation.belongsTo(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasMany relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasMany\n * @method\n * @param {Mapper} related The relation of which the target has many.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasMany = function (related, opts) {\n return function (mapper) {\n Relation.hasMany(related, opts).assignTo(mapper)\n }\n}\n\n/**\n * HasOne relation decorator. You probably won't use this directly.\n *\n * @name module:js-data.hasOne\n * @method\n * @param {Mapper} related The relation of which the target has one.\n * @param {Object} opts Configuration options.\n * @param {string} [opts.foreignKey] The field that holds the primary key of the\n * related record.\n * @param {string} opts.localField The field that holds a reference to the\n * related record object.\n * @returns {Function} Invocation function, which accepts the target as the only\n * parameter.\n */\nexport const hasOne = function (related, opts) {\n return function (mapper) {\n Relation.hasOne(related, opts).assignTo(mapper)\n }\n}\n","import utils, { safeSetLink } from './utils'\nimport Component from './Component'\nimport Settable from './Settable'\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Record'\n\nconst superMethod = function (mapper, name) {\n const store = mapper.datastore\n if (store && store[name]) {\n return function (...args) {\n return store[name](mapper.name, ...args)\n }\n }\n return mapper[name].bind(mapper)\n}\n\n/**\n * js-data's Record class. An instance of `Record` corresponds to an in-memory\n * representation of a single row or document in a database, Firebase,\n * localstorage, etc. Basically, a `Record` instance represents whatever kind of\n * entity in your persistence layer that has a primary key.\n *\n * ```javascript\n * import {Record} from 'js-data'\n * ```\n *\n * @example Record#constructor\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a plain record\n * let record = new Record()\n * console.log('record: ' + JSON.stringify(record))\n *\n * // You can supply properties on instantiation\n * record = new Record({ name: 'John' })\n * console.log('record: ' + JSON.stringify(record))\n *\n * @example Record#constructor2\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Instantiate a record that's associated with a Mapper:\n * const UserMapper = new Mapper({ name: 'user' })\n * const User = UserMapper.recordClass\n * const user = UserMapper.createRecord({ name: 'John' })\n * const user2 = new User({ name: 'Sally' })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user2: ' + JSON.stringify(user2))\n *\n * @example Record#constructor3\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n *\n * // Instantiate a record that's associated with a store's Mapper\n * const user = store.createRecord('user', { name: 'John' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor4\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Validate on instantiation\n * const user = store.createRecord('user', { name: 1234 })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @example Record#constructor5\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * // Skip validation on instantiation\n * const user = store.createRecord('user', { name: 1234 }, { noValidate: true })\n * console.log('user: ' + JSON.stringify(user))\n * console.log('user.isValid(): ' + user.isValid())\n *\n * @class Record\n * @extends Component\n * @param {Object} [props] The initial properties of the new Record instance.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate=false] Whether to skip validation on the\n * initial properties.\n * @since 3.0.0\n */\nfunction Record (props, opts) {\n utils.classCallCheck(this, Record)\n Settable.call(this)\n props || (props = {})\n opts || (opts = {})\n const _set = this._set\n // TODO: Optimize these strings\n _set('creating', true)\n if (opts.noValidate) {\n _set('noValidate', true)\n }\n // Set the idAttribute value first, if it exists.\n const mapper = this.constructor.mapper\n const id = mapper ? utils.get(props, mapper.idAttribute) : undefined\n if (id !== undefined) {\n utils.set(this, mapper.idAttribute, id)\n }\n utils.fillIn(this, props)\n _set('creating', false)\n _set('noValidate', false)\n _set('previous', utils.plainCopy(props))\n}\n\nexport default Component.extend({\n constructor: Record,\n\n /**\n * Returns the {@link Mapper} paired with this record's class, if any.\n *\n * @method Record#_mapper\n * @returns {Mapper} The {@link Mapper} paired with this record's class, if any.\n * @since 3.0.0\n */\n _mapper () {\n const mapper = this.constructor.mapper\n if (!mapper) {\n throw utils.err(`${DOMAIN}#_mapper`, '')(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Lifecycle hook.\n *\n * @method Record#afterLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n afterLoadRelations () {},\n\n /**\n * Lifecycle hook.\n *\n * @method Record#beforeLoadRelations\n * @param {string[]} relations The `relations` argument passed to {@link Record#loadRelations}.\n * @param {Object} opts The `opts` argument passed to {@link Record#loadRelations}.\n * @since 3.0.0\n */\n beforeLoadRelations () {},\n\n /**\n * Return the change history of this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @method Record#changeHistory\n * @since 3.0.0\n */\n changeHistory () {\n return (this._get('history') || []).slice()\n },\n\n /**\n * Return changes to this record since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#changes\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n * user.name = 'John'\n * console.log('user changes: ' + JSON.stringify(user.changes()))\n *\n * @method Record#changes\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {Object} Object describing the changes to this record since it was\n * instantiated or its {@link Record#commit} method was last called.\n * @since 3.0.0\n */\n changes (opts) {\n opts || (opts = {})\n return utils.diffObjects(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Make the record's current in-memory state it's only state, with any\n * previous property values being set to current values.\n *\n * @example Record#commit\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#commit\n * @since 3.0.0\n */\n commit () {\n this._set('changed') // unset\n this._set('history', []) // clear history\n this._set('previous', utils.plainCopy(this))\n },\n\n /**\n * Call {@link Mapper#destroy} using this record's primary key.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user')\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Destroy this user from the database\n * return user.destroy()\n * })\n *\n * @method Record#destroy\n * @param {Object} [opts] Configuration options passed to {@link Mapper#destroy}.\n * @returns {Promise} The result of calling {@link Mapper#destroy} with the\n * primary key of this record.\n * @since 3.0.0\n */\n destroy (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n return superMethod(mapper, 'destroy')(utils.get(this, mapper.idAttribute), opts)\n },\n\n /**\n * Return the value at the given path for this instance.\n *\n * @example Record#get\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', { name: 'Bob' })\n * console.log('user.get(\"name\"): ' + user.get('name'))\n *\n * @method Record#get\n * @param {string} key Path of value to retrieve.\n * @returns {*} Value at path.\n * @since 3.0.0\n */\n 'get' (key) {\n return utils.get(this, key)\n },\n\n /**\n * Return whether this record has changed since it was instantiated or\n * {@link Record#commit} was called.\n *\n * @example Record#hasChanges\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.name = 'John'\n * console.log('user hasChanges: ' + user.hasChanges())\n * user.commit()\n * console.log('user hasChanges: ' + user.hasChanges())\n *\n * @method Record#hasChanges\n * @param [opts] Configuration options.\n * @param {Function} [opts.equalsFn={@link utils.deepEqual}] Equality function.\n * @param {Array} [opts.ignore=[]] Array of strings or RegExp of fields to ignore.\n * @returns {boolean} Return whether the record has changed since it was\n * instantiated or since its {@link Record#commit} method was called.\n * @since 3.0.0\n */\n hasChanges (opts) {\n const quickHasChanges = !!(this._get('changed') || []).length\n return quickHasChanges || utils.areDifferent(typeof this.toJSON === 'function' ? this.toJSON(opts) : this, this._get('previous'), opts)\n },\n\n /**\n * Return whether the record is unsaved. Records that have primary keys are\n * considered \"saved\". Records without primary keys are considered \"unsaved\".\n *\n * @example Record#isNew\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * id: 1234\n * })\n * const user2 = store.createRecord('user')\n * console.log('user isNew: ' + user.isNew()) // false\n * console.log('user2 isNew: ' + user2.isNew()) // true\n *\n * @method Record#isNew\n * @returns {boolean} Whether the record is unsaved.\n * @since 3.0.0\n */\n isNew (opts) {\n return utils.get(this, this._mapper().idAttribute) === undefined\n },\n\n /**\n * Return whether the record in its current state passes validation.\n *\n * @example Record#isValid\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user isValid: ' + user.isValid())\n * user.name = 'John'\n * console.log('user isValid: ' + user.isValid())\n *\n * @method Record#isValid\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {boolean} Whether the record in its current state passes\n * validation.\n * @since 3.0.0\n */\n isValid (opts) {\n return !this._mapper().validate(this, opts)\n },\n\n removeInverseRelation(currentParent, id, inverseDef, idAttribute) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n // e.g. remove comment from otherPost.comments\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n },\n\n setupInverseRelation(record, id, inverseDef, idAttribute) {\n // Update (set) inverse relation\n if (inverseDef.type === hasOneType) {\n // e.g. someUser.profile = profile\n safeSetLink(record, inverseDef.localField, this)\n } else if (inverseDef.type === hasManyType) {\n // e.g. add comment to somePost.comments\n const children = utils.get(record, inverseDef.localField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n },\n\n /**\n * Lazy load relations of this record, to be attached to the record once their\n * loaded.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('user', {\n * relations: {\n * hasMany: {\n * post: {\n * localField: 'posts',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.defineMapper('post', {\n * relations: {\n * belongsTo: {\n * user: {\n * localField: 'user',\n * foreignKey: 'user_id'\n * }\n * }\n * }\n * })\n * store.find('user', 1234).then((user) => {\n * console.log(user.id) // 1234\n *\n * // Load the user's post relations\n * return user.loadRelations(['post'])\n * }).then((user) => {\n * console.log(user.posts) // [{...}, {...}, ...]\n * })\n *\n * @method Record#loadRelations\n * @param {string[]} [relations] List of relations to load. Can use localField\n * names or Mapper names to pick relations.\n * @param {Object} [opts] Configuration options.\n * @returns {Promise} Resolves with the record, with the loaded relations now\n * attached.\n * @since 3.0.0\n */\n loadRelations (relations, opts) {\n let op\n const mapper = this._mapper()\n\n // Default values for arguments\n relations || (relations = [])\n if (utils.isString(relations)) {\n relations = [relations]\n }\n opts || (opts = {})\n opts.with = relations\n\n // Fill in \"opts\" with the Model's configuration\n utils._(opts, mapper)\n opts.adapter = mapper.getAdapterName(opts)\n\n // beforeLoadRelations lifecycle hook\n op = opts.op = 'beforeLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'loadRelations'\n mapper.dbg(op, this, relations, opts)\n let tasks = []\n let task\n utils.forEachRelation(mapper, opts, (def, optsCopy) => {\n const relatedMapper = def.getRelation()\n optsCopy.raw = false\n if (utils.isFunction(def.load)) {\n task = def.load(mapper, def, this, opts)\n } else if (def.type === 'hasMany' || def.type === 'hasOne') {\n if (def.foreignKey) {\n task = superMethod(relatedMapper, 'findAll')({\n [def.foreignKey]: utils.get(this, mapper.idAttribute)\n }, optsCopy).then(function (relatedData) {\n if (def.type === 'hasOne') {\n return relatedData.length ? relatedData[0] : undefined\n }\n return relatedData\n })\n } else if (def.localKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [relatedMapper.idAttribute]: {\n 'in': utils.get(this, def.localKeys)\n }\n }\n })\n } else if (def.foreignKeys) {\n task = superMethod(relatedMapper, 'findAll')({\n where: {\n [def.foreignKeys]: {\n 'contains': utils.get(this, mapper.idAttribute)\n }\n }\n }, opts)\n }\n } else if (def.type === 'belongsTo') {\n const key = utils.get(this, def.foreignKey)\n if (utils.isSorN(key)) {\n task = superMethod(relatedMapper, 'find')(key, optsCopy)\n }\n }\n if (task) {\n task = task.then((relatedData) => {\n def.setLocalField(this, relatedData)\n })\n tasks.push(task)\n }\n })\n return Promise.all(tasks)\n }).then(() => {\n // afterLoadRelations lifecycle hook\n op = opts.op = 'afterLoadRelations'\n return utils.resolve(this[op](relations, opts)).then(() => this)\n })\n },\n\n /**\n * Return the properties with which this record was instantiated.\n *\n * @example Record#previous\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.name = 'Bob'\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n * user.commit()\n * console.log('user previous: ' + JSON.stringify(user.previous()))\n *\n * @method Record#previous\n * @param {string} [key] If specified, return just the initial value of the\n * given key.\n * @returns {Object} The initial properties of this record.\n * @since 3.0.0\n */\n previous (key) {\n if (key) {\n return this._get(`previous.${key}`)\n }\n return this._get('previous')\n },\n\n /**\n * Revert changes to this record back to the properties it had when it was\n * instantiated.\n *\n * @example Record#revert\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user', {\n * name: 'William'\n * })\n * console.log('user: ' + JSON.stringify(user))\n * user.name = 'Bob'\n * console.log('user: ' + JSON.stringify(user))\n * user.revert()\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#revert\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.preserve] Array of strings or Regular Expressions\n * denoting properties that should not be reverted.\n * @since 3.0.0\n */\n revert (opts) {\n const previous = this._get('previous')\n opts || (opts = {})\n opts.preserve || (opts.preserve = [])\n utils.forOwn(this, (value, key) => {\n if (key !== this._mapper().idAttribute && !previous.hasOwnProperty(key) && this.hasOwnProperty(key) && opts.preserve.indexOf(key) === -1) {\n delete this[key]\n }\n })\n utils.forOwn(previous, (value, key) => {\n if (opts.preserve.indexOf(key) === -1) {\n this[key] = value\n }\n })\n this.commit()\n },\n\n /**\n * Delegates to {@link Mapper#create} or {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n *\n * const store = new Container()\n * store.registerAdapter('rethink', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('session')\n * const session = store.createRecord('session', { topic: 'Node.js' })\n *\n * // Create a new record in the database\n * session.save().then(() => {\n * console.log(session.id) // 1234\n *\n * session.skill_level = 'beginner'\n *\n * // Update the record in the database\n * return user.save()\n * })\n *\n * @method Record#save\n * @param {Object} [opts] Configuration options. See {@link Mapper#create} and\n * {@link Mapper#update}.\n * @param {boolean} [opts.changesOnly] Equality function. Default uses `===`.\n * @param {Function} [opts.equalsFn] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @param {Array} [opts.ignore] Passed to {@link Record#changes} when\n * `opts.changesOnly` is `true`.\n * @returns {Promise} The result of calling {@link Mapper#create} or\n * {@link Mapper#update}.\n * @since 3.0.0\n */\n save (opts) {\n opts || (opts = {})\n const mapper = this._mapper()\n const id = utils.get(this, mapper.idAttribute)\n let props = this\n\n const postProcess = (result) => {\n const record = opts.raw ? result.data : result\n if (record) {\n utils.deepMixIn(this, record)\n this.commit()\n }\n return result\n }\n\n if (id === undefined) {\n return superMethod(mapper, 'create')(props, opts).then(postProcess)\n }\n if (opts.changesOnly) {\n const changes = this.changes(opts)\n props = {}\n utils.fillIn(props, changes.added)\n utils.fillIn(props, changes.changed)\n }\n return superMethod(mapper, 'update')(id, props, opts).then(postProcess)\n },\n\n /**\n * Set the value for a given key, or the values for the given keys if \"key\" is\n * an object. Triggers change events on those properties that have `track: true`\n * in {@link Mapper#schema}.\n *\n * @example Record#set\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set('name', 'Bob')\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.set({ age: 30, role: 'admin' })\n * console.log('user: ' + JSON.stringify(user))\n *\n * @fires Record#change\n * @method Record#set\n * @param {(string|Object)} key Key to set or hash of key-value pairs to set.\n * @param {*} [value] Value to set for the given key.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n 'set' (key, value, opts) {\n if (utils.isObject(key)) {\n opts = value\n }\n opts || (opts = {})\n if (opts.silent) {\n this._set('silent', true)\n }\n utils.set(this, key, value)\n if (!this._get('eventId')) {\n this._set('silent') // unset\n }\n },\n\n /**\n * Return a plain object representation of this record. If the class from\n * which this record was created has a Mapper, then {@link Mapper#toJSON} will\n * be called with this record instead.\n *\n * @example Record#toJSON\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n *\n * const user = store.createRecord('user', {\n * name: 'John',\n * $$hashKey: '1234'\n * })\n * console.log('user: ' + JSON.stringify(user.toJSON()))\n * console.log('user: ' + JSON.stringify(user.toJSON({ strict: true })))\n *\n * @method Record#toJSON\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the representation. Only available as an option if the class\n * from which this record was created has a Mapper and this record resides in\n * an instance of {@link DataStore}.\n * @returns {Object} Plain object representation of this record.\n * @since 3.0.0\n */\n toJSON (opts) {\n const mapper = this.constructor.mapper\n if (mapper) {\n return mapper.toJSON(this, opts)\n } else {\n const json = {}\n utils.forOwn(this, function (prop, key) {\n json[key] = utils.plainCopy(prop)\n })\n return json\n }\n },\n\n /**\n * Unset the value for a given key. Triggers change events on those properties\n * that have `track: true` in {@link Mapper#schema}.\n *\n * @example Record#unset\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user')\n *\n * const user = store.createRecord('user', {\n * name: 'John'\n * })\n * console.log('user: ' + JSON.stringify(user))\n *\n * user.unset('name')\n * console.log('user: ' + JSON.stringify(user))\n *\n * @method Record#unset\n * @param {string} key Key to unset.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.silent=false] Whether to trigger change events.\n * @since 3.0.0\n */\n unset (key, opts) {\n this.set(key, undefined, opts)\n },\n\n /**\n * Validate this record based on its current properties.\n *\n * @example Record#validate\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: {\n * properties: {\n * name: { type: 'string' }\n * }\n * }\n * })\n * const user = store.createRecord('user', {\n * name: 1234\n * }, {\n * noValidate: true // this allows us to put the record into an invalid state\n * })\n * console.log('user validation: ' + JSON.stringify(user.validate()))\n * user.name = 'John'\n * console.log('user validation: ' + user.validate())\n *\n * @method Record#validate\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#validate}.\n * @returns {*} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (opts) {\n return this._mapper().validate(this, opts)\n }\n})\n\n/**\n * Allow records to emit events.\n *\n * An record's registered listeners are stored in the record's private data.\n */\nutils.eventify(\n Record.prototype,\n function () {\n return this._get('events')\n },\n function (value) {\n this._set('events', value)\n }\n)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link Record~changeListener} on how to listen for this event.\n *\n * @event Record#change\n * @see Record~changeListener\n */\n\n/**\n * Callback signature for the {@link Record#event:change} event.\n *\n * @example\n * function onChange (record, changes) {\n * // do something\n * }\n * record.on('change', onChange)\n *\n * @callback Record~changeListener\n * @param {Record} The Record that changed.\n * @param {Object} The changes.\n * @see Record#event:change\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this Record:\n * @example Record.extend\n * // Normally you would do: import {Record} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Record} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomRecordClass extends Record {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customRecord = new CustomRecordClass()\n * console.log(customRecord.foo())\n * console.log(CustomRecordClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherRecordClass = Record.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherRecord = new OtherRecordClass()\n * console.log(otherRecord.foo())\n * console.log(OtherRecordClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherRecordClass () {\n * Record.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Record.extend({\n * constructor: AnotherRecordClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherRecord = new AnotherRecordClass()\n * console.log(anotherRecord.created_at)\n * console.log(anotherRecord.foo())\n * console.log(AnotherRecordClass.beep())\n *\n * @method Record.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Record class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\n\nconst DOMAIN = 'Schema'\n\n/**\n * A function map for each of the seven primitive JSON types defined by the core specification.\n * Each function will check a given value and return true or false if the value is an instance of that type.\n * ```\n * types.integer(1) // returns true\n * types.string({}) // returns false\n * ```\n * http://json-schema.org/latest/json-schema-core.html#anchor8\n * @name Schema.types\n * @type {Object}\n */\nconst types = {\n array: utils.isArray,\n boolean: utils.isBoolean,\n integer: utils.isInteger,\n 'null': utils.isNull,\n number: utils.isNumber,\n object: utils.isObject,\n string: utils.isString\n}\n\n/**\n * @ignore\n */\nconst segmentToString = function (segment, prev) {\n let str = ''\n if (segment) {\n if (utils.isNumber(segment)) {\n str += `[${segment}]`\n } else if (prev) {\n str += `.${segment}`\n } else {\n str += `${segment}`\n }\n }\n return str\n}\n\n/**\n * @ignore\n */\nconst makePath = function (opts) {\n opts || (opts = {})\n let path = ''\n const segments = opts.path || []\n segments.forEach(function (segment) {\n path += segmentToString(segment, path)\n })\n path += segmentToString(opts.prop, path)\n return path\n}\n\n/**\n * @ignore\n */\nconst makeError = function (actual, expected, opts) {\n return {\n expected,\n actual: '' + actual,\n path: makePath(opts)\n }\n}\n\n/**\n * @ignore\n */\nconst addError = function (actual, expected, opts, errors) {\n errors.push(makeError(actual, expected, opts))\n}\n\n/**\n * @ignore\n */\nconst maxLengthCommon = function (keyword, value, schema, opts) {\n const max = schema[keyword]\n if (value.length > max) {\n return makeError(value.length, `length no more than ${max}`, opts)\n }\n}\n\n/**\n * @ignore\n */\nconst minLengthCommon = function (keyword, value, schema, opts) {\n const min = schema[keyword]\n if (value.length < min) {\n return makeError(value.length, `length no less than ${min}`, opts)\n }\n}\n\n/**\n * A map of all object member validation functions for each keyword defined in the JSON Schema.\n * @name Schema.validationKeywords\n * @type {Object}\n */\nconst validationKeywords = {\n /**\n * Validates the provided value against all schemas defined in the Schemas `allOf` keyword.\n * The instance is valid against if and only if it is valid against all the schemas declared in the Schema's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be a valid JSON Schema.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor82\n *\n * @name Schema.validationKeywords.allOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `allOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n allOf (value, schema, opts) {\n let allErrors = []\n schema.allOf.forEach(function (_schema) {\n allErrors = allErrors.concat(validate(value, _schema, opts) || [])\n })\n return allErrors.length ? undefined : allErrors\n },\n\n /**\n * Validates the provided value against all schemas defined in the Schemas `anyOf` keyword.\n * The instance is valid against this keyword if and only if it is valid against\n * at least one of the schemas in this keyword's value.\n *\n * The value of this keyword MUST be an array. This array MUST have at least one element.\n * Each element of this array MUST be an object, and each object MUST be a valid JSON Schema.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor85\n *\n * @name Schema.validationKeywords.anyOf\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `anyOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n anyOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.anyOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * http://json-schema.org/latest/json-schema-validation.html#anchor70\n *\n * @name Schema.validationKeywords.dependencies\n * @method\n * @param {*} value TODO\n * @param {Object} schema TODO\n * @param {Object} opts TODO\n */\n dependencies (value, schema, opts) {\n // TODO\n },\n\n /**\n * Validates the provided value against an array of possible values defined by the Schema's `enum` keyword\n * Validation succeeds if the value is deeply equal to one of the values in the array.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor76\n *\n * @name Schema.validationKeywords.enum\n * @method\n * @param {*} value Value to validate\n * @param {Object} schema Schema containing the `enum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n enum (value, schema, opts) {\n const possibleValues = schema['enum']\n if (utils.findIndex(possibleValues, (item) => utils.deepEqual(item, value)) === -1) {\n return makeError(value, `one of (${possibleValues.join(', ')})`, opts)\n }\n },\n\n /**\n * Validates each of the provided array values against a schema or an array of schemas defined by the Schema's `items` keyword\n * see http://json-schema.org/latest/json-schema-validation.html#anchor37 for validation rules.\n *\n * @name Schema.validationKeywords.items\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the items keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n items (value, schema, opts) {\n opts || (opts = {})\n // TODO: additionalItems\n let items = schema.items\n let errors = []\n const checkingTuple = utils.isArray(items)\n const length = value.length\n for (var prop = 0; prop < length; prop++) {\n if (checkingTuple) {\n // Validating a tuple, instead of just checking each item against the\n // same schema\n items = schema.items[prop]\n }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], items, opts) || [])\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided number against a maximum value defined by the Schema's `maximum` keyword\n * Validation succeeds if the value is a number, and is less than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor17\n *\n * @name Schema.validationKeywords.maximum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `maximum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maximum (value, schema, opts) {\n // Must be a number\n const maximum = schema.maximum\n // Must be a boolean\n // Depends on maximum\n // default: false\n const exclusiveMaximum = schema.exclusiveMaximum\n if (typeof value === typeof maximum && !(exclusiveMaximum ? maximum > value : maximum >= value)) {\n return exclusiveMaximum\n ? makeError(value, `no more than nor equal to ${maximum}`, opts)\n : makeError(value, `no more than ${maximum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a maximum value defined by the Schema's `maxItems` keyword.\n * Validation succeeds if the length of the array is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor42\n *\n * @name Schema.validationKeywords.maxItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `maxItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return maxLengthCommon('maxItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a maximum value defined in the Schema's `maxLength` keyword.\n * Validation succeeds if the length of the string is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor26\n *\n * @name Schema.validationKeywords.maxLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `maxLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxLength (value, schema, opts) {\n return maxLengthCommon('maxLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a maximum value defined in the Schema's `maxProperties` keyword.\n * Validation succeeds if the object's property count is less than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor54\n *\n * @name Schema.validationKeywords.maxProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `maxProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n maxProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const maxProperties = schema.maxProperties\n const length = Object.keys(value).length\n if (length > maxProperties) {\n return makeError(length, `no more than ${maxProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided value against a minimum value defined by the Schema's `minimum` keyword\n * Validation succeeds if the value is a number and is greater than, or equal to, the value of this keyword.\n * http://json-schema.org/latest/json-schema-validation.html#anchor21\n *\n * @name Schema.validationKeywords.minimum\n * @method\n * @param {*} value Number to validate against the keyword.\n * @param {Object} schema Schema containing the `minimum` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minimum (value, schema, opts) {\n // Must be a number\n const minimum = schema.minimum\n // Must be a boolean\n // Depends on minimum\n // default: false\n const exclusiveMinimum = schema.exclusiveMinimum\n if (typeof value === typeof minimum && !(exclusiveMinimum ? value > minimum : value >= minimum)) {\n return exclusiveMinimum\n ? makeError(value, `no less than nor equal to ${minimum}`, opts)\n : makeError(value, `no less than ${minimum}`, opts)\n }\n },\n\n /**\n * Validates the length of the provided array against a minimum value defined by the Schema's `minItems` keyword.\n * Validation succeeds if the length of the array is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor45\n *\n * @name Schema.validationKeywords.minItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `minItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minItems (value, schema, opts) {\n if (utils.isArray(value)) {\n return minLengthCommon('minItems', value, schema, opts)\n }\n },\n\n /**\n * Validates the length of the provided string against a minimum value defined in the Schema's `minLength` keyword.\n * Validation succeeds if the length of the string is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor29\n *\n * @name Schema.validationKeywords.minLength\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `minLength` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minLength (value, schema, opts) {\n return minLengthCommon('minLength', value, schema, opts)\n },\n\n /**\n * Validates the count of the provided object's properties against a minimum value defined in the Schema's `minProperties` keyword.\n * Validation succeeds if the object's property count is greater than, or equal to the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor57\n *\n * @name Schema.validationKeywords.minProperties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `minProperties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n minProperties (value, schema, opts) {\n // validate only objects\n if (!utils.isObject(value)) return\n const minProperties = schema.minProperties\n const length = Object.keys(value).length\n if (length < minProperties) {\n return makeError(length, `no more than ${minProperties} properties`, opts)\n }\n },\n\n /**\n * Validates the provided number is a multiple of the number defined in the Schema's `multipleOf` keyword.\n * Validation succeeds if the number can be divided equally into the value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor14\n *\n * @name Schema.validationKeywords.multipleOf\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing the `multipleOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n multipleOf (value, schema, opts) {\n const multipleOf = schema.multipleOf\n if (utils.isNumber(value)) {\n if ((value / multipleOf) % 1 !== 0) {\n return makeError(value, `multipleOf ${multipleOf}`, opts)\n }\n }\n },\n\n /**\n * Validates the provided value is not valid with any of the schemas defined in the Schema's `not` keyword.\n * An instance is valid against this keyword if and only if it is NOT valid against the schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor91\n * @name Schema.validationKeywords.not\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the not keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n not (value, schema, opts) {\n if (!validate(value, schema.not, opts)) {\n // TODO: better messaging\n return makeError('succeeded', 'should have failed', opts)\n }\n },\n\n /**\n * Validates the provided value is valid with one and only one of the schemas defined in the Schema's `oneOf` keyword.\n * An instance is valid against this keyword if and only if it is valid against a single schemas in this keyword's value.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor88\n * @name Schema.validationKeywords.oneOf\n * @method\n * @param {*} value to be checked.\n * @param {Object} schema Schema containing the `oneOf` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n oneOf (value, schema, opts) {\n let validated = false\n let allErrors = []\n schema.oneOf.forEach(function (_schema) {\n const errors = validate(value, _schema, opts)\n if (errors) {\n allErrors = allErrors.concat(errors)\n } else if (validated) {\n allErrors = [makeError('valid against more than one', 'valid against only one', opts)]\n validated = false\n return false\n } else {\n validated = true\n }\n })\n return validated ? undefined : allErrors\n },\n\n /**\n * Validates the provided string matches a pattern defined in the Schema's `pattern` keyword.\n * Validation succeeds if the string is a match of the regex value of this keyword.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor33\n * @name Schema.validationKeywords.pattern\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing the `pattern` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n pattern (value, schema, opts) {\n const pattern = schema.pattern\n if (utils.isString(value) && !value.match(pattern)) {\n return makeError(value, pattern, opts)\n }\n },\n\n /**\n * Validates the provided object's properties against a map of values defined in the Schema's `properties` keyword.\n * Validation succeeds if the object's property are valid with each of the schema's in the provided map.\n * Validation also depends on the additionalProperties and or patternProperties.\n *\n * see http://json-schema.org/latest/json-schema-validation.html#anchor64 for more info.\n *\n * @name Schema.validationKeywords.properties\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `properties` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n properties (value, schema, opts) {\n opts || (opts = {})\n // Can be a boolean or an object\n // Technically the default is an \"empty schema\", but here \"true\" is\n // functionally the same\n const additionalProperties = schema.additionalProperties === undefined ? true : schema.additionalProperties\n // \"s\": The property set of the instance to validate.\n const toValidate = {}\n // \"p\": The property set from \"properties\".\n // Default is an object\n const properties = schema.properties || {}\n // \"pp\": The property set from \"patternProperties\".\n // Default is an object\n const patternProperties = schema.patternProperties || {}\n let errors = []\n\n // Collect set \"s\"\n utils.forOwn(value, function (_value, prop) {\n toValidate[prop] = undefined\n })\n // Remove from \"s\" all elements of \"p\", if any.\n utils.forOwn(properties || {}, function (_schema, prop) {\n // if (value[prop] === undefined && _schema['default'] !== undefined) {\n // value[prop] = utils.copy(_schema['default'])\n // }\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n })\n // For each regex in \"pp\", remove all elements of \"s\" which this regex\n // matches.\n utils.forOwn(patternProperties, function (_schema, pattern) {\n utils.forOwn(toValidate, function (undef, prop) {\n if (prop.match(pattern)) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], _schema, opts) || [])\n delete toValidate[prop]\n }\n })\n })\n const keys = Object.keys(toValidate)\n // If \"s\" is not empty, validation fails\n if (additionalProperties === false) {\n if (keys.length) {\n addError(`extra fields: ${keys.join(', ')}`, 'no extra fields', opts, errors)\n }\n } else if (utils.isObject(additionalProperties)) {\n // Otherwise, validate according to provided schema\n keys.forEach(function (prop) {\n opts.prop = prop\n errors = errors.concat(validate(value[prop], additionalProperties, opts) || [])\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided object's has all properties listed in the Schema's `properties` keyword array.\n * Validation succeeds if the object contains all properties provided in the array value of this keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor61\n *\n * @name Schema.validationKeywords.required\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing the `required` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n required (value, schema, opts) {\n opts || (opts = {})\n const required = schema.required\n let errors = []\n if (!opts.existingOnly) {\n required.forEach(function (prop) {\n if (utils.get(value, prop) === undefined) {\n const prevProp = opts.prop\n opts.prop = prop\n addError(undefined, 'a value', opts, errors)\n opts.prop = prevProp\n }\n })\n }\n return errors.length ? errors : undefined\n },\n\n /**\n * Validates the provided value's type is equal to the type, or array of types, defined in the Schema's `type` keyword.\n * see http://json-schema.org/latest/json-schema-validation.html#anchor79\n *\n * @name Schema.validationKeywords.type\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Schema containing the `type` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n type (value, schema, opts) {\n let type = schema.type\n let validType\n // Can be one of several types\n if (utils.isString(type)) {\n type = [type]\n }\n // Try to match the value against an expected type\n type.forEach(function (_type) {\n // TODO: throw an error if type is not defined\n if (types[_type](value, schema, opts)) {\n // Matched a type\n validType = _type\n return false\n }\n })\n // Value did not match any expected type\n if (!validType) {\n return makeError(value !== undefined && value !== null ? typeof value : '' + value, `one of (${type.join(', ')})`, opts)\n }\n // Run keyword validators for matched type\n // http://json-schema.org/latest/json-schema-validation.html#anchor12\n const validator = typeGroupValidators[validType]\n if (validator) {\n return validator(value, schema, opts)\n }\n },\n\n /**\n * Validates the provided array values are unique.\n * Validation succeeds if the items in the array are unique, but only if the value of this keyword is true\n * see http://json-schema.org/latest/json-schema-validation.html#anchor49\n *\n * @name Schema.validationKeywords.uniqueItems\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing the `uniqueItems` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n uniqueItems (value, schema, opts) {\n if (value && value.length && schema.uniqueItems) {\n const length = value.length\n let item, i, j\n // Check n - 1 items\n for (i = length - 1; i > 0; i--) {\n item = value[i]\n // Only compare against unchecked items\n for (j = i - 1; j >= 0; j--) {\n // Found a duplicate\n if (utils.deepEqual(item, value[j])) {\n return makeError(item, 'no duplicates', opts)\n }\n }\n }\n }\n }\n}\n\n/**\n * @ignore\n */\nconst validateKeyword = function (op, value, schema, opts) {\n return schema[op] !== undefined && validationKeywords[op](value, schema, opts)\n}\n\n/**\n * @ignore\n */\nconst runOps = function (ops, value, schema, opts) {\n let errors = []\n ops.forEach(function (op) {\n errors = errors.concat(validateKeyword(op, value, schema, opts) || [])\n })\n return errors.length ? errors : undefined\n}\n\nconst ANY_OPS = ['enum', 'type', 'allOf', 'anyOf', 'oneOf', 'not']\nconst ARRAY_OPS = ['items', 'maxItems', 'minItems', 'uniqueItems']\nconst NUMERIC_OPS = ['multipleOf', 'maximum', 'minimum']\nconst OBJECT_OPS = ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\nconst STRING_OPS = ['maxLength', 'minLength', 'pattern']\n\n/**\n * http://json-schema.org/latest/json-schema-validation.html#anchor75\n * @ignore\n */\nconst validateAny = function (value, schema, opts) {\n return runOps(ANY_OPS, value, schema, opts)\n}\n\n/**\n * Validates the provided value against a given Schema according to the http://json-schema.org/ v4 specification.\n *\n * @name Schema.validate\n * @method\n * @param {*} value Value to be validated.\n * @param {Object} schema Valid Schema according to the http://json-schema.org/ v4 specification.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\nconst validate = function (value, schema, opts) {\n let errors = []\n opts || (opts = {})\n opts.ctx || (opts.ctx = { value, schema })\n let shouldPop\n let prevProp = opts.prop\n if (schema === undefined) {\n return\n }\n if (!utils.isObject(schema)) {\n throw utils.err(`${DOMAIN}#validate`)(500, `Invalid schema at path: \"${opts.path}\"`)\n }\n if (opts.path === undefined) {\n opts.path = []\n }\n // Track our location as we recurse\n if (opts.prop !== undefined) {\n shouldPop = true\n opts.path.push(opts.prop)\n opts.prop = undefined\n }\n // Validate against parent schema\n if (schema['extends']) {\n // opts.path = path\n // opts.prop = prop\n if (utils.isFunction(schema['extends'].validate)) {\n errors = errors.concat(schema['extends'].validate(value, opts) || [])\n } else {\n errors = errors.concat(validate(value, schema['extends'], opts) || [])\n }\n }\n if (value === undefined) {\n // Check if property is required\n if (schema.required === true && !opts.existingOnly) {\n addError(value, 'a value', opts, errors)\n }\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n }\n\n errors = errors.concat(validateAny(value, schema, opts) || [])\n if (shouldPop) {\n opts.path.pop()\n opts.prop = prevProp\n }\n return errors.length ? errors : undefined\n}\n\n// These strings are cached for optimal performance of the change detection\n// boolean - Whether a Record is changing in the current execution frame\nconst changingPath = 'changing'\n// string[] - Properties that have changed in the current execution frame\nconst changedPath = 'changed'\n// Object[] - History of change records\nconst changeHistoryPath = 'history'\n// boolean - Whether a Record is currently being instantiated\nconst creatingPath = 'creating'\n// number - The setTimeout change event id of a Record, if any\nconst eventIdPath = 'eventId'\n// boolean - Whether to skip validation for a Record's currently changing property\nconst noValidatePath = 'noValidate'\n// boolean - Whether to skip change notification for a Record's currently\n// changing property\nconst silentPath = 'silent'\nconst validationFailureMsg = 'validation failed'\n\n/**\n * Assemble a property descriptor which will be added to the prototype of\n * {@link Mapper#recordClass}. This method is called when\n * {@link Mapper#applySchema} is set to `true`.\n *\n * @ignore\n */\nconst makeDescriptor = function (prop, schema, opts) {\n const descriptor = {\n // Better to allow configurability, but at the user's own risk\n configurable: true,\n // These properties are enumerable by default, but regardless of their\n // enumerability, they won't be \"own\" properties of individual records\n enumerable: schema.enumerable === undefined ? true : !!schema.enumerable\n }\n // Cache a few strings for optimal performance\n const keyPath = `props.${prop}`\n const previousPath = `previous.${prop}`\n const getter = opts.getter\n const setter = opts.setter\n const unsetter = opts.unsetter\n const track = utils.isBoolean(opts.track) ? opts.track : schema.track\n\n descriptor.get = function () {\n return this._get(keyPath)\n }\n\n if (utils.isFunction(schema.get)) {\n const originalGet = descriptor.get\n descriptor.get = function () {\n return schema.get.call(this, originalGet)\n }\n }\n\n descriptor.set = function (value) {\n // These are accessed a lot\n const _get = this[getter]\n const _set = this[setter]\n const _unset = this[unsetter]\n\n // Optionally check that the new value passes validation\n if (!_get(noValidatePath)) {\n const errors = schema.validate(value, { path: [prop] })\n if (errors) {\n // Immediately throw an error, preventing the record from getting into\n // an invalid state\n const error = new Error(validationFailureMsg)\n error.errors = errors\n throw error\n }\n }\n // TODO: Make it so tracking can be turned on for all properties instead of\n // only per-property\n if (track && !_get(creatingPath)) {\n const previous = _get(previousPath)\n const current = _get(keyPath)\n let changing = _get(changingPath)\n let changed = _get(changedPath)\n\n if (!changing) {\n // Track properties that are changing in the current event loop\n changed = []\n }\n\n // Add changing properties to this array once at most\n const index = changed.indexOf(prop)\n if (current !== value && index === -1) {\n changed.push(prop)\n }\n if (previous === value) {\n if (index >= 0) {\n changed.splice(index, 1)\n }\n }\n // No changes in current event loop\n if (!changed.length) {\n changing = false\n _unset(changingPath)\n _unset(changedPath)\n // Cancel pending change event\n if (_get(eventIdPath)) {\n clearTimeout(_get(eventIdPath))\n _unset(eventIdPath)\n }\n }\n // Changes detected in current event loop\n if (!changing && changed.length) {\n _set(changedPath, changed)\n _set(changingPath, true)\n // Saving the timeout id allows us to batch all changes in the same\n // event loop into a single \"change\"\n // TODO: Optimize\n _set(eventIdPath, setTimeout(() => {\n // Previous event loop where changes were gathered has ended, so\n // notify any listeners of those changes and prepare for any new\n // changes\n _unset(changedPath)\n _unset(eventIdPath)\n _unset(changingPath)\n // TODO: Optimize\n if (!_get(silentPath)) {\n let i\n for (i = 0; i < changed.length; i++) {\n this.emit('change:' + changed[i], this, utils.get(this, changed[i]))\n }\n const changes = this.changes()\n const changeRecord = utils.plainCopy(changes)\n changeRecord.timestamp = new Date().getTime()\n const changeHistory = _get(changeHistoryPath) || []\n _set(changeHistoryPath, changeHistory)\n changeHistory.push(changeRecord)\n this.emit('change', this, changes)\n }\n _unset(silentPath)\n }, 0))\n }\n }\n _set(keyPath, value)\n return value\n }\n\n if (utils.isFunction(schema.set)) {\n const originalSet = descriptor.set\n descriptor.set = function (value) {\n return schema.set.call(this, value, originalSet)\n }\n }\n\n return descriptor\n}\n\n/**\n * A map of validation functions grouped by type.\n *\n * @name Schema.typeGroupValidators\n * @type {Object}\n */\nconst typeGroupValidators = {\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an array.\n * The validation keywords for the type `array` are:\n *```\n * ['items', 'maxItems', 'minItems', 'uniqueItems']\n *```\n * see http://json-schema.org/latest/json-schema-validation.html#anchor25\n *\n * @name Schema.typeGroupValidators.array\n * @method\n * @param {*} value Array to be validated.\n * @param {Object} schema Schema containing at least one array keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n array: function (value, schema, opts) {\n return runOps(ARRAY_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an integer.\n * The validation keywords for the type `integer` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.integer\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `integer` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n integer: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an number.\n * The validation keywords for the type `number` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * @name Schema.typeGroupValidators.number\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `number` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n number: function (value, schema, opts) {\n // Additional validations for numerics are the same\n return typeGroupValidators.numeric(value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of a number or integer.\n * The validation keywords for the type `numeric` are:\n *```\n * ['multipleOf', 'maximum', 'minimum']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor13.\n *\n * @name Schema.typeGroupValidators.numeric\n * @method\n * @param {*} value Number to be validated.\n * @param {Object} schema Schema containing at least one `numeric` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n numeric: function (value, schema, opts) {\n return runOps(NUMERIC_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an object.\n * The validation keywords for the type `object` are:\n *```\n * ['maxProperties', 'minProperties', 'required', 'properties', 'dependencies']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor53.\n *\n * @name Schema.typeGroupValidators.object\n * @method\n * @param {*} value Object to be validated.\n * @param {Object} schema Schema containing at least one `object` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n object: function (value, schema, opts) {\n return runOps(OBJECT_OPS, value, schema, opts)\n },\n\n /**\n * Validates the provided value against the schema using all of the validation keywords specific to instances of an string.\n * The validation keywords for the type `string` are:\n *```\n * ['maxLength', 'minLength', 'pattern']\n *```\n * See http://json-schema.org/latest/json-schema-validation.html#anchor25.\n *\n * @name Schema.typeGroupValidators.string\n * @method\n * @param {*} value String to be validated.\n * @param {Object} schema Schema containing at least one `string` keyword.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n string: function (value, schema, opts) {\n return runOps(STRING_OPS, value, schema, opts)\n }\n}\n\n/**\n * js-data's Schema class.\n *\n * @example Schema#constructor\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const PostSchema = new Schema({\n * type: 'object',\n * properties: {\n * title: { type: 'string' }\n * }\n * })\n * PostSchema.validate({ title: 1234 })\n *\n * @class Schema\n * @extends Component\n * @param {Object} definition Schema definition according to json-schema.org\n */\nfunction Schema (definition) {\n definition || (definition = {})\n // TODO: schema validation\n utils.fillIn(this, definition)\n\n if (this.type === 'object' && this.properties) {\n utils.forOwn(this.properties, (_definition, prop) => {\n if (!(_definition instanceof Schema)) {\n this.properties[prop] = new Schema(_definition)\n }\n })\n }\n if (this.type === 'array' && this.items && !(this.items instanceof Schema)) {\n this.items = new Schema(this.items)\n }\n ['allOf', 'anyOf', 'oneOf'].forEach((validationKeyword) => {\n if (this[validationKeyword]) {\n this[validationKeyword].forEach((_definition, i) => {\n if (!(_definition instanceof Schema)) {\n this[validationKeyword][i] = new Schema(_definition)\n }\n })\n }\n })\n}\n\nexport default Component.extend({\n constructor: Schema,\n\n /**\n * This adds ES5 getters/setters to the target based on the \"properties\" in\n * this Schema, which makes possible change tracking and validation on\n * property assignment.\n *\n * @name Schema#validate\n * @method\n * @param {Object} target The prototype to which to apply this schema.\n */\n apply (target, opts) {\n opts || (opts = {})\n opts.getter || (opts.getter = '_get')\n opts.setter || (opts.setter = '_set')\n opts.unsetter || (opts.unsetter = '_unset')\n opts.track || (opts.track = this.track)\n const properties = this.properties || {}\n utils.forOwn(properties, function (schema, prop) {\n Object.defineProperty(\n target,\n prop,\n makeDescriptor(prop, schema, opts)\n )\n })\n },\n\n /**\n * Apply default values to the target object for missing values.\n *\n * @name Schema#applyDefaults\n * @method\n * @param {Object} target The target to which to apply values for missing values.\n */\n applyDefaults (target) {\n if (!target) {\n return\n }\n const properties = this.properties || {}\n const hasSet = utils.isFunction(target.set) || utils.isFunction(target._set)\n utils.forOwn(properties, function (schema, prop) {\n if (schema.hasOwnProperty('default') && utils.get(target, prop) === undefined) {\n if (hasSet) {\n target.set(prop, utils.plainCopy(schema['default']), { silent: true })\n } else {\n utils.set(target, prop, utils.plainCopy(schema['default']))\n }\n }\n if (schema.type === 'object' && schema.properties) {\n if (hasSet) {\n const orig = target._get('noValidate')\n target._set('noValidate', true)\n utils.set(target, prop, utils.get(target, prop) || {}, { silent: true })\n target._set('noValidate', orig)\n } else {\n utils.set(target, prop, utils.get(target, prop) || {})\n }\n schema.applyDefaults(utils.get(target, prop))\n }\n })\n },\n\n /**\n * Validate the provided value against this schema.\n *\n * @name Schema#validate\n * @method\n * @param {*} value Value to validate.\n * @param {Object} [opts] Configuration options.\n * @returns {(array|undefined)} Array of errors or `undefined` if valid.\n */\n validate (value, opts) {\n return validate(value, this, opts)\n }\n}, {\n ANY_OPS,\n ARRAY_OPS,\n NUMERIC_OPS,\n OBJECT_OPS,\n STRING_OPS,\n typeGroupValidators,\n types,\n validate,\n validationKeywords\n})\n\n/**\n * Create a subclass of this Schema:\n * @example Schema.extend\n * // Normally you would do: import {Schema} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Schema} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomSchemaClass extends Schema {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customSchema = new CustomSchemaClass()\n * console.log(customSchema.foo())\n * console.log(CustomSchemaClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherSchemaClass = Schema.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherSchema = new OtherSchemaClass()\n * console.log(otherSchema.foo())\n * console.log(OtherSchemaClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherSchemaClass () {\n * Schema.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Schema.extend({\n * constructor: AnotherSchemaClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherSchema = new AnotherSchemaClass()\n * console.log(anotherSchema.created_at)\n * console.log(anotherSchema.foo())\n * console.log(AnotherSchemaClass.beep())\n *\n * @method Schema.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Schema class.\n * @since 3.0.0\n */\n\n","import utils from './utils'\nimport Component from './Component'\nimport Record from './Record'\nimport Schema from './Schema'\nimport { Relation } from './relations'\nimport {\n belongsTo,\n belongsToType,\n hasMany,\n hasManyType,\n hasOne,\n hasOneType\n} from './decorators'\n\nconst DOMAIN = 'Mapper'\nconst applyDefaultsHooks = [\n 'beforeCreate',\n 'beforeCreateMany'\n]\nconst validatingHooks = [\n 'beforeCreate',\n 'beforeCreateMany',\n 'beforeUpdate',\n 'beforeUpdateAll',\n 'beforeUpdateMany'\n]\nconst makeNotify = function (num) {\n return function (...args) {\n const opts = args[args.length - num]\n const op = opts.op\n this.dbg(op, ...args)\n\n if (applyDefaultsHooks.indexOf(op) !== -1 && opts.applyDefaults !== false) {\n const schema = this.getSchema()\n if (schema && schema.applyDefaults) {\n let toProcess = args[0]\n if (!utils.isArray(toProcess)) {\n toProcess = [toProcess]\n }\n toProcess.forEach((record) => {\n schema.applyDefaults(record)\n })\n }\n }\n\n // Automatic validation\n if (validatingHooks.indexOf(op) !== -1 && !opts.noValidate) {\n // Save current value of option\n const originalExistingOnly = opts.existingOnly\n\n // For updates, ignore required fields if they aren't present\n if (op.indexOf('beforeUpdate') === 0 && opts.existingOnly === undefined) {\n opts.existingOnly = true\n }\n const errors = this.validate(args[op === 'beforeUpdate' ? 1 : 0], utils.pick(opts, ['existingOnly']))\n\n // Restore option\n opts.existingOnly = originalExistingOnly\n\n // Abort lifecycle due to validation errors\n if (errors) {\n return utils.reject(errors)\n }\n }\n\n // Emit lifecycle event\n if (opts.notify || (opts.notify === undefined && this.notify)) {\n setTimeout(() => {\n this.emit(op, ...args)\n })\n }\n }\n}\n\n// These are the default implementations of all of the lifecycle hooks\nconst notify = makeNotify(1)\nconst notify2 = makeNotify(2)\n\n// This object provides meta information used by Mapper#crud to actually\n// execute each lifecycle method\nconst LIFECYCLE_METHODS = {\n count: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroy: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n destroyAll: {\n defaults: [{}, {}],\n skip: true,\n types: []\n },\n find: {\n defaults: [undefined, {}],\n types: []\n },\n findAll: {\n defaults: [{}, {}],\n types: []\n },\n sum: {\n defaults: [undefined, {}, {}],\n skip: true,\n types: []\n },\n update: {\n adapterArgs (mapper, id, props, opts) {\n return [id, mapper.toJSON(props, opts), opts]\n },\n beforeAssign: 1,\n defaults: [undefined, {}, {}],\n types: []\n },\n updateAll: {\n adapterArgs (mapper, props, query, opts) {\n return [mapper.toJSON(props, opts), query, opts]\n },\n beforeAssign: 0,\n defaults: [{}, {}, {}],\n types: []\n },\n updateMany: {\n adapterArgs (mapper, records, opts) {\n return [records.map(function (record) {\n return mapper.toJSON(record, opts)\n }), opts]\n },\n beforeAssign: 0,\n defaults: [[], {}],\n types: []\n }\n}\n\nconst MAPPER_DEFAULTS = {\n /**\n * Hash of registered adapters. Don't modify directly. Use\n * {@link Mapper#registerAdapter} instead.\n *\n * @default {}\n * @name Mapper#_adapters\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n _adapters: {},\n\n /**\n * Whether {@link Mapper#beforeCreate} and {@link Mapper#beforeCreateMany}\n * should automatically receive default values according to the Mapper's schema.\n *\n * @default true\n * @name Mapper#applyDefaults\n * @since 3.0.0\n * @type {boolean}\n */\n applyDefaults: true,\n\n /**\n * Whether to augment {@link Mapper#recordClass} with ES5 getters and setters\n * according to the properties defined in {@link Mapper#schema}. This makes\n * possible validation and change tracking on individual properties\n * when using the dot (e.g. `user.name = \"Bob\"`) operator to modify a\n * property, and is `true` by default.\n *\n * @default true\n * @name Mapper#applySchema\n * @since 3.0.0\n * @type {boolean}\n */\n applySchema: true,\n\n /**\n * The name of the registered adapter that this Mapper should used by default.\n *\n * @default \"http\"\n * @name Mapper#defaultAdapter\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n * @type {string}\n */\n defaultAdapter: 'http',\n\n /**\n * The field used as the unique identifier on records handled by this Mapper.\n *\n * @default id\n * @name Mapper#idAttribute\n * @since 3.0.0\n * @type {string}\n */\n idAttribute: 'id',\n\n /**\n * Whether this Mapper should emit operational events.\n *\n * @default true\n * @name Mapper#notify\n * @since 3.0.0\n * @type {boolean}\n */\n notify: true,\n\n /**\n * Whether to skip validation when the Record instances are created.\n *\n * @default false\n * @name Mapper#noValidate\n * @since 3.0.0\n * @type {boolean}\n */\n noValidate: false,\n\n /**\n * Whether {@link Mapper#create}, {@link Mapper#createMany},\n * {@link Mapper#update}, {@link Mapper#updateAll}, {@link Mapper#updateMany},\n * {@link Mapper#find}, {@link Mapper#findAll}, {@link Mapper#destroy},\n * {@link Mapper#destroyAll}, {@link Mapper#count}, and {@link Mapper#sum}\n * should return a raw result object that contains both the instance data\n * returned by the adapter _and_ metadata about the operation.\n *\n * The default is to NOT return the result object, and instead return just the\n * instance data.\n *\n * @default false\n * @name Mapper#raw\n * @since 3.0.0\n * @type {boolean}\n */\n raw: false\n}\n\n/**\n * The core of JSData's [ORM/ODM][orm] implementation. Given a minimum amout of\n * meta information about a resource, a Mapper can perform generic CRUD\n * operations against that resource. Apart from its configuration, a Mapper is\n * stateless. The particulars of various persistence layers have been abstracted\n * into adapters, which a Mapper uses to perform its operations.\n *\n * The term \"Mapper\" comes from the [Data Mapper Pattern][pattern] described in\n * Martin Fowler's [Patterns of Enterprise Application Architecture][book]. A\n * Data Mapper moves data between [in-memory object instances][record] and a\n * relational or document-based database. JSData's Mapper can work with any\n * persistence layer you can write an adapter for.\n *\n * _(\"Model\" is a heavily overloaded term and is avoided in this documentation\n * to prevent confusion.)_\n *\n * [orm]: https://en.wikipedia.org/wiki/Object-relational_mapping\n * [pattern]: https://en.wikipedia.org/wiki/Data_mapper_pattern\n * [book]: http://martinfowler.com/books/eaa.html\n * [record]: Record.html\n *\n * @example\n * // Import and instantiate\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @example\n * // Define a Mapper using the Container component\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @class Mapper\n * @extends Component\n * @param {Object} opts Configuration options.\n * @param {boolean} [opts.applySchema=true] See {@link Mapper#applySchema}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {string} [opts.defaultAdapter=http] See {@link Mapper#defaultAdapter}.\n * @param {string} [opts.idAttribute=id] See {@link Mapper#idAttribute}.\n * @param {Object} [opts.methods] See {@link Mapper#methods}.\n * @param {string} opts.name See {@link Mapper#name}.\n * @param {boolean} [opts.notify] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw=false] See {@link Mapper#raw}.\n * @param {Function|boolean} [opts.recordClass] See {@link Mapper#recordClass}.\n * @param {Object|Schema} [opts.schema] See {@link Mapper#schema}.\n * @returns {Mapper} A new {@link Mapper} instance.\n * @see http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n */\nfunction Mapper (opts) {\n utils.classCallCheck(this, Mapper)\n Component.call(this)\n opts || (opts = {})\n\n // Prepare certain properties to be non-enumerable\n Object.defineProperties(this, {\n _adapters: {\n value: undefined,\n writable: true\n },\n\n /**\n * The {@link Container} that holds this Mapper. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n datastore: {\n value: undefined,\n writable: true\n },\n\n /**\n * The meta information describing this Mapper's available lifecycle\n * methods. __Do not modify.__\n *\n * @name Mapper#lifecycleMethods\n * @since 3.0.0\n * @type {Object}\n */\n lifecycleMethods: {\n value: LIFECYCLE_METHODS\n },\n\n /**\n * Set to `false` to force the Mapper to work with POJO objects only.\n *\n * @example\n * // Use POJOs only.\n * import {Mapper, Record} from 'js-data'\n * const UserMapper = new Mapper({ recordClass: false })\n * UserMapper.recordClass // false\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n *\n * @example\n * // Set to a custom class to have records wrapped in your custom class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User {\n * constructor (props = {}) {\n * for (var key in props) {\n * if (props.hasOwnProperty(key)) {\n * this[key] = props[key]\n * }\n * }\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // false\n * user instanceof User // true\n *\n *\n * @example\n * // Extend the {@link Record} class.\n * import {Mapper, Record} from 'js-data'\n * // Custom class\n * class User extends Record {\n * constructor () {\n * super(props)\n * }\n * }\n * const UserMapper = new Mapper({ recordClass: User })\n * UserMapper.recordClass // function User() {}\n * const user = UserMapper#createRecord()\n * user instanceof Record // true\n * user instanceof User // true\n *\n * @name Mapper#recordClass\n * @default {@link Record}\n * @see Record\n * @since 3.0.0\n */\n recordClass: {\n value: undefined,\n writable: true\n },\n\n /**\n * This Mapper's {@link Schema}.\n *\n * @example Mapper#schema\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const UserMapper = new Mapper({\n * name: 'user',\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * first: { type: 'string', track: true },\n * last: { type: 'string', track: true },\n * role: { type: 'string', track: true, required: true },\n * age: { type: 'integer', track: true },\n * is_active: { type: 'number' }\n * }\n * }\n * })\n * const user = UserMapper.createRecord({\n * id: 1,\n * name: 'John',\n * role: 'admin'\n * })\n * user.on('change', function (user, changes) {\n * console.log(changes)\n * })\n * user.on('change:role', function (user, value) {\n * console.log('change:role - ' + value)\n * })\n * user.role = 'owner'\n *\n * @name Mapper#schema\n * @see Schema\n * @since 3.0.0\n * @type {Schema}\n */\n schema: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply user-provided configuration\n utils.fillIn(this, opts)\n // Fill in any missing options with the defaults\n utils.fillIn(this, utils.copy(MAPPER_DEFAULTS))\n\n /**\n * The name for this Mapper. This is the minimum amount of meta information\n * required for a Mapper to be able to execute CRUD operations for a\n * Resource.\n *\n * @name Mapper#name\n * @since 3.0.0\n * @type {string}\n */\n if (!this.name) {\n throw utils.err(`new ${DOMAIN}`, 'opts.name')(400, 'string', this.name)\n }\n\n // Setup schema, with an empty default schema if necessary\n if (this.schema) {\n this.schema.type || (this.schema.type = 'object')\n }\n if (!(this.schema instanceof Schema)) {\n this.schema = new Schema(this.schema || { type: 'object' })\n }\n\n // Create a subclass of Record that's tied to this Mapper\n if (this.recordClass === undefined) {\n const superClass = Record\n this.recordClass = superClass.extend({\n constructor: (function Record () {\n var subClass = function Record (props, opts) {\n utils.classCallCheck(this, subClass)\n superClass.call(this, props, opts)\n }\n return subClass\n })()\n })\n }\n\n if (this.recordClass) {\n this.recordClass.mapper = this\n\n /**\n * Functions that should be added to the prototype of {@link Mapper#recordClass}.\n *\n * @name Mapper#methods\n * @since 3.0.0\n * @type {Object}\n */\n if (utils.isObject(this.methods)) {\n utils.addHiddenPropsToTarget(this.recordClass.prototype, this.methods)\n }\n\n // We can only apply the schema to the prototype of this.recordClass if the\n // class extends Record\n if (Record.prototype.isPrototypeOf(Object.create(this.recordClass.prototype)) && this.schema && this.schema.apply && this.applySchema) {\n this.schema.apply(this.recordClass.prototype)\n }\n }\n}\n\nexport default Component.extend({\n constructor: Mapper,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCount: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterCreateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroy: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterDestroyAll\n * @param {*} data The `data` returned by the adapter.\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterDestroyAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFind: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterFindAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterSum\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterSum: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdate: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateAll: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#afterUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @param {*} result The result, if any.\n * @since 3.0.0\n */\n afterUpdateMany: notify2,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#create}. If this method\n * returns a promise then {@link Mapper#create} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreate\n * @param {Object} props The `props` argument passed to {@link Mapper#create}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#create}.\n * @since 3.0.0\n */\n beforeCreate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#createMany}. If this method\n * returns a promise then {@link Mapper#createMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCreateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#createMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#createMany}.\n * @since 3.0.0\n */\n beforeCreateMany: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#count}. If this method\n * returns a promise then {@link Mapper#count} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeCount\n * @param {Object} query The `query` argument passed to {@link Mapper#count}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#count}.\n * @since 3.0.0\n */\n beforeCount: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroy}. If this method\n * returns a promise then {@link Mapper#destroy} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroy\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#destroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroy}.\n * @since 3.0.0\n */\n beforeDestroy: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#destroyAll}. If this method\n * returns a promise then {@link Mapper#destroyAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeDestroyAll\n * @param {query} query The `query` argument passed to {@link Mapper#destroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#destroyAll}.\n * @since 3.0.0\n */\n beforeDestroyAll: notify,\n\n /**\n * Mappers lifecycle hook called by {@link Mapper#find}. If this method\n * returns a promise then {@link Mapper#find} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFind\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#find}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#find}.\n * @since 3.0.0\n */\n beforeFind: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#findAll}. If this method\n * returns a promise then {@link Mapper#findAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeFindAll\n * @param {Object} query The `query` argument passed to {@link Mapper#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#findAll}.\n * @since 3.0.0\n */\n beforeFindAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#sum}. If this method\n * returns a promise then {@link Mapper#sum} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeSum\n * @param {string} field The `field` argument passed to {@link Mapper#sum}.\n * @param {Object} query The `query` argument passed to {@link Mapper#sum}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#sum}.\n * @since 3.0.0\n */\n beforeSum: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#update}. If this method\n * returns a promise then {@link Mapper#update} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdate\n * @param {(string|number)} id The `id` argument passed to {@link Mapper#update}.\n * @param {props} props The `props` argument passed to {@link Mapper#update}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#update}.\n * @since 3.0.0\n */\n beforeUpdate: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateAll}. If this method\n * returns a promise then {@link Mapper#updateAll} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateAll\n * @param {Object} props The `props` argument passed to {@link Mapper#updateAll}.\n * @param {Object} query The `query` argument passed to {@link Mapper#updateAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateAll}.\n * @since 3.0.0\n */\n beforeUpdateAll: notify,\n\n /**\n * Mapper lifecycle hook called by {@link Mapper#updateMany}. If this method\n * returns a promise then {@link Mapper#updateMany} will wait for the promise\n * to resolve before continuing.\n *\n * @method Mapper#beforeUpdateMany\n * @param {Array} records The `records` argument passed to {@link Mapper#updateMany}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#updateMany}.\n * @since 3.0.0\n */\n beforeUpdateMany: notify,\n\n /**\n * This method is called at the end of most lifecycle methods. It does the\n * following:\n *\n * 1. If `opts.raw` is `true`, add this Mapper's configuration to the `opts`\n * argument as metadata for the operation.\n * 2. Wrap the result data appropriately using {@link Mapper#wrap}, which\n * calls {@link Mapper#createRecord}.\n *\n * @method Mapper#_end\n * @private\n * @since 3.0.0\n */\n _end (result, opts, skip) {\n if (opts.raw) {\n utils._(result, opts)\n }\n if (skip) {\n return result\n }\n let _data = opts.raw ? result.data : result\n if (_data && utils.isFunction(this.wrap)) {\n _data = this.wrap(_data, opts)\n if (opts.raw) {\n result.data = _data\n } else {\n result = _data\n }\n }\n return result\n },\n\n /**\n * Define a belongsTo relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * PostMapper.belongsTo(UserMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to post records at \"post.user\"\n * localField: 'user'\n * })\n *\n * CommentMapper.belongsTo(UserMapper, {\n * // comment.user_id points to user.id\n * foreignKey: 'user_id'\n * // user records will be attached to comment records at \"comment.user\"\n * localField: 'user'\n * })\n * CommentMapper.belongsTo(PostMapper, {\n * // comment.post_id points to post.id\n * foreignKey: 'post_id'\n * // post records will be attached to comment records at \"comment.post\"\n * localField: 'post'\n * })\n *\n * @method Mapper#belongsTo\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n belongsTo (relatedMapper, opts) {\n return belongsTo(relatedMapper, opts)(this)\n },\n\n /**\n * Select records according to the `query` argument and return the count.\n *\n * {@link Mapper#beforeCount} will be called before calling the adapter.\n * {@link Mapper#afterCount} will be called after calling the adapter.\n *\n * @example\n * // Get the number of published blog posts\n * PostMapper.count({ status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Mapper#count\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `count` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the count of the selected records.\n * @since 3.0.0\n */\n count (query, opts) {\n return this.crud('count', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~beforeCreateListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreate\n * @see Mapper~beforeCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Mapper~beforeCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeCreate}.\n * @see Mapper#event:beforeCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#create}. See\n * {@link Mapper~afterCreateListener} for how to listen for this event.\n *\n * @event Mapper#afterCreate\n * @see Mapper~afterCreateListener\n * @see Mapper#create\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Mapper~afterCreateListener\n * @param {Object} props The `props` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterCreate}.\n * @see Mapper#event:afterCreate\n * @see Mapper#create\n * @since 3.0.0\n */\n /**\n * Create and save a new the record using the provided `props`.\n *\n * {@link Mapper#beforeCreate} will be called before calling the adapter.\n * {@link Mapper#afterCreate} will be called after calling the adapter.\n *\n * @example\n * // Create and save a new blog post\n * PostMapper.create({\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#create\n * @param {Object} props The properties for the new record.\n * @param {Object} [opts] Configuration options. Refer to the `create` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `props` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#create}\n * or {@link Mapper#createMany} call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created record.\n * @since 3.0.0\n */\n create (props, opts) {\n let op, adapter\n // Default values for arguments\n props || (props = {})\n opts || (opts = {})\n const originalRecord = props\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreate lifecycle hook\n op = opts.op = 'beforeCreate'\n return utils.resolve(this[op](props, opts)).then((_props) => {\n // Allow for re-assignment from lifecycle hook\n props = _props === undefined ? props : _props\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n const relatedMapper = def.getRelation()\n const relatedIdAttribute = relatedMapper.idAttribute\n optsCopy.raw = false\n if (!relationData) {\n return\n }\n if (def.type === belongsToType) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(relatedMapper.create(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n def.setForeignKey(props, data)\n }))\n } else if (def.type === hasManyType && def.localKeys) {\n // Create his hasMany relation first because it uses localKeys\n tasks.push(relatedMapper.createMany(relationData, optsCopy).then((data) => {\n def.setLocalField(belongsToRelationData, data)\n utils.set(props, def.localKeys, data.map((record) => utils.get(record, relatedIdAttribute)))\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter for the main create\n op = opts.op = 'create'\n this.dbg(op, props, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, this.toJSON(props, { with: opts.pass || [] }), opts))\n }).then((result) => {\n const createdRecordData = opts.raw ? result.data : result\n\n // Deep post-create hasMany and hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(props)\n if (!relationData) {\n return\n }\n optsCopy.raw = false\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType && def.foreignKey) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === hasOneType) {\n def.setForeignKey(createdRecordData, relationData)\n task = def.getRelation().create(relationData, optsCopy).then((result) => {\n def.setLocalField(createdRecordData, result)\n })\n } else if (def.type === belongsToType && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n } else if (def.type === hasManyType && def.localKeys && def.getLocalField(belongsToRelationData)) {\n def.setLocalField(createdRecordData, def.getLocalField(belongsToRelationData))\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n if (opts.raw) {\n result.data = originalRecord\n } else {\n result = originalRecord\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreate lifecycle hook\n op = opts.op = 'afterCreate'\n return utils.resolve(this[op](props, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Use {@link Mapper#createRecord} instead.\n * @deprecated\n * @method Mapper#createInstance\n * @param {Object|Array} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Object|Array} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n createInstance (props, opts) {\n return this.createRecord(props, opts)\n },\n\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeCreateMany\n * @see Mapper~beforeCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Mapper~beforeCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Mapper#event:beforeCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#createMany}. See\n * {@link Mapper~afterCreateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterCreateMany\n * @see Mapper~afterCreateManyListener\n * @see Mapper#createMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Mapper~afterCreateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Mapper#event:afterCreateMany\n * @see Mapper#createMany\n * @since 3.0.0\n */\n /**\n * Given an array of records, batch create them via an adapter.\n *\n * {@link Mapper#beforeCreateMany} will be called before calling the adapter.\n * {@link Mapper#afterCreateMany} will be called after calling the adapter.\n *\n * @example\n * // Create and save several new blog posts\n * PostMapper.createMany([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Mapper#beforeCreate\n * @fires Mapper#afterCreate\n * @method Mapper#createMany\n * @param {Record[]} records Array of records to be created in one batch.\n * @param {Object} [opts] Configuration options. Refer to the `createMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to create in a cascading\n * create if `records` contains nested relations. NOT performed in a\n * transaction. Each nested create will result in another {@link Mapper#createMany}\n * call.\n * @param {string[]} [opts.pass=[]] Relations to send to the adapter as part\n * of the payload. Normally relations are not sent.\n * @returns {Promise} Resolves with the created records.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n createMany (records, opts) {\n let op, adapter\n // Default values for arguments\n records || (records = [])\n opts || (opts = {})\n const originalRecords = records\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // beforeCreateMany lifecycle hook\n op = opts.op = 'beforeCreateMany'\n return utils.resolve(this[op](records, opts)).then((_records) => {\n // Allow for re-assignment from lifecycle hook\n records = _records === undefined ? records : _records\n\n // Deep pre-create belongsTo relations\n const belongsToRelationData = {}\n opts.with || (opts.with = [])\n let tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (def.type === belongsToType && relationData.length === records.length) {\n // Create belongsTo relation first because we need a generated id to\n // attach to the child\n tasks.push(def.getRelation().createMany(relationData, optsCopy).then((data) => {\n const relatedRecords = optsCopy.raw ? data.data : data\n def.setLocalField(belongsToRelationData, relatedRecords)\n records.forEach((record, i) => {\n def.setForeignKey(record, relatedRecords[i])\n })\n }))\n }\n })\n return utils.Promise.all(tasks).then(() => {\n // Now delegate to the adapter\n op = opts.op = 'createMany'\n const json = records.map((record) => this.toJSON(record, { with: opts.pass || [] }))\n this.dbg(op, records, opts)\n return utils.resolve(this.getAdapter(adapter)[op](this, json, opts))\n }).then((result) => {\n const createdRecordsData = opts.raw ? result.data : result\n\n // Deep post-create hasOne relations\n tasks = []\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = records\n .map((record) => def.getLocalField(record))\n .filter((relatedRecord) => relatedRecord)\n if (relationData.length !== records.length) {\n return\n }\n const belongsToData = def.getLocalField(belongsToRelationData)\n let task\n // Create hasMany and hasOne after the main create because we needed\n // a generated id to attach to these items\n if (def.type === hasManyType) {\n // Not supported\n this.log('warn', 'deep createMany of hasMany type not supported!')\n } else if (def.type === hasOneType) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setForeignKey(createdRecordData, relationData[i])\n })\n task = def.getRelation().createMany(relationData, optsCopy).then((result) => {\n const relatedData = opts.raw ? result.data : result\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, relatedData[i])\n })\n })\n } else if (def.type === belongsToType && belongsToData && belongsToData.length === createdRecordsData.length) {\n createdRecordsData.forEach((createdRecordData, i) => {\n def.setLocalField(createdRecordData, belongsToData[i])\n })\n }\n if (task) {\n tasks.push(task)\n }\n })\n return utils.Promise.all(tasks).then(() => {\n createdRecordsData.forEach((createdRecordData, i) => {\n const originalRecord = originalRecords[i]\n utils.set(originalRecord, createdRecordData, { silent: true })\n if (utils.isFunction(originalRecord.commit)) {\n originalRecord.commit()\n }\n })\n if (opts.raw) {\n result.data = originalRecords\n } else {\n result = originalRecords\n }\n return result\n })\n })\n }).then((result) => {\n result = this._end(result, opts)\n // afterCreateMany lifecycle hook\n op = opts.op = 'afterCreateMany'\n return utils.resolve(this[op](records, opts, result)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Create an unsaved, uncached instance of this Mapper's\n * {@link Mapper#recordClass}.\n *\n * Returns `props` if `props` is already an instance of\n * {@link Mapper#recordClass}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * const post = PostMapper.createRecord()\n *\n * @example\n * // Create an unsaved record instance with inital properties\n * const post = PostMapper.createRecord({\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create a record instance that corresponds to a saved record\n * const post = PostMapper.createRecord({\n * // JSData thinks this record has been saved if it has a primary key\n * id: 1234,\n * title: 'Modeling your data',\n * status: 'draft'\n * })\n *\n * @example\n * // Create record instances from an array\n * const posts = PostMapper.createRecord([{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }])\n *\n * @example\n * // Records are validated by default\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * try {\n * const post = PostMapper.createRecord({\n * title: 1234,\n * })\n * } catch (err) {\n * console.log(err.errors) // [{ expected: 'one of (string)', actual: 'number', path: 'title' }]\n * }\n *\n * @example\n * // Skip validation\n * import {Mapper} from 'js-data'\n * const PostMapper = new Mapper({\n * name: 'post',\n * schema: { properties: { title: { type: 'string' } } }\n * })\n * const post = PostMapper.createRecord({\n * title: 1234,\n * }, { noValidate: true })\n * console.log(post.isValid()) // false\n *\n * @method Mapper#createRecord\n * @param {Object|Object[]} props The properties for the Record instance or an\n * array of property objects for the Record instances.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @returns {Record|Record[]} The Record instance or Record instances.\n * @since 3.0.0\n */\n createRecord (props, opts) {\n props || (props = {})\n if (utils.isArray(props)) {\n return props.map((_props) => this.createRecord(_props, opts))\n }\n if (!utils.isObject(props)) {\n throw utils.err(`${DOMAIN}#createRecord`, 'props')(400, 'array or object', props)\n }\n const RecordCtor = this.recordClass\n const relationList = this.relationList || []\n relationList.forEach(function (def) {\n const relatedMapper = def.getRelation()\n const relationData = def.getLocalField(props)\n if (relationData && !relatedMapper.is(relationData)) {\n if (utils.isArray(relationData) && (!relationData.length || relatedMapper.is(relationData[0]))) {\n return\n }\n utils.set(props, def.localField, relatedMapper.createRecord(relationData, opts))\n }\n })\n // Check to make sure \"props\" is not already an instance of this Mapper.\n if (RecordCtor && (!(props instanceof RecordCtor))) {\n return new RecordCtor(props, opts)\n }\n return props\n },\n\n /**\n * Lifecycle invocation method. You probably won't call this method directly.\n *\n * @method Mapper#crud\n * @param {string} method Name of the lifecycle method to invoke.\n * @param {...*} args Arguments to pass to the lifecycle method.\n * @returns {Promise}\n * @since 3.0.0\n */\n crud (method, ...args) {\n const config = this.lifecycleMethods[method]\n if (!config) {\n throw utils.err(`${DOMAIN}#crud`, method)(404, 'method')\n }\n\n const upper = `${method.charAt(0).toUpperCase()}${method.substr(1)}`\n const before = `before${upper}`\n const after = `after${upper}`\n\n let op, adapter\n\n // Default values for arguments\n config.defaults.forEach((value, i) => {\n if (args[i] === undefined) {\n args[i] = utils.copy(value)\n }\n })\n\n const opts = args[args.length - 1]\n\n // Fill in \"opts\" with the Mapper's configuration\n utils._(opts, this)\n adapter = opts.adapter = this.getAdapterName(opts)\n\n // before lifecycle hook\n op = opts.op = before\n return utils.resolve(this[op](...args)).then((_value) => {\n if (args[config.beforeAssign] !== undefined) {\n // Allow for re-assignment from lifecycle hook\n args[config.beforeAssign] = _value === undefined ? args[config.beforeAssign] : _value\n }\n // Now delegate to the adapter\n op = opts.op = method\n args = config.adapterArgs ? config.adapterArgs(this, ...args) : args\n this.dbg(op, ...args)\n return utils.resolve(this.getAdapter(adapter)[op](this, ...args))\n }).then((result) => {\n result = this._end(result, opts, !!config.skip)\n args.push(result)\n // after lifecycle hook\n op = opts.op = after\n return utils.resolve(this[op](...args)).then((_result) => {\n // Allow for re-assignment from lifecycle hook\n return _result === undefined ? result : _result\n })\n })\n },\n\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~beforeDestroyListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroy\n * @see Mapper~beforeDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Mapper~beforeDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroy}.\n * @see Mapper#event:beforeDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroy}. See\n * {@link Mapper~afterDestroyListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroy\n * @see Mapper~afterDestroyListener\n * @see Mapper#destroy\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Mapper~afterDestroyListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroy}.\n * @see Mapper#event:afterDestroy\n * @see Mapper#destroy\n * @since 3.0.0\n */\n /**\n * Using an adapter, destroy the record with the given primary key.\n *\n * {@link Mapper#beforeDestroy} will be called before destroying the record.\n * {@link Mapper#afterDestroy} will be called after destroying the record.\n *\n * @example\n * // Destroy a specific blog post\n * PostMapper.destroy(1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @example\n * // Get full response\n * PostMapper.destroy(1234, { raw: true }).then((result) => {\n * console.log(result.deleted) e.g. 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroy\n * @fires Mapper#afterDestroy\n * @method Mapper#destroy\n * @param {(string|number)} id The primary key of the record to destroy.\n * @param {Object} [opts] Configuration options. Refer to the `destroy` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the record has been destroyed. Resolves\n * even if no record was found to be destroyed.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroy (id, opts) {\n return this.crud('destroy', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeDestroyAll\n * @see Mapper~beforeDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Mapper~beforeDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeDestroyAll}.\n * @see Mapper#event:beforeDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#destroyAll}. See\n * {@link Mapper~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Mapper#afterDestroyAll\n * @see Mapper~afterDestroyAllListener\n * @see Mapper#destroyAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Mapper~afterDestroyAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterDestroyAll}.\n * @see Mapper#event:afterDestroyAll\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n /**\n * Destroy the records selected by `query` via an adapter. If no `query` is\n * provided then all records will be destroyed.\n *\n * {@link Mapper#beforeDestroyAll} will be called before destroying the records.\n * {@link Mapper#afterDestroyAll} will be called after destroying the records.\n *\n * @example\n * // Destroy all blog posts\n * PostMapper.destroyAll().then(() => {\n * // All blog posts have been destroyed\n * })\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * PostMapper.destroyAll({ status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @example\n * // Get full response\n * const query = null\n * const options = { raw: true }\n * PostMapper.destroyAll(query, options).then((result) => {\n * console.log(result.deleted) e.g. 14\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeDestroyAll\n * @fires Mapper#afterDestroyAll\n * @method Mapper#destroyAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `destroyAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves when the records have been destroyed. Resolves\n * even if no records were found to be destroyed.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n destroyAll (query, opts) {\n return this.crud('destroyAll', query, opts)\n },\n\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~beforeFindListener} for how to listen for this event.\n *\n * @event Mapper#beforeFind\n * @see Mapper~beforeFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Mapper~beforeFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFind}.\n * @see Mapper#event:beforeFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#find}. See\n * {@link Mapper~afterFindListener} for how to listen for this event.\n *\n * @event Mapper#afterFind\n * @see Mapper~afterFindListener\n * @see Mapper#find\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFind} event.\n *\n * @example\n * function onAfterFind (id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Mapper~afterFindListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFind}.\n * @see Mapper#event:afterFind\n * @see Mapper#find\n * @since 3.0.0\n */\n /**\n * Retrieve via an adapter the record with the given primary key.\n *\n * {@link Mapper#beforeFind} will be called before calling the adapter.\n * {@link Mapper#afterFind} will be called after calling the adapter.\n *\n * @example\n * PostMapper.find(1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @example\n * // Get full response\n * PostMapper.find(1, { raw: true }).then((result) => {\n * console.log(result.data) // { id: 1, ...}\n * console.log(result.found) // 1\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFind\n * @fires Mapper#afterFind\n * @method Mapper#find\n * @param {(string|number)} id The primary key of the record to retrieve.\n * @param {Object} [opts] Configuration options. Refer to the `find` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found record. Resolves with\n * `undefined` if no record was found.\n * @see http://www.js-data.io/v3.0/docs/reading-data\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n find (id, opts) {\n return this.crud('find', id, opts)\n },\n\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~beforeFindAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeFindAll\n * @see Mapper~beforeFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Mapper~beforeFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeFindAll}.\n * @see Mapper#event:beforeFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#findAll}. See\n * {@link Mapper~afterFindAllListener} for how to listen for this event.\n *\n * @event Mapper#afterFindAll\n * @see Mapper~afterFindAllListener\n * @see Mapper#findAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Mapper~afterFindAllListener\n * @param {Object} query The `query` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterFindAll}.\n * @see Mapper#event:afterFindAll\n * @see Mapper#findAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, select records to retrieve via an adapter.\n *\n * {@link Mapper#beforeFindAll} will be called before calling the adapter.\n * {@link Mapper#afterFindAll} will be called after calling the adapter.\n *\n * @example\n * // Find all \"published\" blog posts\n * PostMapper.findAll({ status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, status: 'published', ...}, ...]\n * })\n *\n * @example\n * // Get full response\n * PostMapper.findAll({ status: 'published' }, { raw: true }).then((result) => {\n * console.log(result.data) // [{ id: 1, status: 'published', ...}, ...]\n * console.log(result.found) // e.g. 13\n * console.log(...) // etc., more metadata can be found on the result\n * })\n *\n * @fires Mapper#beforeFindAll\n * @fires Mapper#afterFindAll\n * @method Mapper#findAll\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `findAll` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @param {string[]} [opts.with=[]] Relations to eager load in the request.\n * @returns {Promise} Resolves with the found records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/reading-data\",\"Reading data\"]\n */\n findAll (query, opts) {\n return this.crud('findAll', query, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Mapper#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapter (name) {\n this.dbg('getAdapter', 'name:', name)\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Mapper#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || opts.defaultAdapter\n },\n\n /**\n * Get the object of registered adapters for this Mapper.\n *\n * @method Mapper#getAdapters\n * @returns {Object} {@link Mapper#_adapters}\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Returns this Mapper's {@link Schema}.\n *\n * @method Mapper#getSchema\n * @returns {Schema} This Mapper's {@link Schema}.\n * @see Mapper#schema\n * @since 3.0.0\n */\n getSchema () {\n return this.schema\n },\n\n /**\n * Defines a hasMany relationship. Only useful if you're managing your\n * Mappers manually and not using a Container or DataStore component.\n *\n * @example\n * UserMapper.hasMany(PostMapper, {\n * // post.user_id points to user.id\n * foreignKey: 'user_id'\n * // post records will be attached to user records at \"user.posts\"\n * localField: 'posts'\n * })\n *\n * @method Mapper#hasMany\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasMany (relatedMapper, opts) {\n return hasMany(relatedMapper, opts)(this)\n },\n\n /**\n * Defines a hasOne relationship. Only useful if you're managing your Mappers\n * manually and not using a {@link Container} or {@link DataStore} component.\n *\n * @example\n * UserMapper.hasOne(ProfileMapper, {\n * // profile.user_id points to user.id\n * foreignKey: 'user_id'\n * // profile records will be attached to user records at \"user.profile\"\n * localField: 'profile'\n * })\n *\n * @method Mapper#hasOne\n * @see http://www.js-data.io/v3.0/docs/relations\n * @since 3.0.0\n */\n hasOne (relatedMapper, opts) {\n return hasOne(relatedMapper, opts)(this)\n },\n\n /**\n * Return whether `record` is an instance of this Mapper's recordClass.\n *\n * @example\n * const post = PostMapper.createRecord()\n *\n * console.log(PostMapper.is(post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof PostMapper.recordClass) // true\n *\n * @method Mapper#is\n * @param {Object|Record} record The record to check.\n * @returns {boolean} Whether `record` is an instance of this Mapper's\n * {@link Mapper#recordClass}.\n * @since 3.0.0\n */\n is (record) {\n const recordClass = this.recordClass\n return recordClass ? record instanceof recordClass : false\n },\n\n /**\n * Register an adapter on this Mapper under the given name.\n *\n * @method Mapper#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for this Mapper.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.defaultAdapter = name\n }\n },\n\n /**\n * Select records according to the `query` argument, and aggregate the sum\n * value of the property specified by `field`.\n *\n * {@link Mapper#beforeSum} will be called before calling the adapter.\n * {@link Mapper#afterSum} will be called after calling the adapter.\n *\n * @example\n * PurchaseOrderMapper.sum('amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Mapper#sum\n * @param {string} field The field to sum.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `sum` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the aggregated sum.\n * @since 3.0.0\n */\n sum (field, query, opts) {\n return this.crud('sum', field, query, opts)\n },\n\n /**\n * Return a plain object representation of the given record. Relations can\n * be optionally be included. Non-schema properties can be excluded.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })\n * console.log(PersonMapper.toJSON(person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(PersonMapper.toJSON(person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Mapper#toJSON\n * @param {Record|Record[]} records Record or records from which to create a\n * POJO representation.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.strict] Whether to exclude properties that are not\n * defined in {@link Mapper#schema}.\n * @param {string[]} [opts.with] Array of relation names or relation fields\n * to include in the POJO representation.\n * @param {boolean} [opts.withAll] Whether to simply include all relations in\n * the representation. Overrides `opts.with`.\n * @returns {Object|Object[]} POJO representation of the record or records.\n * @since 3.0.0\n */\n toJSON (records, opts) {\n let record\n opts || (opts = {})\n if (utils.isArray(records)) {\n return records.map((record) => this.toJSON(record, opts))\n } else {\n record = records\n }\n const relationFields = (this ? this.relationFields : []) || []\n let json = {}\n let properties\n if (this && this.schema) {\n properties = this.schema.properties || {}\n // TODO: Make this work recursively\n utils.forOwn(properties, (opts, prop) => {\n json[prop] = utils.plainCopy(record[prop])\n })\n }\n properties || (properties = {})\n if (!opts.strict) {\n for (var key in record) {\n if (!properties[key] && relationFields.indexOf(key) === -1) {\n json[key] = utils.plainCopy(record[key])\n }\n }\n }\n // The user wants to include relations in the resulting plain object\n // representation\n if (this && opts.withAll) {\n opts.with = relationFields.slice()\n }\n if (this && opts.with) {\n if (utils.isString(opts.with)) {\n opts.with = [opts.with]\n }\n utils.forEachRelation(this, opts, (def, optsCopy) => {\n const relationData = def.getLocalField(record)\n if (relationData) {\n // The actual recursion\n if (utils.isArray(relationData)) {\n def.setLocalField(json, relationData.map((item) => {\n return def.getRelation().toJSON(item, optsCopy)\n }))\n } else {\n def.setLocalField(json, def.getRelation().toJSON(relationData, optsCopy))\n }\n }\n })\n }\n return json\n },\n\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~beforeUpdateListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdate\n * @see Mapper~beforeUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Mapper~beforeUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#beforeUpdate}.\n * @see Mapper#event:beforeUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#update}. See\n * {@link Mapper~afterUpdateListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdate\n * @see Mapper~afterUpdateListener\n * @see Mapper#update\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Mapper~afterUpdateListener\n * @param {string|number} id The `id` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument passed to {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument passed to {@link Mapper#afterUpdate}.\n * @see Mapper#event:afterUpdate\n * @see Mapper#update\n * @since 3.0.0\n */\n /**\n * Using an adapter, update the record with the primary key specified by the\n * `id` argument.\n *\n * {@link Mapper#beforeUpdate} will be called before updating the record.\n * {@link Mapper#afterUpdate} will be called after updating the record.\n *\n * @example\n * // Update a specific post\n * PostMapper.update(1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Mapper#beforeUpdate\n * @fires Mapper#afterUpdate\n * @method Mapper#update\n * @param {(string|number)} id The primary key of the record to update.\n * @param {Object} props The update to apply to the record.\n * @param {Object} [opts] Configuration options. Refer to the `update` method\n * of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * transaction.\n * @returns {Promise} Resolves with the updated record. Rejects if the record\n * could not be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n update (id, props, opts) {\n return this.crud('update', id, props, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateAll\n * @see Mapper~beforeUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Mapper~beforeUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Mapper#event:beforeUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateAll}. See\n * {@link Mapper~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateAll\n * @see Mapper~afterUpdateAllListener\n * @see Mapper#updateAll\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Mapper~afterUpdateAllListener\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Mapper#event:afterUpdateAll\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n /**\n * Using the `query` argument, perform the a single updated to the selected\n * records.\n *\n * {@link Mapper#beforeUpdateAll} will be called before making the update.\n * {@link Mapper#afterUpdateAll} will be called after making the update.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * PostMapper.updateAll(update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateAll\n * @fires Mapper#afterUpdateAll\n * @method Mapper#updateAll\n * @param {Object} props Update to apply to selected records.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options. Refer to the `updateAll`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the update records, if any.\n * @see query\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateAll (props, query, opts) {\n return this.crud('updateAll', props, query, opts)\n },\n\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#beforeUpdateMany\n * @see Mapper~beforeUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Mapper~beforeUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Mapper#event:beforeUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Mapper#updateMany}. See\n * {@link Mapper~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Mapper#afterUpdateMany\n * @see Mapper~afterUpdateManyListener\n * @see Mapper#updateMany\n */\n /**\n * Callback signature for the {@link Mapper#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Mapper~afterUpdateManyListener\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Mapper#event:afterUpdateMany\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n /**\n * Given an array of updates, perform each of the updates via an adapter. Each\n * \"update\" is a hash of properties with which to update an record. Each\n * update must contain the primary key of the record to be updated.\n *\n * {@link Mapper#beforeUpdateMany} will be called before making the update.\n * {@link Mapper#afterUpdateMany} will be called after making the update.\n *\n * @example\n * PostMapper.updateMany([\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Mapper#beforeUpdateMany\n * @fires Mapper#afterUpdateMany\n * @method Mapper#updateMany\n * @param {Record[]} records Array up record updates.\n * @param {Object} [opts] Configuration options. Refer to the `updateMany`\n * method of whatever adapter you're using for more configuration options.\n * @param {boolean} [opts.adapter={@link Mapper#defaultAdapter}] Name of the\n * adapter to use.\n * @param {boolean} [opts.notify={@link Mapper#notify}] See {@link Mapper#notify}.\n * @param {boolean} [opts.noValidate={@link Mapper#noValidate}] See {@link Mapper#noValidate}.\n * @param {boolean} [opts.raw={@link Mapper#raw}] See {@link Mapper#raw}.\n * @returns {Promise} Resolves with the updated records. Rejects if any of the\n * records could be found.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n updateMany (records, opts) {\n return this.crud('updateMany', records, opts)\n },\n\n /**\n * Validate the given record or records according to this Mapper's\n * {@link Schema}. If there are no validation errors then the return value\n * will be `undefined`.\n *\n * @example\n * import {Mapper, Schema} from 'js-data'\n * const PersonSchema = new Schema({\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * })\n * const PersonMapper = new Mapper({\n * name: 'person',\n * schema: PersonSchema\n * })\n * let errors = PersonMapper.validate({ name: 'John' })\n * console.log(errors) // undefined\n * errors = PersonMapper.validate({ name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Mapper#validate\n * @param {Object|Object[]} record The record or records to validate.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Schema#validate}.\n * @returns {Object[]} Array of errors or `undefined` if no errors.\n * @since 3.0.0\n */\n validate (record, opts) {\n opts || (opts = {})\n const schema = this.getSchema()\n const _opts = utils.pick(opts, ['existingOnly'])\n if (utils.isArray(record)) {\n const errors = record.map((_record) => schema.validate(_record, utils.pick(_opts, ['existingOnly'])))\n let hasErrors = false\n errors.forEach(function (err) {\n if (err) {\n hasErrors = true\n }\n })\n if (hasErrors) {\n return errors\n }\n return undefined\n }\n return schema.validate(record, _opts)\n },\n\n /**\n * Method used to wrap data returned by an adapter with this Mapper's\n * {@link Mapper#recordClass}. This method is used by all of a Mapper's CRUD\n * methods. The provided implementation of this method assumes that the `data`\n * passed to it is a record or records that need to be wrapped with\n * {@link Mapper#createRecord}. Override with care.\n *\n * Provided implementation of {@link Mapper#wrap}:\n *\n * ```\n * function (data, opts) {\n * return this.createRecord(data, opts)\n * }\n * ```\n *\n * @example\n * const PostMapper = new Mapper({\n * name: 'post',\n * // Override to customize behavior\n * wrap (data, opts) {\n * const originalWrap = this.constructor.prototype.wrap\n * // Let's say \"GET /post\" doesn't return JSON quite like JSData expects,\n * // but the actual post records are nested under a \"posts\" field. So,\n * // we override Mapper#wrap to handle this special case.\n * if (opts.op === 'findAll') {\n * return originalWrap.call(this, data.posts, opts)\n * }\n * // Otherwise perform original behavior\n * return originalWrap.call(this, data, opts)\n * }\n * })\n *\n * @method Mapper#wrap\n * @param {Object|Object[]} data The record or records to be wrapped.\n * @param {Object} [opts] Configuration options. Passed to {@link Mapper#createRecord}.\n * @returns {Record|Record[]} The wrapped record or records.\n * @since 3.0.0\n */\n wrap (data, opts) {\n return this.createRecord(data, opts)\n },\n\n /**\n * @ignore\n */\n defineRelations () {\n // Setup the mapper's relations, including generating Mapper#relationList\n // and Mapper#relationFields\n utils.forOwn(this.relations, (group, type) => {\n utils.forOwn(group, (relations, _name) => {\n if (utils.isObject(relations)) {\n relations = [relations]\n }\n relations.forEach((def) => {\n const relatedMapper = this.datastore.getMapperByName(_name) || _name\n def.getRelation = () => this.datastore.getMapper(_name)\n\n if (typeof Relation[type] !== 'function') {\n throw utils.err(DOMAIN, 'defineRelations')(400, 'relation type (hasOne, hasMany, etc)', type, true)\n }\n\n this[type](relatedMapper, def)\n })\n })\n })\n }\n})\n\n/**\n * Create a subclass of this Mapper:\n *\n * @example Mapper.extend\n * // Normally you would do: import {Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Mapper} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomMapperClass extends Mapper {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customMapper = new CustomMapperClass()\n * console.log(customMapper.foo())\n * console.log(CustomMapperClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherMapperClass = Mapper.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherMapper = new OtherMapperClass()\n * console.log(otherMapper.foo())\n * console.log(OtherMapperClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherMapperClass () {\n * Mapper.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Mapper.extend({\n * constructor: AnotherMapperClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherMapper = new AnotherMapperClass()\n * console.log(anotherMapper.created_at)\n * console.log(anotherMapper.foo())\n * console.log(AnotherMapperClass.beep())\n *\n * @method Mapper.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Mapper class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport Component from './Component'\nimport Mapper from './Mapper'\n\nconst DOMAIN = 'Container'\n\nexport const proxiedMapperMethods = [\n /**\n * Wrapper for {@link Mapper#count}.\n *\n * @example\n * // Get the number of published blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.count('post', { status: 'published' }).then((numPublished) => {\n * console.log(numPublished) // e.g. 45\n * })\n *\n * @method Container#count\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#count}.\n * @param {Object} [opts] See {@link Mapper#count}.\n * @returns {Promise} See {@link Mapper#count}.\n * @see Mapper#count\n * @since 3.0.0\n */\n 'count',\n\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~beforeCreateListener} for how to listen for this event.\n *\n * @event Container#beforeCreate\n * @see Container~beforeCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback Container~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see Container#event:beforeCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#create}. See\n * {@link Container~afterCreateListener} for how to listen for this event.\n *\n * @event Container#afterCreate\n * @see Container~afterCreateListener\n * @see Container#create\n */\n /**\n * Callback signature for the {@link Container#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback Container~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see Container#event:afterCreate\n * @see Container#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}.\n *\n * @example\n * // Create and save a new blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.create('post', {\n * title: 'Modeling your data',\n * status: 'draft'\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreate\n * @fires Container#afterCreate\n * @method Container#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props See {@link Mapper#create}.\n * @param {Object} [opts] See {@link Mapper#create}.\n * @returns {Promise} See {@link Mapper#create}.\n * @see Mapper#create\n * @since 3.0.0\n */\n 'create',\n\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~beforeCreateManyListener} for how to listen for this event.\n *\n * @event Container#beforeCreateMany\n * @see Container~beforeCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback Container~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see Container#event:beforeCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#createMany}. See\n * {@link Container~afterCreateManyListener} for how to listen for this event.\n *\n * @event Container#afterCreateMany\n * @see Container~afterCreateManyListener\n * @see Container#createMany\n */\n /**\n * Callback signature for the {@link Container#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback Container~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see Container#event:afterCreateMany\n * @see Container#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}.\n *\n * @example\n * // Create and save several new blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.createMany('post', [{\n * title: 'Modeling your data',\n * status: 'draft'\n * }, {\n * title: 'Reading data',\n * status: 'draft'\n * }]).then((posts) => {\n * console.log(posts[0]) // { id: 1234, status: 'draft', ... }\n * console.log(posts[1]) // { id: 1235, status: 'draft', ... }\n * })\n *\n * @fires Container#beforeCreateMany\n * @fires Container#afterCreateMany\n * @method Container#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record[]} records See {@link Mapper#createMany}.\n * @param {Object} [opts] See {@link Mapper#createMany}.\n * @returns {Promise} See {@link Mapper#createMany}.\n * @see Mapper#createMany\n * @since 3.0.0\n */\n 'createMany',\n\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * __Note:__ This method does __not__ interact with any adapter, and does\n * __not__ save any data. It only creates new objects in memory.\n *\n * @example\n * // Create empty unsaved record instance\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = PostMapper.createRecord()\n *\n * @method Container#createRecord\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Object[]} props See {@link Mapper#createRecord}.\n * @param {Object} [opts] See {@link Mapper#createRecord}.\n * @returns {Promise} See {@link Mapper#createRecord}.\n * @see Mapper#createRecord\n * @since 3.0.0\n */\n 'createRecord',\n\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~beforeDestroyListener} for how to listen for this event.\n *\n * @event Container#beforeDestroy\n * @see Container~beforeDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback Container~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see Container#event:beforeDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroy}. See\n * {@link Container~afterDestroyListener} for how to listen for this event.\n *\n * @event Container#afterDestroy\n * @see Container~afterDestroyListener\n * @see Container#destroy\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback Container~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see Container#event:afterDestroy\n * @see Container#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}.\n *\n * @example\n * // Destroy a specific blog post\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroy('post', 1234).then(() => {\n * // Blog post #1234 has been destroyed\n * })\n *\n * @fires Container#beforeDestroy\n * @fires Container#afterDestroy\n * @method Container#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#destroy}.\n * @param {Object} [opts] See {@link Mapper#destroy}.\n * @returns {Promise} See {@link Mapper#destroy}.\n * @see Mapper#destroy\n * @since 3.0.0\n */\n 'destroy',\n\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event Container#beforeDestroyAll\n * @see Container~beforeDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback Container~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see Container#event:beforeDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#destroyAll}. See\n * {@link Container~afterDestroyAllListener} for how to listen for this event.\n *\n * @event Container#afterDestroyAll\n * @see Container~afterDestroyAllListener\n * @see Container#destroyAll\n */\n /**\n * Callback signature for the {@link Container#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback Container~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see Container#event:afterDestroyAll\n * @see Container#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}.\n *\n * @example\n * // Destroy all \"draft\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.destroyAll('post', { status: 'draft' }).then(() => {\n * // All \"draft\" blog posts have been destroyed\n * })\n *\n * @fires Container#beforeDestroyAll\n * @fires Container#afterDestroyAll\n * @method Container#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#destroyAll}.\n * @param {Object} [opts] See {@link Mapper#destroyAll}.\n * @returns {Promise} See {@link Mapper#destroyAll}.\n * @see Mapper#destroyAll\n * @since 3.0.0\n */\n 'destroyAll',\n\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~beforeFindListener} for how to listen for this event.\n *\n * @event Container#beforeFind\n * @see Container~beforeFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback Container~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see Container#event:beforeFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#find}. See\n * {@link Container~afterFindListener} for how to listen for this event.\n *\n * @event Container#afterFind\n * @see Container~afterFindListener\n * @see Container#find\n */\n /**\n * Callback signature for the {@link Container#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback Container~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see Container#event:afterFind\n * @see Container#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.find('post', 1).then((post) => {\n * console.log(post) // { id: 1, ...}\n * })\n *\n * @fires Container#beforeFind\n * @fires Container#afterFind\n * @method Container#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#find}.\n * @param {Object} [opts] See {@link Mapper#find}.\n * @returns {Promise} See {@link Mapper#find}.\n * @see Mapper#find\n * @since 3.0.0\n */\n 'find',\n\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~beforeFindAllListener} for how to listen for this event.\n *\n * @event Container#beforeFindAll\n * @see Container~beforeFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback Container~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see Container#event:beforeFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#findAll}. See\n * {@link Container~afterFindAllListener} for how to listen for this event.\n *\n * @event Container#afterFindAll\n * @see Container~afterFindAllListener\n * @see Container#findAll\n */\n /**\n * Callback signature for the {@link Container#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback Container~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see Container#event:afterFindAll\n * @see Container#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createRecord}.\n *\n * @example\n * // Find all \"published\" blog posts\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.findAll('post', { status: 'published' }).then((posts) => {\n * console.log(posts) // [{ id: 1, ...}, ...]\n * })\n *\n * @fires Container#beforeFindAll\n * @fires Container#afterFindAll\n * @method Container#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] See {@link Mapper#findAll}.\n * @param {Object} [opts] See {@link Mapper#findAll}.\n * @returns {Promise} See {@link Mapper#findAll}.\n * @see Mapper#findAll\n * @since 3.0.0\n */\n 'findAll',\n\n /**\n * Wrapper for {@link Mapper#getSchema}.\n *\n * @method Container#getSchema\n * @param {string} name Name of the {@link Mapper} to target.\n * @returns {Schema} See {@link Mapper#getSchema}.\n * @see Mapper#getSchema\n * @since 3.0.0\n */\n 'getSchema',\n\n /**\n * Wrapper for {@link Mapper#is}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post')\n * const post = store.createRecord()\n *\n * console.log(store.is('post', post)) // true\n * // Equivalent to what's above\n * console.log(post instanceof store.getMapper('post').recordClass) // true\n *\n * @method Container#is\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object|Record} record See {@link Mapper#is}.\n * @returns {boolean} See {@link Mapper#is}.\n * @see Mapper#is\n * @since 3.0.0\n */\n 'is',\n\n /**\n * Wrapper for {@link Mapper#sum}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('purchase_order')\n *\n * store.sum('purchase_order', 'amount', { status: 'paid' }).then((amountPaid) => {\n * console.log(amountPaid) // e.g. 451125.34\n * })\n *\n * @method Container#sum\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {string} field See {@link Mapper#sum}.\n * @param {Object} [query] See {@link Mapper#sum}.\n * @param {Object} [opts] See {@link Mapper#sum}.\n * @returns {Promise} See {@link Mapper#sum}.\n * @see Mapper#sum\n * @since 3.0.0\n */\n 'sum',\n\n /**\n * Wrapper for {@link Mapper#toJSON}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('person', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' })\n * console.log(store.toJSON('person', person)) // {\"id\":1,\"name\":\"John\",\"foo\":\"bar\"}\n * console.log(store.toJSON('person', person), { strict: true }) // {\"id\":1,\"name\":\"John\"}\n *\n * @method Container#toJSON\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Record|Record[]} records See {@link Mapper#toJSON}.\n * @param {Object} [opts] See {@link Mapper#toJSON}.\n * @returns {Object|Object[]} See {@link Mapper#toJSON}.\n * @see Mapper#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~beforeUpdateListener} for how to listen for this event.\n *\n * @event Container#beforeUpdate\n * @see Container~beforeUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback Container~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see Container#event:beforeUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#update}. See\n * {@link Container~afterUpdateListener} for how to listen for this event.\n *\n * @event Container#afterUpdate\n * @see Container~afterUpdateListener\n * @see Container#update\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback Container~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see Container#event:afterUpdate\n * @see Container#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.update('post', 1234, {\n * status: 'published',\n * published_at: new Date()\n * }).then((post) => {\n * console.log(post) // { id: 1234, status: 'published', ... }\n * })\n *\n * @fires Container#beforeUpdate\n * @fires Container#afterUpdate\n * @method Container#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link Mapper#update}.\n * @param {Object} record See {@link Mapper#update}.\n * @param {Object} [opts] See {@link Mapper#update}.\n * @returns {Promise} See {@link Mapper#update}.\n * @see Mapper#update\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/saving-data\",\"Saving data\"]\n */\n 'update',\n\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateAll\n * @see Container~beforeUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback Container~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see Container#event:beforeUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateAll}. See\n * {@link Container~afterUpdateAllListener} for how to listen for this event.\n *\n * @event Container#afterUpdateAll\n * @see Container~afterUpdateAllListener\n * @see Container#updateAll\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback Container~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see Container#event:afterUpdateAll\n * @see Container#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}.\n *\n * @example\n * // Turn all of John's blog posts into drafts.\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * const update = { status: draft: published_at: null }\n * const query = { userId: 1234 }\n * store.updateAll('post', update, query).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateAll\n * @fires Container#afterUpdateAll\n * @method Container#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} update See {@link Mapper#updateAll}.\n * @param {Object} [query] See {@link Mapper#updateAll}.\n * @param {Object} [opts] See {@link Mapper#updateAll}.\n * @returns {Promise} See {@link Mapper#updateAll}.\n * @see Mapper#updateAll\n * @since 3.0.0\n */\n 'updateAll',\n\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event Container#beforeUpdateMany\n * @see Container~beforeUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback Container~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see Container#event:beforeUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link Container#updateMany}. See\n * {@link Container~afterUpdateManyListener} for how to listen for this event.\n *\n * @event Container#afterUpdateMany\n * @see Container~afterUpdateManyListener\n * @see Container#updateMany\n */\n /**\n * Callback signature for the {@link Container#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback Container~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see Container#event:afterUpdateMany\n * @see Container#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}.\n *\n * @example\n * import {Container} from 'js-data'\n * import RethinkDBAdapter from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n * store.defineMapper('post')\n *\n * store.updateMany('post', [\n * { id: 1234, status: 'draft' },\n * { id: 2468, status: 'published', published_at: new Date() }\n * ]).then((posts) => {\n * console.log(posts) // [...]\n * })\n *\n * @fires Container#beforeUpdateMany\n * @fires Container#afterUpdateMany\n * @method Container#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#updateMany}.\n * @param {Object} [opts] See {@link Mapper#updateMany}.\n * @returns {Promise} See {@link Mapper#updateMany}.\n * @see Mapper#updateMany\n * @since 3.0.0\n */\n 'updateMany',\n\n /**\n * Wrapper for {@link Mapper#validate}.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * name: { type: 'string' },\n * id: { type: 'string' }\n * }\n * }\n * })\n * let errors = store.validate('post', { name: 'John' })\n * console.log(errors) // undefined\n * errors = store.validate('post', { name: 123 })\n * console.log(errors) // [{ expected: 'one of (string)', actual: 'number', path: 'name' }]\n *\n * @method Container#validate\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records See {@link Mapper#validate}.\n * @param {Object} [opts] See {@link Mapper#validate}.\n * @returns {Promise} See {@link Mapper#validate}.\n * @see Mapper#validate\n * @since 3.0.0\n */\n 'validate'\n]\n\n/**\n * The `Container` class is a place to define and store {@link Mapper} instances.\n *\n * `Container` makes it easy to manage your Mappers. Without a container, you\n * need to manage Mappers yourself, including resolving circular dependencies\n * among relations. All Mappers in a container share the same adapters, so you\n * don't have to register adapters for every single Mapper.\n *\n * @example Container#constructor\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n *\n * @class Container\n * @extends Component\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {Constructor} [opts.mapperClass] See {@link Container#mapperClass}.\n * @param {Object} [opts.mapperDefaults] See {@link Container#mapperDefaults}.\n * @since 3.0.0\n */\nexport function Container (opts) {\n utils.classCallCheck(this, Container)\n Component.call(this)\n opts || (opts = {})\n\n Object.defineProperties(this, {\n /**\n * The adapters registered with this Container, which are also shared by all\n * Mappers in this Container.\n *\n * @name Container#_adapters\n * @see Container#registerAdapter\n * @since 3.0.0\n * @type {Object}\n */\n _adapters: {\n value: {}\n },\n\n /**\n * The the mappers in this container\n *\n * @name Container#_mappers\n * @see Mapper\n * @since 3.0.0\n * @type {Object}\n */\n _mappers: {\n value: {}\n },\n\n /**\n * Constructor function to use in {@link Container#defineMapper} to create new\n * {@link Mapper} instances. {@link Container#mapperClass} should extend\n * {@link Mapper}. By default {@link Mapper} is used to instantiate Mappers.\n *\n * @example Container#mapperClass\n * // import {Container, Mapper} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * class MyMapperClass extends Mapper {\n * foo () { return 'bar' }\n * }\n * const store = new Container({\n * mapperClass: MyMapperClass\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').foo())\n *\n * @name Container#mapperClass\n * @see Mapper\n * @since 3.0.0\n * @type {Constructor}\n */\n mapperClass: {\n value: undefined,\n writable: true\n }\n })\n\n // Apply options provided by the user\n utils.fillIn(this, opts)\n\n /**\n * Defaults options to pass to {@link Container#mapperClass} when creating a\n * new {@link Mapper}.\n *\n * @example Container#mapperDefaults\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: {\n * idAttribute: '_id'\n * }\n * })\n * store.defineMapper('user')\n * console.log(store.getMapper('user').idAttribute)\n *\n * @default {}\n * @name Container#mapperDefaults\n * @since 3.0.0\n * @type {Object}\n */\n this.mapperDefaults = this.mapperDefaults || {}\n\n // Use the Mapper class if the user didn't provide a mapperClass\n this.mapperClass || (this.mapperClass = Mapper)\n}\n\nconst props = {\n constructor: Container,\n\n /**\n * Register a new event listener on this Container.\n *\n * Proxy for {@link Component#on}. If an event was emitted by a {@link Mapper}\n * in the Container, then the name of the {@link Mapper} will be prepended to\n * the arugments passed to the listener.\n *\n * @example Container#on\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * store.on('foo', function (...args) { console.log(args.join(':')) })\n * store.defineMapper('user')\n * store.emit('foo', 'arg1', 'arg2')\n * store.getMapper('user').emit('foo', 'arg1', 'arg2')\n *\n * @method Container#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n * @since 3.0.0\n */\n\n /**\n * Used to bind to events emitted by mappers in this container.\n *\n * @method Container#_onMapperEvent\n * @param {string} name Name of the mapper that emitted the event.\n * @param {...*} [args] Args See {@link Mapper#emit}.\n * @private\n * @since 3.0.0\n */\n _onMapperEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * Return a container scoped to a particular mapper.\n *\n * @example Container#as\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method Container#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} A container scoped to a particular mapper.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n proxiedMapperMethods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Create a new mapper and register it in this container.\n *\n * @example Container#defineMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container({\n * mapperDefaults: { foo: 'bar' }\n * })\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(UserMapper.foo)\n *\n * @method Container#defineMapper\n * @param {string} name Name under which to register the new {@link Mapper}.\n * {@link Mapper#name} will be set to this value.\n * @param {Object} [opts] Configuration options. Passed to\n * {@link Container#mapperClass} when creating the new {@link Mapper}.\n * @returns {Mapper} The newly created instance of {@link Mapper}.\n * @see Container#as\n * @since 3.0.0\n */\n defineMapper (name, opts) {\n // For backwards compatibility with defineResource\n if (utils.isObject(name)) {\n opts = name\n name = opts.name\n }\n if (!utils.isString(name)) {\n throw utils.err(`${DOMAIN}#defineMapper`, 'name')(400, 'string', name)\n }\n\n // Default values for arguments\n opts || (opts = {})\n // Set Mapper#name\n opts.name = name\n opts.relations || (opts.relations = {})\n\n // Check if the user is overriding the datastore's default mapperClass\n const mapperClass = opts.mapperClass || this.mapperClass\n delete opts.mapperClass\n\n // Apply the datastore's defaults to the options going into the mapper\n utils.fillIn(opts, this.mapperDefaults)\n\n // Instantiate a mapper\n const mapper = this._mappers[name] = new mapperClass(opts) // eslint-disable-line\n mapper.relations || (mapper.relations = {})\n // Make sure the mapper's name is set\n mapper.name = name\n // All mappers in this datastore will share adapters\n mapper._adapters = this.getAdapters()\n\n mapper.datastore = this\n\n mapper.on('all', (...args) => this._onMapperEvent(name, ...args))\n mapper.defineRelations()\n\n return mapper\n },\n\n defineResource (name, opts) {\n console.warn('DEPRECATED: defineResource is deprecated, use defineMapper instead')\n return this.defineMapper(name, opts)\n },\n\n /**\n * Return the registered adapter with the given name or the default adapter if\n * no name is provided.\n *\n * @method Container#getAdapter\n * @param {string} [name] The name of the adapter to retrieve.\n * @returns {Adapter} The adapter.\n * @since 3.0.0\n */\n getAdapter (name) {\n const adapter = this.getAdapterName(name)\n if (!adapter) {\n throw utils.err(`${DOMAIN}#getAdapter`, 'name')(400, 'string', name)\n }\n return this.getAdapters()[adapter]\n },\n\n /**\n * Return the name of a registered adapter based on the given name or options,\n * or the name of the default adapter if no name provided.\n *\n * @method Container#getAdapterName\n * @param {(Object|string)} [opts] The name of an adapter or options, if any.\n * @returns {string} The name of the adapter.\n * @since 3.0.0\n */\n getAdapterName (opts) {\n opts || (opts = {})\n if (utils.isString(opts)) {\n opts = { adapter: opts }\n }\n return opts.adapter || this.mapperDefaults.defaultAdapter\n },\n\n /**\n * Return the registered adapters of this container.\n *\n * @method Container#getAdapters\n * @returns {Adapter}\n * @since 3.0.0\n */\n getAdapters () {\n return this._adapters\n },\n\n /**\n * Return the mapper registered under the specified name.\n *\n * @example Container#getMapper\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * store.getMapper('profile') // throws Error, there is no mapper with name \"profile\"\n *\n * @method Container#getMapper\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapper (name) {\n const mapper = this.getMapperByName(name)\n if (!mapper) {\n throw utils.err(`${DOMAIN}#getMapper`, name)(404, 'mapper')\n }\n return mapper\n },\n\n /**\n * Return the mapper registered under the specified name.\n * Doesn't throw error if mapper doesn't exist.\n *\n * @example Container#getMapperByName\n * // import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new Container()\n * // Container#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n * console.log(UserMapper === store.getMapper('user'))\n * console.log(UserMapper === store.as('user').getMapper())\n * console.log(store.getMapper('profile')) // Does NOT throw an error\n *\n * @method Container#getMapperByName\n * @param {string} name {@link Mapper#name}.\n * @returns {Mapper}\n * @since 3.0.0\n */\n getMapperByName (name) {\n return this._mappers[name]\n },\n\n /**\n * Register an adapter on this container under the given name. Adapters\n * registered on a container are shared by all mappers in the container.\n *\n * @example\n * import {Container} from 'js-data'\n * import {RethinkDBAdapter} from 'js-data-rethinkdb'\n * const store = new Container()\n * store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })\n *\n * @method Container#registerAdapter\n * @param {string} name The name of the adapter to register.\n * @param {Adapter} adapter The adapter to register.\n * @param {Object} [opts] Configuration options.\n * @param {boolean} [opts.default=false] Whether to make the adapter the\n * default adapter for all Mappers in this container.\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/connecting-to-a-data-source\",\"Connecting to a data source\"]\n */\n registerAdapter (name, adapter, opts) {\n opts || (opts = {})\n this.getAdapters()[name] = adapter\n // Optionally make it the default adapter for the target.\n if (opts === true || opts.default) {\n this.mapperDefaults.defaultAdapter = name\n utils.forOwn(this._mappers, function (mapper) {\n mapper.defaultAdapter = name\n })\n }\n }\n}\n\nproxiedMapperMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getMapper(name)[method](...args)\n }\n})\n\nComponent.extend(props)\n\n/**\n * Create a subclass of this Container:\n * @example Container.extend\n * // Normally you would do: import {Container} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {Container} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomContainerClass extends Container {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customContainer = new CustomContainerClass()\n * console.log(customContainer.foo())\n * console.log(CustomContainerClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherContainerClass = Container.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherContainer = new OtherContainerClass()\n * console.log(otherContainer.foo())\n * console.log(OtherContainerClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherContainerClass () {\n * Container.call(this)\n * this.created_at = new Date().getTime()\n * }\n * Container.extend({\n * constructor: AnotherContainerClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherContainer = new AnotherContainerClass()\n * console.log(anotherContainer.created_at)\n * console.log(anotherContainer.foo())\n * console.log(AnotherContainerClass.beep())\n *\n * @method Container.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this Container class.\n * @since 3.0.0\n */\n","import utils from './utils'\nimport './decorators'\nimport Collection from './Collection'\n\nconst DOMAIN = 'LinkedCollection'\n\n/**\n * Extends {@link Collection}. Used by a {@link DataStore} to implement an\n * Identity Map.\n *\n * ```javascript\n * import {LinkedCollection} from 'js-data'\n * ```\n *\n * @class LinkedCollection\n * @extends Collection\n * @param {Array} [records] Initial set of records to insert into the\n * collection. See {@link Collection}.\n * @param {Object} [opts] Configuration options. See {@link Collection}.\n * @returns {Mapper}\n */\nfunction LinkedCollection (records, opts) {\n utils.classCallCheck(this, LinkedCollection)\n // Make sure this collection has somewhere to store \"added\" timestamps\n Object.defineProperties(this, {\n _added: {\n value: {}\n },\n datastore: {\n writable: true,\n value: undefined\n }\n })\n\n Collection.call(this, records, opts)\n\n // Make sure this collection has a reference to a datastore\n if (!this.datastore) {\n throw utils.err(`new ${DOMAIN}`, 'opts.datastore')(400, 'DataStore', this.datastore)\n }\n}\n\nexport default Collection.extend({\n constructor: LinkedCollection,\n\n _addMeta (record, timestamp) {\n // Track when this record was added\n this._added[this.recordId(record)] = timestamp\n\n if (utils.isFunction(record._set)) {\n record._set('$', timestamp)\n }\n },\n\n _clearMeta (record) {\n delete this._added[this.recordId(record)]\n if (utils.isFunction(record._set)) {\n record._set('$') // unset\n }\n },\n\n _onRecordEvent (...args) {\n Collection.prototype._onRecordEvent.apply(this, args)\n const event = args[0]\n // This is a very brute force method\n // Lots of room for optimization\n if (utils.isString(event) && event.indexOf('change') === 0) {\n this.updateIndexes(args[1])\n }\n },\n\n add (records, opts) {\n const mapper = this.mapper\n const timestamp = new Date().getTime()\n const singular = utils.isObject(records) && !utils.isArray(records)\n\n if (singular) {\n records = [records]\n }\n records = Collection.prototype.add.call(this, records, opts)\n\n if (mapper.relationList.length && records.length) {\n // Check the currently visited record for relations that need to be\n // inserted into their respective collections.\n mapper.relationList.forEach(function (def) {\n def.addLinkedRecords(records)\n })\n }\n\n records.forEach((record) => this._addMeta(record, timestamp))\n\n return singular ? records[0] : records\n },\n\n remove (idOrRecord, opts) {\n const mapper = this.mapper\n const record = Collection.prototype.remove.call(this, idOrRecord, opts)\n if (record) {\n this._clearMeta(record)\n }\n\n if (mapper.relationList.length && record) {\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, [record])\n })\n }\n\n return record\n },\n\n removeAll (query, opts) {\n const mapper = this.mapper\n const records = Collection.prototype.removeAll.call(this, query, opts)\n records.forEach(this._clearMeta, this)\n\n if (mapper.relationList.length && records.length) {\n mapper.relationList.forEach(function (def) {\n def.removeLinkedRecords(mapper, records)\n })\n }\n\n return records\n }\n})\n\n/**\n * Create a subclass of this LinkedCollection:\n *\n * @example LinkedCollection.extend\n * // Normally you would do: import {LinkedCollection} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {LinkedCollection} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomLinkedCollectionClass extends LinkedCollection {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customLinkedCollection = new CustomLinkedCollectionClass()\n * console.log(customLinkedCollection.foo())\n * console.log(CustomLinkedCollectionClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherLinkedCollectionClass = LinkedCollection.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherLinkedCollection = new OtherLinkedCollectionClass()\n * console.log(otherLinkedCollection.foo())\n * console.log(OtherLinkedCollectionClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherLinkedCollectionClass () {\n * LinkedCollection.call(this)\n * this.created_at = new Date().getTime()\n * }\n * LinkedCollection.extend({\n * constructor: AnotherLinkedCollectionClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherLinkedCollection = new AnotherLinkedCollectionClass()\n * console.log(anotherLinkedCollection.created_at)\n * console.log(anotherLinkedCollection.foo())\n * console.log(AnotherLinkedCollectionClass.beep())\n *\n * @method LinkedCollection.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this LinkedCollection class.\n * @since 3.0.0\n */\n","import utils, { safeSetLink, safeSetProp } from './utils'\n\nimport {\n belongsToType,\n hasManyType,\n hasOneType\n} from './decorators'\nimport {proxiedMapperMethods, Container} from './Container'\nimport LinkedCollection from './LinkedCollection'\n\nconst DOMAIN = 'DataStore'\nconst proxiedCollectionMethods = [\n /**\n * Wrapper for {@link LinkedCollection#add}.\n *\n * @example DataStore#add\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n *\n * // Add one book to the in-memory store:\n * store.add('book', { id: 1, title: 'Respect your Data' })\n * // Add multiple books to the in-memory store:\n * store.add('book', [\n * { id: 2, title: 'Easy data recipes' },\n * { id: 3, title: 'Active Record 101' }\n * ])\n *\n * @fires DataStore#add\n * @method DataStore#add\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Object[]|Record|Record[])} data See {@link LinkedCollection#add}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#add}.\n * @returns {(Object|Object[]|Record|Record[])} See {@link LinkedCollection#add}.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n 'add',\n\n /**\n * Wrapper for {@link LinkedCollection#between}.\n *\n * @example\n * // Get all users ages 18 to 30\n * const users = store.between('user', 18, 30, { index: 'age' })\n *\n * @example\n * // Same as above\n * const users = store.between('user', [18], [30], { index: 'age' })\n *\n * @method DataStore#between\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Array} leftKeys See {@link LinkedCollection#between}.\n * @param {Array} rightKeys See {@link LinkedCollection#between}.\n * @param {Object} [opts] Configuration options. See {@link LinkedCollection#between}.\n * @returns {Object[]|Record[]} See {@link LinkedCollection#between}.\n * @see LinkedCollection#between\n * @see Collection#between\n * @since 3.0.0\n */\n 'between',\n\n /**\n * Wrapper for {@link LinkedCollection#createIndex}.\n *\n * @example\n * // Index users by age\n * store.createIndex('user', 'age')\n *\n * @example\n * // Index users by status and role\n * store.createIndex('user', 'statusAndRole', ['status', 'role'])\n *\n * @method DataStore#createIndex\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {string} name See {@link LinkedCollection#createIndex}.\n * @param {string[]} [fieldList] See {@link LinkedCollection#createIndex}.\n * @see LinkedCollection#createIndex\n * @see Collection#createIndex\n * @since 3.0.0\n */\n 'createIndex',\n\n /**\n * Wrapper for {@link LinkedCollection#filter}.\n *\n * @example DataStore#filter\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * // Get the draft posts created less than three months ago\n * let posts = store.filter('post', {\n * where: {\n * status: {\n * '==': 'draft'\n * },\n * created_at_timestamp: {\n * '>=': (new Date().getTime() - (1000 \\* 60 \\* 60 \\* 24 \\* 30 \\* 3)) // 3 months ago\n * }\n * }\n * })\n * console.log(posts)\n *\n * // Use a custom filter function\n * posts = store.filter('post', function (post) { return post.id % 2 === 0 })\n *\n * @method DataStore#filter\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(Object|Function)} [queryOrFn={}] See {@link LinkedCollection#filter}.\n * @param {Object} [thisArg] See {@link LinkedCollection#filter}.\n * @returns {Array} See {@link LinkedCollection#filter}.\n * @see LinkedCollection#filter\n * @see Collection#filter\n * @since 3.0.0\n */\n 'filter',\n\n /**\n * Wrapper for {@link LinkedCollection#get}.\n *\n * @example DataStore#get\n * // import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('post')\n * store.add('post', [\n * { id: 1, status: 'draft', created_at_timestamp: new Date().getTime() }\n * ])\n *\n * console.log(store.get('post', 1)) // {...}\n * console.log(store.get('post', 2)) // undefined\n *\n * @method DataStore#get\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id See {@link LinkedCollection#get}.\n * @returns {(Object|Record)} See {@link LinkedCollection#get}.\n * @see LinkedCollection#get\n * @see Collection#get\n * @since 3.0.0\n */\n 'get',\n\n /**\n * Wrapper for {@link LinkedCollection#getAll}.\n *\n * @example\n * // Get the posts where \"status\" is \"draft\" or \"inReview\"\n * const posts = store.getAll('post', 'draft', 'inReview', { index: 'status' })\n *\n * @example\n * // Same as above\n * const posts = store.getAll('post', ['draft'], ['inReview'], { index: 'status' })\n *\n * @method DataStore#getAll\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {...Array} [keyList] See {@link LinkedCollection#getAll}.\n * @param {Object} [opts] See {@link LinkedCollection#getAll}.\n * @returns {Array} See {@link LinkedCollection#getAll}.\n * @see LinkedCollection#getAll\n * @see Collection#getAll\n * @since 3.0.0\n */\n 'getAll',\n\n /**\n * Wrapper for {@link LinkedCollection#prune}.\n *\n * @method DataStore#prune\n * @param {Object} [opts] See {@link LinkedCollection#prune}.\n * @returns {Array} See {@link LinkedCollection#prune}.\n * @see LinkedCollection#prune\n * @see Collection#prune\n * @since 3.0.0\n */\n 'prune',\n\n /**\n * Wrapper for {@link LinkedCollection#query}.\n *\n * @example\n * // Grab page 2 of users between ages 18 and 30\n * store.query('user')\n * .between(18, 30, { index: 'age' }) // between ages 18 and 30\n * .skip(10) // second page\n * .limit(10) // page size\n * .run()\n *\n * @method DataStore#query\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @returns {Query} See {@link LinkedCollection#query}.\n * @see LinkedCollection#query\n * @see Collection#query\n * @since 3.0.0\n */\n 'query',\n\n /**\n * Wrapper for {@link LinkedCollection#toJSON}.\n *\n * @example\n * store.defineMapper('post', {\n * schema: {\n * properties: {\n * id: { type: 'number' },\n * title: { type: 'string' }\n * }\n * }\n * })\n * store.add('post', [\n * { id: 1, status: 'published', title: 'Respect your Data' },\n * { id: 2, status: 'draft', title: 'Connecting to a data source' }\n * ])\n * console.log(store.toJSON('post'))\n * const draftsJSON = store.query('post')\n * .filter({ status: 'draft' })\n * .mapCall('toJSON')\n * .run()\n *\n * @method DataStore#toJSON\n * @param {(string|number)} name Name of the {@link Mapper} to target.\n * @param {Object} [opts] See {@link LinkedCollection#toJSON}.\n * @returns {Array} See {@link LinkedCollection#toJSON}.\n * @see LinkedCollection#toJSON\n * @see Collection#toJSON\n * @since 3.0.0\n */\n 'toJSON',\n\n /**\n * Wrapper for {@link LinkedCollection#unsaved}.\n *\n * @method DataStore#unsaved\n * @returns {Array} See {@link LinkedCollection#unsaved}.\n * @see LinkedCollection#unsaved\n * @see Collection#unsaved\n * @since 3.0.0\n */\n 'unsaved'\n]\nconst ownMethodsForScoping = [\n 'addToCache',\n 'cachedFind',\n 'cachedFindAll',\n 'cacheFind',\n 'cacheFindAll',\n 'hashQuery'\n]\n\nconst cachedFn = function (name, hashOrId, opts) {\n const cached = this._completedQueries[name][hashOrId]\n if (utils.isFunction(cached)) {\n return cached(name, hashOrId, opts)\n }\n return cached\n}\n\nconst DATASTORE_DEFAULTS = {\n /**\n * Whether in-memory relations should be unlinked from records after they are\n * destroyed.\n *\n * @default true\n * @name DataStore#unlinkOnDestroy\n * @since 3.0.0\n * @type {boolean}\n */\n unlinkOnDestroy: true,\n\n /**\n * Whether to use the pending query if a `find` request for the specified\n * record is currently underway. Can be set to `true`, `false`, or to a\n * function that returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFind\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFind: true,\n\n /**\n * Whether to use the pending query if a `findAll` request for the given query\n * is currently underway. Can be set to `true`, `false`, or to a function that\n * returns `true` or `false`.\n *\n * @default true\n * @name DataStore#usePendingFindAll\n * @since 3.0.0\n * @type {boolean|Function}\n */\n usePendingFindAll: true\n}\n\n/**\n * The `DataStore` class is an extension of {@link Container}. Not only does\n * `DataStore` manage mappers, but also collections. `DataStore` implements the\n * asynchronous {@link Mapper} methods, such as {@link Mapper#find} and\n * {@link Mapper#create}. If you use the asynchronous `DataStore` methods\n * instead of calling them directly on the mappers, then the results of the\n * method calls will be inserted into the store's collections. You can think of\n * a `DataStore` as an [Identity Map](https://en.wikipedia.org/wiki/Identity_map_pattern)\n * for the [ORM](https://en.wikipedia.org/wiki/Object-relational_mapping)\n * (the Mappers).\n *\n * ```javascript\n * import {DataStore} from 'js-data'\n * ```\n *\n * @example\n * import {DataStore} from 'js-data'\n * import HttpAdapter from 'js-data-http'\n * const store = new DataStore()\n *\n * // DataStore#defineMapper returns a direct reference to the newly created\n * // Mapper.\n * const UserMapper = store.defineMapper('user')\n *\n * // DataStore#as returns the store scoped to a particular Mapper.\n * const UserStore = store.as('user')\n *\n * // Call \"find\" on \"UserMapper\" (Stateless ORM)\n * UserMapper.find(1).then((user) => {\n * // retrieved a \"user\" record via the http adapter, but that's it\n *\n * // Call \"find\" on \"store\" targeting \"user\" (Stateful DataStore)\n * return store.find('user', 1) // same as \"UserStore.find(1)\"\n * }).then((user) => {\n * // not only was a \"user\" record retrieved, but it was added to the\n * // store's \"user\" collection\n * const cachedUser = store.getCollection('user').get(1)\n * console.log(user === cachedUser) // true\n * })\n *\n * @class DataStore\n * @extends Container\n * @param {Object} [opts] Configuration options. See {@link Container}.\n * @param {boolean} [opts.collectionClass={@link LinkedCollection}] See {@link DataStore#collectionClass}.\n * @param {boolean} [opts.debug=false] See {@link Component#debug}.\n * @param {boolean} [opts.unlinkOnDestroy=true] See {@link DataStore#unlinkOnDestroy}.\n * @param {boolean|Function} [opts.usePendingFind=true] See {@link DataStore#usePendingFind}.\n * @param {boolean|Function} [opts.usePendingFindAll=true] See {@link DataStore#usePendingFindAll}.\n * @returns {DataStore}\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/working-with-the-datastore\",\"Working with the DataStore\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/jsdata-and-the-browser\",\"Notes on using JSData in the Browser\"]\n */\nfunction DataStore (opts) {\n utils.classCallCheck(this, DataStore)\n\n opts || (opts = {})\n // Fill in any missing options with the defaults\n utils.fillIn(opts, DATASTORE_DEFAULTS)\n Container.call(this, opts)\n\n this.collectionClass = this.collectionClass || LinkedCollection\n this._collections = {}\n this._pendingQueries = {}\n this._completedQueries = {}\n}\n\nconst props = {\n constructor: DataStore,\n\n /**\n * Internal method used to handle Mapper responses.\n *\n * @method DataStore#_end\n * @private\n * @param {string} name Name of the {@link LinkedCollection} to which to\n * add the data.\n * @param {Object} result The result from a Mapper.\n * @param {Object} [opts] Configuration options.\n * @returns {(Object|Array)} Result.\n */\n _end (name, result, opts) {\n let data = opts.raw ? result.data : result\n if (data && utils.isFunction(this.addToCache)) {\n data = this.addToCache(name, data, opts)\n if (opts.raw) {\n result.data = data\n } else {\n result = data\n }\n }\n return result\n },\n\n /**\n * Register a new event listener on this DataStore.\n *\n * Proxy for {@link Container#on}. If an event was emitted by a Mapper or\n * Collection in the DataStore, then the name of the Mapper or Collection will\n * be prepended to the arugments passed to the provided event handler.\n *\n * @example\n * // Listen for all \"afterCreate\" events in a DataStore\n * store.on('afterCreate', (mapperName, props, opts, result) => {\n * console.log(mapperName) // \"post\"\n * console.log(props.id) // undefined\n * console.log(result.id) // 1234\n * })\n * store.create('post', { title: 'Modeling your data' }).then((post) => {\n * console.log(post.id) // 1234\n * })\n *\n * @example\n * // Listen for the \"add\" event on a collection\n * store.on('add', (mapperName, records) => {\n * console.log(records) // [...]\n * })\n *\n * @example\n * // Listen for \"change\" events on a record\n * store.on('change', (mapperName, record, changes) => {\n * console.log(changes) // { changed: { title: 'Modeling your data' } }\n * })\n * post.title = 'Modeling your data'\n *\n * @method DataStore#on\n * @param {string} event Name of event to subsribe to.\n * @param {Function} listener Listener function to handle the event.\n * @param {*} [ctx] Optional content in which to invoke the listener.\n */\n\n /**\n * Used to bind to events emitted by collections in this store.\n *\n * @method DataStore#_onCollectionEvent\n * @private\n * @param {string} name Name of the collection that emitted the event.\n * @param {...*} [args] Args passed to {@link Collection#emit}.\n */\n _onCollectionEvent (name, ...args) {\n const type = args.shift()\n this.emit(type, name, ...args)\n },\n\n /**\n * This method takes the data received from {@link DataStore#find},\n * {@link DataStore#findAll}, {@link DataStore#update}, etc., and adds the\n * data to the store. _You don't need to call this method directly._\n *\n * If you're using the http adapter and your response data is in an unexpected\n * format, you may need to override this method so the right data gets added\n * to the store.\n *\n * @example\n * const store = new DataStore({\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return DataStore.prototype.addToCache.call(this, mapperName, data, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * addToCache (mapperName, data, opts) {\n * // Let's say for a particular Resource, response data is in a weird format\n * if (name === 'comment') {\n * // Re-assign the variable to add the correct records into the stores\n * data = data.items\n * }\n * // Now perform default behavior\n * return super.addToCache(mapperName, data, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#addToCache\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {*} data Data from which data should be selected for add.\n * @param {Object} [opts] Configuration options.\n */\n addToCache (name, data, opts) {\n return this.getCollection(name).add(data, opts)\n },\n\n /**\n * Return the store scoped to a particular mapper/collection pair.\n *\n * @example DataStore.as\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * const UserMapper = store.defineMapper('user')\n * const UserStore = store.as('user')\n *\n * const user1 = store.createRecord('user', { name: 'John' })\n * const user2 = UserStore.createRecord({ name: 'John' })\n * const user3 = UserMapper.createRecord({ name: 'John' })\n * console.log(user1 === user2)\n * console.log(user2 === user3)\n * console.log(user1 === user3)\n *\n * @method DataStore#as\n * @param {string} name Name of the {@link Mapper}.\n * @returns {Object} The store, scoped to a particular Mapper/Collection pair.\n * @since 3.0.0\n */\n as (name) {\n const props = {}\n const original = this\n const methods = ownMethodsForScoping\n .concat(proxiedMapperMethods)\n .concat(proxiedCollectionMethods)\n\n methods.forEach(function (method) {\n props[method] = {\n writable: true,\n value (...args) {\n return original[method](name, ...args)\n }\n }\n })\n props.getMapper = {\n writable: true,\n value () {\n return original.getMapper(name)\n }\n }\n props.getCollection = {\n writable: true,\n value () {\n return original.getCollection(name)\n }\n }\n return Object.create(this, props)\n },\n\n /**\n * Retrieve a cached `find` result, if any. This method is called during\n * {@link DataStore#find} to determine if {@link Mapper#find} needs to be\n * called. If this method returns `undefined` then {@link Mapper#find} will\n * be called. Otherwise {@link DataStore#find} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFind.call(this, mapperName, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFind (mapperName, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#find call\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cachedFind(mapperName, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cachedFind: cachedFn,\n\n /**\n * Retrieve a cached `findAll` result, if any. This method is called during\n * {@link DataStore#findAll} to determine if {@link Mapper#findAll} needs to be\n * called. If this method returns `undefined` then {@link Mapper#findAll} will\n * be called. Otherwise {@link DataStore#findAll} will immediately resolve with\n * the return value of this method.\n *\n * When using {@link DataStore} in the browser, you can override this method\n * to implement your own cache-busting strategy.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return undefined to trigger a Mapper#findAll call\n * return undefined\n * }\n * // Otherwise perform default behavior\n * return super.cachedFindAll(mapperName, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cachedFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cachedFindAll: cachedFn,\n\n /**\n * Mark a {@link Mapper#find} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `find` entry is\n * added it means subsequent calls to the same Resource with the same `id`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#get} instead of delegating to {@link Mapper#find}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return DataStore.prototype.cacheFind.call(this, mapperName, data, id, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cacheFind (mapperName, data, id, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior\n * return super.cacheFind(mapperName, data, id, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFind\n * @param {string} name The `name` argument passed to {@link DataStore#find}.\n * @param {*} data The result to cache.\n * @param {(string|number)} id The `id` argument passed to {@link DataStore#find}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#find}.\n * @since 3.0.0\n */\n cacheFind (name, data, id, opts) {\n this._completedQueries[name][id] = (name, id, opts) => this.get(name, id)\n },\n\n /**\n * Mark a {@link Mapper#findAll} result as cached by adding an entry to\n * {@link DataStore#_completedQueries}. By default, once a `findAll` entry is\n * added it means subsequent calls to the same Resource with the same `query`\n * argument will immediately resolve with the result of calling\n * {@link DataStore#filter} instead of delegating to {@link Mapper#findAll}.\n *\n * As part of implementing your own caching strategy, you may choose to\n * override this method.\n *\n * @example\n * const store = new DataStore({\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return DataStore.prototype.cachedFindAll.call(this, mapperName, data, hash, opts)\n * }\n * })\n *\n * @example\n * // Extend using ES2015 class syntax.\n * class MyStore extends DataStore {\n * cachedFindAll (mapperName, data, hash, opts) {\n * // Let's say for a particular Resource, we always want to pull fresh from the server\n * if (mapperName === 'schedule') {\n * // Return without saving an entry to DataStore#_completedQueries\n * return\n * }\n * // Otherwise perform default behavior.\n * return super.cachedFindAll(mapperName, data, hash, opts)\n * }\n * }\n * const store = new MyStore()\n *\n * @method DataStore#cacheFindAll\n * @param {string} name The `name` argument passed to {@link DataStore#findAll}.\n * @param {*} data The result to cache.\n * @param {string} hash The result of calling {@link DataStore#hashQuery} on\n * the `query` argument passed to {@link DataStore#findAll}.\n * @param {Object} opts The `opts` argument passed to {@link DataStore#findAll}.\n * @since 3.0.0\n */\n cacheFindAll (name, data, hash, opts) {\n this._completedQueries[name][hash] = (name, hash, opts) => this.filter(name, utils.fromJson(hash))\n },\n\n /**\n * Remove __all__ records from the in-memory store and reset\n * {@link DataStore#_completedQueries}.\n *\n * @method DataStore#clear\n * @returns {Object} Object containing all records that were in the store.\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n clear () {\n const removed = {}\n utils.forOwn(this._collections, (collection, name) => {\n removed[name] = collection.removeAll()\n this._completedQueries[name] = {}\n })\n return removed\n },\n\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~beforeCreateListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreate\n * @see DataStore~beforeCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreate} event.\n *\n * @example\n * function onBeforeCreate (mapperName, props, opts) {\n * // do something\n * }\n * store.on('beforeCreate', onBeforeCreate)\n *\n * @callback DataStore~beforeCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreate}.\n * @see DataStore#event:beforeCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#create}. See\n * {@link DataStore~afterCreateListener} for how to listen for this event.\n *\n * @event DataStore#afterCreate\n * @see DataStore~afterCreateListener\n * @see DataStore#create\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreate} event.\n *\n * @example\n * function onAfterCreate (mapperName, props, opts, result) {\n * // do something\n * }\n * store.on('afterCreate', onAfterCreate)\n *\n * @callback DataStore~afterCreateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterCreate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreate}.\n * @see DataStore#event:afterCreate\n * @see DataStore#create\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#create}. Adds the created record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book {\"author_id\":1234,...}\n * store.create('book', {\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }).then((book) => {\n * console.log(book.id) // 120392\n * console.log(book.title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreate\n * @fires DataStore#afterCreate\n * @fires DataStore#add\n * @method DataStore#create\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} record Passed to {@link Mapper#create}.\n * @param {Object} [opts] Passed to {@link Mapper#create}. See\n * {@link Mapper#create} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n create (name, record, opts) {\n opts || (opts = {})\n return Container.prototype.create.call(this, name, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~beforeCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeCreateMany\n * @see DataStore~beforeCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeCreateMany} event.\n *\n * @example\n * function onBeforeCreateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeCreateMany', onBeforeCreateMany)\n *\n * @callback DataStore~beforeCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeCreateMany}.\n * @see DataStore#event:beforeCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#createMany}. See\n * {@link DataStore~afterCreateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterCreateMany\n * @see DataStore~afterCreateManyListener\n * @see DataStore#createMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterCreateMany} event.\n *\n * @example\n * function onAfterCreateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterCreateMany', onAfterCreateMany)\n *\n * @callback DataStore~afterCreateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterCreateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterCreateMany}.\n * @see DataStore#event:afterCreateMany\n * @see DataStore#createMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#createMany}. Adds the created records to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // POST /book [{\"author_id\":1234,...},{...}]\n * store.createMany('book', [{\n * author_id: 1234,\n * edition: 'First Edition',\n * title: 'Respect your Data'\n * }, {\n * author_id: 1234,\n * edition: 'Second Edition',\n * title: 'Respect your Data'\n * }]).then((books) => {\n * console.log(books[0].id) // 142394\n * console.log(books[0].title) // \"Respect your Data\"\n * })\n *\n * @fires DataStore#beforeCreateMany\n * @fires DataStore#afterCreateMany\n * @fires DataStore#add\n * @method DataStore#createMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Array} records Passed to {@link Mapper#createMany}.\n * @param {Object} [opts] Passed to {@link Mapper#createMany}. See\n * {@link Mapper#createMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the create.\n * @since 3.0.0\n */\n createMany (name, records, opts) {\n opts || (opts = {})\n return Container.prototype.createMany.call(this, name, records, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n defineMapper (name, opts) {\n // Complexity of this method is beyond simply using => functions to bind context\n const self = this\n const mapper = Container.prototype.defineMapper.call(self, name, opts)\n self._pendingQueries[name] = {}\n self._completedQueries[name] = {}\n mapper.relationList || Object.defineProperty(mapper, 'relationList', { value: [] })\n\n // The datastore uses a subclass of Collection that is \"datastore-aware\"\n const collection = self._collections[name] = new self.collectionClass(null, { // eslint-disable-line\n // Make sure the collection has somewhere to store \"added\" timestamps\n _added: {},\n // Give the collection a reference to this datastore\n datastore: self,\n // The mapper tied to the collection\n mapper\n })\n\n const schema = mapper.schema || {}\n const properties = schema.properties || {}\n // TODO: Make it possible index nested properties?\n utils.forOwn(properties, function (opts, prop) {\n if (opts.indexed) {\n collection.createIndex(prop)\n }\n })\n\n // Create a secondary index on the \"added\" timestamps of records in the\n // collection\n collection.createIndex('addedTimestamps', ['$'], {\n fieldGetter (obj) {\n return collection._added[collection.recordId(obj)]\n }\n })\n\n collection.on('all', function (...args) {\n self._onCollectionEvent(name, ...args)\n })\n\n const idAttribute = mapper.idAttribute\n\n mapper.relationList.forEach(function (def) {\n const relation = def.relation\n const localField = def.localField\n const path = `links.${localField}`\n const foreignKey = def.foreignKey\n const type = def.type\n const updateOpts = { index: foreignKey }\n let descriptor\n\n const getter = function () { return this._get(path) }\n\n if (type === belongsToType) {\n if (!collection.indexes[foreignKey]) {\n collection.createIndex(foreignKey)\n }\n\n descriptor = {\n get: getter,\n // e.g. profile.user = someUser\n // or comment.post = somePost\n set (record) {\n // e.g. const otherUser = profile.user\n const currentParent = this._get(path)\n // e.g. profile.user === someUser\n if (record === currentParent) {\n return currentParent\n }\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n\n // e.g. profile.user !== someUser\n // or comment.post !== somePost\n if (currentParent && inverseDef) {\n this.removeInverseRelation(currentParent, id, inverseDef, idAttribute)\n }\n if (record) {\n // e.g. profile.user = someUser\n const relatedIdAttribute = def.getRelation().idAttribute\n const relatedId = utils.get(record, relatedIdAttribute)\n\n // Prefer store record\n if (relatedId !== undefined && this._get('$')) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n // e.g. profile.user = someUser\n // or comment.post = somePost\n safeSetLink(this, localField, record)\n safeSetProp(this, foreignKey, relatedId)\n collection.updateIndex(this, updateOpts)\n\n if (inverseDef) {\n this.setupInverseRelation(record, id, inverseDef, idAttribute)\n }\n } else {\n // Unset in-memory link only\n // e.g. profile.user = undefined\n // or comment.post = undefined\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n\n let foreignKeyDescriptor = Object.getOwnPropertyDescriptor(mapper.recordClass.prototype, foreignKey)\n if (!foreignKeyDescriptor) {\n foreignKeyDescriptor = {\n enumerable: true\n }\n }\n const originalGet = foreignKeyDescriptor.get\n foreignKeyDescriptor.get = function () {\n if (originalGet) {\n return originalGet.call(this)\n }\n return this._get(`props.${foreignKey}`)\n }\n const originalSet = foreignKeyDescriptor.set\n foreignKeyDescriptor.set = function (value) {\n if (originalSet) {\n originalSet.call(this, value)\n }\n const currentParent = utils.get(this, localField)\n const id = utils.get(this, idAttribute)\n const inverseDef = def.getInverse(mapper)\n const currentParentId = currentParent ? utils.get(currentParent, def.getRelation().idAttribute) : undefined\n\n if (currentParent && currentParentId !== undefined && currentParentId !== value) {\n if (inverseDef.type === hasOneType) {\n safeSetLink(currentParent, inverseDef.localField, undefined)\n } else if (inverseDef.type === hasManyType) {\n const children = utils.get(currentParent, inverseDef.localField)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n }\n }\n\n safeSetProp(this, foreignKey, value)\n collection.updateIndex(this, updateOpts)\n\n if ((value === undefined || value === null)) {\n if (currentParentId !== undefined) {\n // Unset locals\n utils.set(this, localField, undefined)\n }\n } else if (this._get('$')) {\n const storeRecord = self.get(relation, value)\n if (storeRecord) {\n utils.set(this, localField, storeRecord)\n }\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, foreignKey, foreignKeyDescriptor)\n } else if (type === hasManyType) {\n const localKeys = def.localKeys\n const foreignKeys = def.foreignKeys\n\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n\n descriptor = {\n get () {\n let current = getter.call(this)\n if (!current) {\n this._set(path, [])\n }\n return getter.call(this)\n },\n // e.g. post.comments = someComments\n // or user.groups = someGroups\n // or group.users = someUsers\n set (records) {\n if (records && !utils.isArray(records)) {\n records = [records]\n }\n const id = utils.get(this, idAttribute)\n const relatedIdAttribute = def.getRelation().idAttribute\n const inverseDef = def.getInverse(mapper)\n const inverseLocalField = inverseDef.localField\n const current = this._get(path) || []\n const toLink = []\n const toLinkIds = {}\n\n if (records) {\n records.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n const currentParent = utils.get(record, inverseLocalField)\n if (currentParent && currentParent !== this) {\n const currentChildrenOfParent = utils.get(currentParent, localField)\n // e.g. somePost.comments.remove(comment)\n if (relatedId === undefined) {\n utils.remove(currentChildrenOfParent, (child) => child === record)\n } else {\n utils.remove(currentChildrenOfParent, (child) => child === record || relatedId === utils.get(child, relatedIdAttribute))\n }\n }\n if (relatedId !== undefined) {\n if (this._get('$')) {\n // Prefer store record\n record = self.get(relation, relatedId) || record\n }\n // e.g. toLinkIds[comment.id] = comment\n toLinkIds[relatedId] = record\n }\n toLink.push(record)\n })\n }\n\n // e.g. post.comments = someComments\n if (foreignKey) {\n current.forEach((record) => {\n // e.g. comment.id\n const relatedId = utils.get(record, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(record) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update (unset) inverse relation\n if (records) {\n // e.g. comment.post_id = undefined\n safeSetProp(record, foreignKey, undefined)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n }\n // e.g. comment.post = undefined\n safeSetLink(record, inverseLocalField, undefined)\n }\n })\n toLink.forEach((record) => {\n // Update (set) inverse relation\n // e.g. comment.post_id = post.id\n safeSetProp(record, foreignKey, id)\n // e.g. CommentCollection.updateIndex(comment, { index: 'post_id' })\n self.getCollection(relation).updateIndex(record, updateOpts)\n // e.g. comment.post = post\n safeSetLink(record, inverseLocalField, this)\n })\n } else if (localKeys) {\n // Update locals\n // e.g. group.users = someUsers\n // Update (set) inverse relation\n const ids = toLink.map((child) => utils.get(child, relatedIdAttribute)).filter((id) => id !== undefined)\n // e.g. group.user_ids = [1,2,3,...]\n utils.set(this, localKeys, ids)\n // Update (unset) inverse relation\n if (inverseDef.foreignKeys) {\n current.forEach((child) => {\n const relatedId = utils.get(child, relatedIdAttribute)\n if ((relatedId === undefined && toLink.indexOf(child) === -1) || (relatedId !== undefined && !(relatedId in toLinkIds))) {\n // Update inverse relation\n // safeSetLink(child, inverseLocalField, undefined)\n const parents = utils.get(child, inverseLocalField) || []\n // e.g. someUser.groups.remove(group)\n if (id === undefined) {\n utils.remove(parents, (parent) => parent === this)\n } else {\n utils.remove(parents, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n }\n })\n toLink.forEach((child) => {\n // Update (set) inverse relation\n const parents = utils.get(child, inverseLocalField)\n // e.g. someUser.groups.push(group)\n if (id === undefined) {\n utils.noDupeAdd(parents, this, (parent) => parent === this)\n } else {\n utils.noDupeAdd(parents, this, (parent) => parent === this || id === utils.get(parent, idAttribute))\n }\n })\n }\n } else if (foreignKeys) {\n // e.g. user.groups = someGroups\n // Update (unset) inverse relation\n current.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n // e.g. someGroup.user_ids.remove(user.id)\n utils.remove(ids, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n // e.g. someGroup.users.remove(user)\n if (id === undefined) {\n utils.remove(children, (child) => child === this)\n } else {\n utils.remove(children, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n // Update (set) inverse relation\n toLink.forEach((parent) => {\n const ids = utils.get(parent, foreignKeys) || []\n utils.noDupeAdd(ids, id, (_key) => id === _key)\n const children = utils.get(parent, inverseLocalField)\n if (id === undefined) {\n utils.noDupeAdd(children, this, (child) => child === this)\n } else {\n utils.noDupeAdd(children, this, (child) => child === this || id === utils.get(child, idAttribute))\n }\n })\n }\n\n this._set(path, toLink)\n return toLink\n }\n }\n } else if (type === hasOneType) {\n // TODO: Handle case when belongsTo relation isn't ever defined\n if (self._collections[relation] && foreignKey && !self.getCollection(relation).indexes[foreignKey]) {\n self.getCollection(relation).createIndex(foreignKey)\n }\n descriptor = {\n get: getter,\n // e.g. user.profile = someProfile\n set (record) {\n const current = this._get(path)\n if (record === current) {\n return current\n }\n const inverseLocalField = def.getInverse(mapper).localField\n // Update (unset) inverse relation\n if (current) {\n safeSetProp(current, foreignKey, undefined)\n self.getCollection(relation).updateIndex(current, updateOpts)\n safeSetLink(current, inverseLocalField, undefined)\n }\n if (record) {\n const relatedId = utils.get(record, def.getRelation().idAttribute)\n // Prefer store record\n if (relatedId !== undefined) {\n record = self.get(relation, relatedId) || record\n }\n\n // Set locals\n safeSetLink(this, localField, record)\n\n // Update (set) inverse relation\n safeSetProp(record, foreignKey, utils.get(this, idAttribute))\n self.getCollection(relation).updateIndex(record, updateOpts)\n safeSetLink(record, inverseLocalField, this)\n } else {\n // Unset locals\n safeSetLink(this, localField, undefined)\n }\n return record\n }\n }\n }\n\n if (descriptor) {\n descriptor.enumerable = def.enumerable === undefined ? false : def.enumerable\n if (def.get) {\n let origGet = descriptor.get\n descriptor.get = function () {\n return def.get(def, this, (...args) => origGet.apply(this, args))\n }\n }\n if (def.set) {\n let origSet = descriptor.set\n descriptor.set = function (related) {\n return def.set(def, this, related, (value) => origSet.call(this, value === undefined ? related : value))\n }\n }\n Object.defineProperty(mapper.recordClass.prototype, localField, descriptor)\n }\n })\n\n return mapper\n },\n\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~beforeDestroyListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroy\n * @see DataStore~beforeDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroy} event.\n *\n * @example\n * function onBeforeDestroy (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeDestroy', onBeforeDestroy)\n *\n * @callback DataStore~beforeDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroy}.\n * @see DataStore#event:beforeDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroy}. See\n * {@link DataStore~afterDestroyListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroy\n * @see DataStore~afterDestroyListener\n * @see DataStore#destroy\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroy} event.\n *\n * @example\n * function onAfterDestroy (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterDestroy', onAfterDestroy)\n *\n * @callback DataStore~afterDestroyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroy}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroy}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroy}.\n * @see DataStore#event:afterDestroy\n * @see DataStore#destroy\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroy}. Removes any destroyed record from the\n * in-memory store. Clears out any {@link DataStore#_completedQueries} entries\n * associated with the provided `id`.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is no longer in the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n *\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroy\n * @fires DataStore#afterDestroy\n * @fires DataStore#remove\n * @method DataStore#destroy\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#destroy}.\n * @param {Object} [opts] Passed to {@link Mapper#destroy}. See\n * {@link Mapper#destroy} for more configuration options.\n * @returns {Promise} Resolves when the destroy operation completes.\n * @since 3.0.0\n */\n destroy (name, id, opts) {\n opts || (opts = {})\n return Container.prototype.destroy.call(this, name, id, opts).then((result) => {\n const record = this.getCollection(name).remove(id, opts)\n\n if (record && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n utils.set(record, def.localField, undefined)\n })\n }\n\n if (opts.raw) {\n result.data = record\n } else {\n result = record\n }\n delete this._pendingQueries[name][id]\n delete this._completedQueries[name][id]\n return result\n })\n },\n\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~beforeDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeDestroyAll\n * @see DataStore~beforeDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeDestroyAll} event.\n *\n * @example\n * function onBeforeDestroyAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeDestroyAll', onBeforeDestroyAll)\n *\n * @callback DataStore~beforeDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeDestroyAll}.\n * @see DataStore#event:beforeDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#destroyAll}. See\n * {@link DataStore~afterDestroyAllListener} for how to listen for this event.\n *\n * @event DataStore#afterDestroyAll\n * @see DataStore~afterDestroyAllListener\n * @see DataStore#destroyAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterDestroyAll} event.\n *\n * @example\n * function onAfterDestroyAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterDestroyAll', onAfterDestroyAll)\n *\n * @callback DataStore~afterDestroyAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterDestroyAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterDestroyAll}.\n * @see DataStore#event:afterDestroyAll\n * @see DataStore#destroyAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#destroyAll}. Removes any destroyed records from\n * the in-memory store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * store.add('book', { id: 1234, title: 'Data Management is Hard' })\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // DELETE /book/1234\n * store.destroy('book', 1234).then(() => {\n * // The book record is gone from the in-memory store\n * console.log(store.get('book', 1234)) // undefined\n * return store.find('book', 1234)\n * }).then((book) {\n * // The book was deleted from the database too\n * console.log(book) // undefined\n * })\n *\n * @fires DataStore#beforeDestroyAll\n * @fires DataStore#afterDestroyAll\n * @fires DataStore#remove\n * @method DataStore#destroyAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper#destroyAll}.\n * @param {Object} [opts] Passed to {@link Mapper#destroyAll}. See\n * {@link Mapper#destroyAll} for more configuration options.\n * @returns {Promise} Resolves when the delete completes.\n * @since 3.0.0\n */\n destroyAll (name, query, opts) {\n opts || (opts = {})\n return Container.prototype.destroyAll.call(this, name, query, opts).then((result) => {\n const records = this.getCollection(name).removeAll(query, opts)\n\n if (records && records.length && this.unlinkOnDestroy) {\n const _opts = utils.plainCopy(opts)\n _opts.withAll = true\n utils.forEachRelation(this.getMapper(name), _opts, (def) => {\n records.forEach((record) => {\n utils.set(record, def.localField, undefined)\n })\n })\n }\n\n if (opts.raw) {\n result.data = records\n } else {\n result = records\n }\n const hash = this.hashQuery(name, query, opts)\n delete this._pendingQueries[name][hash]\n delete this._completedQueries[name][hash]\n return result\n })\n },\n\n eject (name, id, opts) {\n console.warn('DEPRECATED: \"eject\" is deprecated, use \"remove\" instead')\n return this.remove(name, id, opts)\n },\n\n ejectAll (name, query, opts) {\n console.warn('DEPRECATED: \"ejectAll\" is deprecated, use \"removeAll\" instead')\n return this.removeAll(name, query, opts)\n },\n\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~beforeFindListener} for how to listen for this event.\n *\n * @event DataStore#beforeFind\n * @see DataStore~beforeFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFind} event.\n *\n * @example\n * function onBeforeFind (mapperName, id, opts) {\n * // do something\n * }\n * store.on('beforeFind', onBeforeFind)\n *\n * @callback DataStore~beforeFindListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFind}.\n * @see DataStore#event:beforeFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#find}. See\n * {@link DataStore~afterFindListener} for how to listen for this event.\n *\n * @event DataStore#afterFind\n * @see DataStore~afterFindListener\n * @see DataStore#find\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFind} event.\n *\n * @example\n * function onAfterFind (mapperName, id, opts, result) {\n * // do something\n * }\n * store.on('afterFind', onAfterFind)\n *\n * @callback DataStore~afterFindListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFind}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterFind}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFind}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFind}.\n * @see DataStore#event:afterFind\n * @see DataStore#find\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#find}. Adds any found record to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('book')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /book/1234\n * store.find('book', 1234).then((book) => {\n * // The book record is now in the in-memory store\n * console.log(store.get('book', 1234) === book) // true\n * })\n *\n * @fires DataStore#beforeFind\n * @fires DataStore#afterFind\n * @fires DataStore#add\n * @method DataStore#find\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#find}.\n * @param {Object} [opts] Passed to {@link Mapper#find}.\n * @param {boolean|Function} [opts.usePendingFind] See {@link DataStore#usePendingFind}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n find (name, id, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const pendingQuery = this._pendingQueries[name][id]\n const usePendingFind = opts.usePendingFind === undefined ? this.usePendingFind : opts.usePendingFind\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFind) ? usePendingFind.call(this, name, id, opts) : usePendingFind)) {\n return pendingQuery\n }\n const item = this.cachedFind(name, id, opts)\n let promise\n\n if (opts.force || !item) {\n promise = this._pendingQueries[name][id] = Container.prototype.find.call(this, name, id, opts).then((result) => {\n delete this._pendingQueries[name][id]\n result = this._end(name, result, opts)\n this.cacheFind(name, result, id, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][id]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(item)\n }\n return promise\n },\n\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~beforeFindAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeFindAll\n * @see DataStore~beforeFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeFindAll} event.\n *\n * @example\n * function onBeforeFindAll (mapperName, query, opts) {\n * // do something\n * }\n * store.on('beforeFindAll', onBeforeFindAll)\n *\n * @callback DataStore~beforeFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeFindAll}.\n * @see DataStore#event:beforeFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#findAll}. See\n * {@link DataStore~afterFindAllListener} for how to listen for this event.\n *\n * @event DataStore#afterFindAll\n * @see DataStore~afterFindAllListener\n * @see DataStore#findAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterFindAll} event.\n *\n * @example\n * function onAfterFindAll (mapperName, query, opts, result) {\n * // do something\n * }\n * store.on('afterFindAll', onAfterFindAll)\n *\n * @callback DataStore~afterFindAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterFindAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterFindAll}.\n * @see DataStore#event:afterFindAll\n * @see DataStore#findAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#findAll}. Adds any found records to the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('movie')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // GET /movie?rating=PG\n * store.find('movie', { rating: 'PG' }).then((movies) => {\n * // The movie records are now in the in-memory store\n * console.log(store.filter('movie'))\n * })\n *\n * @fires DataStore#beforeFindAll\n * @fires DataStore#afterFindAll\n * @fires DataStore#add\n * @method DataStore#findAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} [query] Passed to {@link Mapper.findAll}.\n * @param {Object} [opts] Passed to {@link Mapper.findAll}.\n * @param {boolean|Function} [opts.usePendingFindAll] See {@link DataStore#usePendingFindAll}\n * @returns {Promise} Resolves with the result, if any.\n * @since 3.0.0\n */\n findAll (name, query, opts) {\n opts || (opts = {})\n const mapper = this.getMapper(name)\n const hash = this.hashQuery(name, query, opts)\n const pendingQuery = this._pendingQueries[name][hash]\n const usePendingFindAll = opts.usePendingFindAll === undefined ? this.usePendingFindAll : opts.usePendingFindAll\n utils._(opts, mapper)\n\n if (pendingQuery && (utils.isFunction(usePendingFindAll) ? usePendingFindAll.call(this, name, query, opts) : usePendingFindAll)) {\n return pendingQuery\n }\n\n const items = this.cachedFindAll(name, hash, opts)\n let promise\n\n if (opts.force || !items) {\n promise = this._pendingQueries[name][hash] = Container.prototype.findAll.call(this, name, query, opts).then((result) => {\n delete this._pendingQueries[name][hash]\n result = this._end(name, result, opts)\n this.cacheFindAll(name, result, hash, opts)\n return result\n }, (err) => {\n delete this._pendingQueries[name][hash]\n return utils.reject(err)\n })\n } else {\n promise = utils.resolve(items)\n }\n return promise\n },\n\n /**\n * Return the {@link LinkedCollection} with the given name, if for some\n * reason you need a direct reference to the collection.\n *\n * @method DataStore#getCollection\n * @param {string} name Name of the {@link LinkedCollection} to retrieve.\n * @returns {LinkedCollection}\n * @since 3.0.0\n * @throws {Error} Thrown if the specified {@link LinkedCollection} does not\n * exist.\n */\n getCollection (name) {\n const collection = this._collections[name]\n if (!collection) {\n throw utils.err(`${DOMAIN}#getCollection`, name)(404, 'collection')\n }\n return collection\n },\n\n /**\n * Hashing function used to cache {@link DataStore#find} and\n * {@link DataStore#findAll} requests. This method simply JSONifies the\n * `query` argument passed to {@link DataStore#find} or\n * {@link DataStore#findAll}.\n *\n * Override this method for custom hashing behavior.\n * @method DataStore#hashQuery\n * @param {string} name The `name` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @param {Object} query The `query` argument passed to {@link DataStore#find}\n * or {@link DataStore#findAll}.\n * @returns {string} The JSONified `query`.\n * @since 3.0.0\n */\n hashQuery (name, query, opts) {\n return utils.toJson(query)\n },\n\n inject (name, records, opts) {\n console.warn('DEPRECATED: \"inject\" is deprecated, use \"add\" instead')\n return this.add(name, records, opts)\n },\n\n /**\n * Wrapper for {@link LinkedCollection#remove}. Removes the specified\n * {@link Record} from the store.\n *\n * @example DataStore#remove\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('book')\n * console.log(store.getAll('book').length)\n * store.add('book', { id: 1234 })\n * console.log(store.getAll('book').length)\n * store.remove('book', 1234)\n * console.log(store.getAll('book').length)\n *\n * @fires DataStore#remove\n * @method DataStore#remove\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {string|number} id The primary key of the {@link Record} to remove.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n remove (name, id, opts) {\n const record = this.getCollection(name).remove(id, opts)\n if (record) {\n this.removeRelated(name, [record], opts)\n }\n return record\n },\n\n /**\n * Wrapper for {@link LinkedCollection#removeAll}. Removes the selected\n * {@link Record}s from the store.\n *\n * @example DataStore#removeAll\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * const store = new DataStore()\n * store.defineMapper('movie')\n * console.log(store.getAll('movie').length)\n * store.add('movie', [{ id: 3, rating: 'R' }, { id: 4, rating: 'PG-13' })\n * console.log(store.getAll('movie').length)\n * store.removeAll('movie', { rating: 'R' })\n * console.log(store.getAll('movie').length)\n *\n * @fires DataStore#remove\n * @method DataStore#removeAll\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Object} [query={}] Selection query. See {@link query}.\n * @param {Object} [query.where] See {@link query.where}.\n * @param {number} [query.offset] See {@link query.offset}.\n * @param {number} [query.limit] See {@link query.limit}.\n * @param {string|Array[]} [query.orderBy] See {@link query.orderBy}.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record} to also\n * remove from the store.\n * @returns {Record} The removed {@link Record}s, if any.\n * @see LinkedCollection#add\n * @see Collection#add\n * @since 3.0.0\n */\n removeAll (name, query, opts) {\n const records = this.getCollection(name).removeAll(query, opts)\n if (records.length) {\n this.removeRelated(name, records, opts)\n }\n return records\n },\n\n /**\n * Remove from the store {@link Record}s that are related to the provided\n * {@link Record}(s).\n *\n * @fires DataStore#remove\n * @method DataStore#removeRelated\n * @param {string} name The name of the {@link LinkedCollection} to target.\n * @param {Record|Record[]} records {@link Record}s whose relations are to be\n * removed.\n * @param {Object} [opts] Configuration options.\n * @param {string[]} [opts.with] Relations of the {@link Record}(s) to remove\n * from the store.\n * @since 3.0.0\n */\n removeRelated (name, records, opts) {\n if (!utils.isArray(records)) {\n records = [records]\n }\n utils.forEachRelation(this.getMapper(name), opts, (def, optsCopy) => {\n records.forEach((record) => {\n let relatedData\n let query\n if (def.foreignKey && (def.type === hasOneType || def.type === hasManyType)) {\n query = { [def.foreignKey]: def.getForeignKey(record) }\n } else if (def.type === hasManyType && def.localKeys) {\n query = {\n where: {\n [def.getRelation().idAttribute]: {\n 'in': utils.get(record, def.localKeys)\n }\n }\n }\n } else if (def.type === hasManyType && def.foreignKeys) {\n query = {\n where: {\n [def.foreignKeys]: {\n 'contains': def.getForeignKey(record)\n }\n }\n }\n } else if (def.type === belongsToType) {\n relatedData = this.remove(def.relation, def.getForeignKey(record), optsCopy)\n }\n if (query) {\n relatedData = this.removeAll(def.relation, query, optsCopy)\n }\n if (relatedData) {\n if (utils.isArray(relatedData) && !relatedData.length) {\n return\n }\n if (def.type === hasOneType) {\n relatedData = relatedData[0]\n }\n def.setLocalField(record, relatedData)\n }\n })\n })\n },\n\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~beforeUpdateListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdate\n * @see DataStore~beforeUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdate} event.\n *\n * @example\n * function onBeforeUpdate (mapperName, id, props, opts) {\n * // do something\n * }\n * store.on('beforeUpdate', onBeforeUpdate)\n *\n * @callback DataStore~beforeUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdate}.\n * @see DataStore#event:beforeUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#update}. See\n * {@link DataStore~afterUpdateListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdate\n * @see DataStore~afterUpdateListener\n * @see DataStore#update\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdate} event.\n *\n * @example\n * function onAfterUpdate (mapperName, id, props, opts, result) {\n * // do something\n * }\n * store.on('afterUpdate', onAfterUpdate)\n *\n * @callback DataStore~afterUpdateListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdate}.\n * @param {string|number} id The `id` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdate}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdate}.\n * @see DataStore#event:afterUpdate\n * @see DataStore#update\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#update}. Adds the updated {@link Record} to the\n * store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post/1234 {\"status\":\"published\"}\n * store.update('post', 1, { status: 'published' }).then((post) => {\n * // The post record has also been updated in the in-memory store\n * console.log(store.get('post', 1234))\n * })\n *\n * @fires DataStore#beforeUpdate\n * @fires DataStore#afterUpdate\n * @fires DataStore#add\n * @method DataStore#update\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(string|number)} id Passed to {@link Mapper#update}.\n * @param {Object} record Passed to {@link Mapper#update}.\n * @param {Object} [opts] Passed to {@link Mapper#update}. See\n * {@link Mapper#update} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n update (name, id, record, opts) {\n opts || (opts = {})\n return Container.prototype.update.call(this, name, id, record, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~beforeUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateAll\n * @see DataStore~beforeUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateAll} event.\n *\n * @example\n * function onBeforeUpdateAll (mapperName, props, query, opts) {\n * // do something\n * }\n * store.on('beforeUpdateAll', onBeforeUpdateAll)\n *\n * @callback DataStore~beforeUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#beforeUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateAll}.\n * @see DataStore#event:beforeUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateAll}. See\n * {@link DataStore~afterUpdateAllListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateAll\n * @see DataStore~afterUpdateAllListener\n * @see DataStore#updateAll\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateAll} event.\n *\n * @example\n * function onAfterUpdateAll (mapperName, props, query, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateAll', onAfterUpdateAll)\n *\n * @callback DataStore~afterUpdateAllListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} props The `props` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} query The `query` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateAll}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateAll}.\n * @see DataStore#event:afterUpdateAll\n * @see DataStore#updateAll\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateAll}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post?author_id=1234 {\"status\":\"published\"}\n * store.updateAll('post', { author_id: 1234 }, { status: 'published' }).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.filter('posts', { author_id: 1234 }))\n * })\n *\n * @fires DataStore#beforeUpdateAll\n * @fires DataStore#afterUpdateAll\n * @fires DataStore#add\n * @method DataStore#updateAll\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {Object} props Passed to {@link Mapper#updateAll}.\n * @param {Object} [query] Passed to {@link Mapper#updateAll}.\n * @param {Object} [opts] Passed to {@link Mapper#updateAll}. See\n * {@link Mapper#updateAll} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateAll (name, props, query, opts) {\n opts || (opts = {})\n return Container.prototype.updateAll.call(this, name, query, props, opts)\n .then((result) => this._end(name, result, opts))\n },\n\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~beforeUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#beforeUpdateMany\n * @see DataStore~beforeUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:beforeUpdateMany} event.\n *\n * @example\n * function onBeforeUpdateMany (mapperName, records, opts) {\n * // do something\n * }\n * store.on('beforeUpdateMany', onBeforeUpdateMany)\n *\n * @callback DataStore~beforeUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#beforeUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#beforeUpdateMany}.\n * @see DataStore#event:beforeUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Fired during {@link DataStore#updateMany}. See\n * {@link DataStore~afterUpdateManyListener} for how to listen for this event.\n *\n * @event DataStore#afterUpdateMany\n * @see DataStore~afterUpdateManyListener\n * @see DataStore#updateMany\n */\n /**\n * Callback signature for the {@link DataStore#event:afterUpdateMany} event.\n *\n * @example\n * function onAfterUpdateMany (mapperName, records, opts, result) {\n * // do something\n * }\n * store.on('afterUpdateMany', onAfterUpdateMany)\n *\n * @callback DataStore~afterUpdateManyListener\n * @param {string} name The `name` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} records The `records` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} opts The `opts` argument received by {@link Mapper#afterUpdateMany}.\n * @param {Object} result The `result` argument received by {@link Mapper#afterUpdateMany}.\n * @see DataStore#event:afterUpdateMany\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n /**\n * Wrapper for {@link Mapper#updateMany}. Adds the updated {@link Record}s to\n * the store.\n *\n * @example\n * import {DataStore} from 'js-data'\n * import {HttpAdapter} from 'js-data-http'\n *\n * const store = new DataStore()\n * store.registerAdapter('http', new HttpAdapter(), { default: true })\n *\n * store.defineMapper('post')\n *\n * // Since this example uses the http adapter, we'll get something like:\n * //\n * // PUT /post [{\"id\":3,status\":\"published\"},{\"id\":4,status\":\"published\"}]\n * store.updateMany('post', [\n * { id: 3, status: 'published' },\n * { id: 4, status: 'published' }\n * ]).then((posts) => {\n * // The post records have also been updated in the in-memory store\n * console.log(store.getAll('post', 3, 4))\n * })\n *\n * @fires DataStore#beforeUpdateMany\n * @fires DataStore#afterUpdateMany\n * @fires DataStore#add\n * @method DataStore#updateMany\n * @param {string} name Name of the {@link Mapper} to target.\n * @param {(Object[]|Record[])} records Passed to {@link Mapper#updateMany}.\n * @param {Object} [opts] Passed to {@link Mapper#updateMany}. See\n * {@link Mapper#updateMany} for more configuration options.\n * @returns {Promise} Resolves with the result of the update.\n * @since 3.0.0\n */\n updateMany (name, records, opts) {\n opts || (opts = {})\n return Container.prototype.updateMany.call(this, name, records, opts)\n .then((result) => this._end(name, result, opts))\n }\n}\n\nproxiedCollectionMethods.forEach(function (method) {\n props[method] = function (name, ...args) {\n return this.getCollection(name)[method](...args)\n }\n})\n\nexport default Container.extend(props)\n\n/**\n * Fired when a record changes. Only works for records that have tracked fields.\n * See {@link DataStore~changeListener} on how to listen for this event.\n *\n * @event DataStore#change\n * @see DataStore~changeListener\n */\n\n/**\n * Callback signature for the {@link DataStore#event:change} event.\n *\n * @example\n * function onChange (mapperName, record, changes) {\n * // do something\n * }\n * store.on('change', onChange)\n *\n * @callback DataStore~changeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record} record The Record that changed.\n * @param {Object} changes The changes.\n * @see DataStore#event:change\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are added to the in-memory store. See\n * {@link DataStore~addListener} on how to listen for this event.\n *\n * @event DataStore#add\n * @see DataStore~addListener\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n */\n\n/**\n * Callback signature for the {@link DataStore#event:add} event.\n *\n * @example\n * function onAdd (mapperName, recordOrRecords) {\n * // do something\n * }\n * store.on('add', onAdd)\n *\n * @callback DataStore~addListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} The Record or Records that were added.\n * @see DataStore#event:add\n * @see DataStore#add\n * @see DataStore#create\n * @see DataStore#createMany\n * @see DataStore#find\n * @see DataStore#findAll\n * @see DataStore#update\n * @see DataStore#updateAll\n * @see DataStore#updateMany\n * @since 3.0.0\n */\n\n/**\n * Fired when one or more records are removed from the in-memory store. See\n * {@link DataStore~removeListener} for how to listen for this event.\n *\n * @event DataStore#remove\n * @see DataStore~removeListener\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n */\n\n/**\n * Callback signature for the {@link DataStore#event:remove} event.\n *\n * @example\n * function onRemove (mapperName, recordsOrRecords) {\n * // do something\n * }\n * store.on('remove', onRemove)\n *\n * @callback DataStore~removeListener\n * @param {string} name The name of the associated {@link Mapper}.\n * @param {Record|Record[]} Record or Records that were removed.\n * @see DataStore#event:remove\n * @see DataStore#clear\n * @see DataStore#destroy\n * @see DataStore#destroyAll\n * @see DataStore#remove\n * @see DataStore#removeAll\n * @since 3.0.0\n */\n\n/**\n * Create a subclass of this DataStore:\n * @example DataStore.extend\n * // Normally you would do: import {DataStore} from 'js-data'\n * const JSData = require('js-data@3.0.0-beta.10')\n * const {DataStore} = JSData\n * console.log('Using JSData v' + JSData.version.full)\n *\n * // Extend the class using ES2015 class syntax.\n * class CustomDataStoreClass extends DataStore {\n * foo () { return 'bar' }\n * static beep () { return 'boop' }\n * }\n * const customDataStore = new CustomDataStoreClass()\n * console.log(customDataStore.foo())\n * console.log(CustomDataStoreClass.beep())\n *\n * // Extend the class using alternate method.\n * const OtherDataStoreClass = DataStore.extend({\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const otherDataStore = new OtherDataStoreClass()\n * console.log(otherDataStore.foo())\n * console.log(OtherDataStoreClass.beep())\n *\n * // Extend the class, providing a custom constructor.\n * function AnotherDataStoreClass () {\n * DataStore.call(this)\n * this.created_at = new Date().getTime()\n * }\n * DataStore.extend({\n * constructor: AnotherDataStoreClass,\n * foo () { return 'bar' }\n * }, {\n * beep () { return 'boop' }\n * })\n * const anotherDataStore = new AnotherDataStoreClass()\n * console.log(anotherDataStore.created_at)\n * console.log(anotherDataStore.foo())\n * console.log(AnotherDataStoreClass.beep())\n *\n * @method DataStore.extend\n * @param {Object} [props={}] Properties to add to the prototype of the\n * subclass.\n * @param {Object} [props.constructor] Provide a custom constructor function\n * to be used as the subclass itself.\n * @param {Object} [classProps={}] Static properties to add to the subclass.\n * @returns {Constructor} Subclass of this DataStore class.\n * @since 3.0.0\n */\n","/**\n * Registered as `js-data` in NPM and Bower.\n *\n * Also available from CDN.JS and JSDelivr.\n *\n * @module js-data\n *\n * @example Install from NPM\n * npm i --save js-data@beta\n * @example Install from Bower\n * bower i --save js-data@3.0.0-beta.1\n * @example Install from CDN.JS\n * \n * @example Install from JSDelivr\n * \n * @example Load into your app via script tag\n * \n * \n * @example Load into your app via CommonJS\n * var JSData = require('js-data');\n * @example Load into your app via ES2015 Modules\n * import * as JSData from 'js-data';\n * @example Load into your app via AMD\n * define('myApp', ['js-data'], function (JSData) { ... })\n */\n\n/**\n * Describes the version of this `JSData` object.\n *\n * @example\n * console.log(JSData.version.full) // \"3.0.0-beta.1\"\n *\n * @name version\n * @memberof module:js-data\n * @property {string} full The full semver value.\n * @property {number} major The major version number.\n * @property {number} minor The minor version number.\n * @property {number} patch The patch version number.\n * @property {(string|boolean)} alpha The alpha version value, otherwise `false`\n * if the current version is not alpha.\n * @property {(string|boolean)} beta The beta version value, otherwise `false`\n * if the current version is not beta.\n * @since 2.0.0\n * @type {Object}\n */\nexport const version = '<%= version %>'\n\n/**\n * JSData's utility methods.\n *\n * @example\n * import {utils} from 'js-data'\n * console.log(utils.isString('foo')) // true\n *\n * @name module:js-data.utils\n * @property {Function} Promise See {@link utils.Promise}.\n * @see utils\n * @since 3.0.0\n * @type {Object}\n */\nimport utils from './utils'\n\n/**\n * JSData's {@link Collection} class.\n *\n * @example\n * import {Collection} from 'js-data'\n * const collection = new Collection()\n *\n * @name module:js-data.Collection\n * @see Collection\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#collection\",\"Components of JSData: Collection\"]\n * @type {Constructor}\n */\nimport Collection from './Collection'\n\n/**\n * JSData's {@link Component} class. Most components in JSData extend this\n * class.\n *\n * @example\n * import {Component} from 'js-data'\n * // Make a custom component.\n * const MyComponent = Component.extend({\n * myMethod (someArg) { ... }\n * })\n *\n * @name module:js-data.Component\n * @see Component\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Component from './Component'\n\n/**\n * JSData's {@link Container} class. Defines and manages {@link Mapper}s. Used\n * in Node.js and in the browser, though in the browser you may want to use\n * {@link DataStore} instead.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n *\n * @name module:js-data.Container\n * @see Container\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#container\",\"Components of JSData: Container\"]\n * @type {Constructor}\n */\nimport {Container} from './Container'\n\n/**\n * JSData's {@link DataStore} class. Primarily for use in the browser. In\n * Node.js you probably want to use {@link Container} instead.\n *\n * @example\n * import {DataStore} from 'js-data'\n * const store = new DataStore()\n *\n * @name module:js-data.DataStore\n * @see DataStore\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#datastore\",\"Components of JSData: DataStore\"]\n * @type {Constructor}\n */\nimport DataStore from './DataStore'\n\n/**\n * JSData's {@link Index} class, based on [mindex]{@link https://github.com/internalfx/mindex}.\n *\n * @name module:js-data.Index\n * @see Index\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Index from '../lib/mindex/index'\n\n/**\n * JSData's {@link LinkedCollection} class. Used by the {@link DataStore}\n * component. If you need to create a collection manually, you should probably\n * use the {@link Collection} class.\n *\n * @name module:js-data.LinkedCollection\n * @see DataStore\n * @see LinkedCollection\n * @since 3.0.0\n * @type {Constructor}\n */\nimport LinkedCollection from './LinkedCollection'\n\n/**\n * JSData's {@link Mapper} class. The core of the ORM.\n *\n * @example Recommended use\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n *\n * @example Create Mapper manually\n * import {Mapper} from 'js-data'\n * const UserMapper = new Mapper({ name: 'user' })\n *\n * @name module:js-data.Mapper\n * @see Container\n * @see Mapper\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/modeling-your-data\",\"Modeling your data\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#mapper\",\"Components of JSData: Mapper\"]\n * @type {Constructor}\n */\nimport Mapper from './Mapper'\n\n/**\n * JSData's {@link Query} class. Used by the {@link Collection} component.\n *\n * @name module:js-data.Query\n * @see Query\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Query from './Query'\n\n/**\n * JSData's {@link Record} class.\n *\n * @example\n * import {Container} from 'js-data'\n * const store = new Container()\n * store.defineMapper('user')\n * const user = store.createRecord('user')\n *\n * @name module:js-data.Record\n * @see Record\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#record\",\"Components of JSData: Record\"]\n * @type {Constructor}\n */\nimport Record from './Record'\n\n/**\n * JSData's {@link Schema} class. Implements http://json-schema.org/draft-04.\n *\n * @example\n * import {Container, Schema} from 'js-data'\n * const userSchema = new Schema({\n * properties: {\n * id: { type: 'string' },\n * name: { type: 'string' }\n * }\n * })\n * const store = new Container()\n * store.defineMapper('user', {\n * schema: userSchema\n * })\n *\n * @name module:js-data.Schema\n * @see Schema\n * @see http://json-schema.org/\n * @since 3.0.0\n * @tutorial [\"http://www.js-data.io/v3.0/docs/components-of-jsdata#schema\",\"Components of JSData: schema\"]\n * @tutorial [\"http://www.js-data.io/v3.0/docs/schemas\",\"JSData's Schema Syntax\"]\n * @type {Constructor}\n */\nimport Schema from './Schema'\n\n/**\n * JSData's {@link Settable} class.\n *\n * @example\n * import {Settable} from 'js-data'\n * const obj = new Settable()\n * obj.set('secret', 'value')\n * console.log(JSON.stringify(obj)) // {}\n *\n * @name module:js-data.Settable\n * @see Settable\n * @since 3.0.0\n * @type {Constructor}\n */\nimport Settable from './Settable'\n\nexport * from './decorators'\n\nexport {\n Collection,\n Component,\n Container,\n DataStore,\n Index,\n LinkedCollection,\n Mapper,\n Query,\n Record,\n Schema,\n Settable,\n utils\n}\n"],"names":["DOMAIN","Component","Query","Schema","Record","_belongsTo","_hasMany","_hasOne","Mapper","Collection","LinkedCollection","props"],"mappings":"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"} \ No newline at end of file diff --git a/dist/js-data.min.js b/dist/js-data.min.js index d6f37c92..dad9f4d5 100644 --- a/dist/js-data.min.js +++ b/dist/js-data.min.js @@ -1,13 +1,13 @@ /*! * js-data -* @version 3.0.0-rc.3 - Homepage +* @version 3.0.0-rc.4 - Homepage * @author js-data project authors * @copyright (c) 2014-2016 js-data project authors * @license MIT * * @overview js-data is a framework-agnostic, datastore-agnostic ORM/ODM for Node.js and the Browser. */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define("js-data",["exports"],t):t(e.JSData=e.JSData||{})}(this,function(e){"use strict";function Settable(){var e={};Object.defineProperties(this,{_get:{value:function value(t){return O.get(e,t)}},_set:{value:function value(t,n){return O.set(e,t,n)}},_unset:{value:function value(t){return O.unset(e,t)}}})}function Component(e){Settable.call(this),e||(e={}),this.debug=!!e.hasOwnProperty("debug")&&!!e.debug,Object.defineProperty(this,"_listeners",{value:{},writable:!0})}function Query(e){O.classCallCheck(this,Query),this.collection=e,this.data=null}function sort(e,t,n){return e===t?0:(n&&(e=n(e),t=n(t)),null===e&&null===t||void 0===e&&void 0===t?-1:null===e||void 0===e?-1:null===t||void 0===t?1:et?1:0)}function insertAt(e,t,n){return e.splice(t,0,n),e}function removeAt(e,t){return e.splice(t,1),e}function binarySearch(e,t,n){for(var i=0,r=e.length,o=void 0,a=void 0;i=0?o=r:(a=O._getIndex(e.with,t.localField))>=0&&(o=t.localField),e.withAll)return void n.call(i,t,{});if(o){var s={};O.fillIn(s,t.getRelation()),O.fillIn(s,e),s.with=e.with.slice(),s._activeWith=s.with.splice(a,1)[0],s.with.forEach(function(e,t){e&&0===e.indexOf(o)&&e.length>=o.length&&"."===e[o.length]?s.with[t]=e.substr(o.length+1):s.with[t]=""}),n.call(i,t,s)}},_getIndex:function _getIndex(e,t){var n=-1;return e.forEach(function(e,i){return e===t?(n=i,!1):O.isObject(e)&&e.relation===t?(n=i,!1):void 0}),n},addHiddenPropsToTarget:function addHiddenPropsToTarget(e,t){var n={};Object.keys(t).forEach(function(e){var i=Object.getOwnPropertyDescriptor(t,e);i.enumerable=!1,n[e]=i}),Object.defineProperties(e,n)},areDifferent:function areDifferent(e,t,n){n||(n={});var i=O.diffObjects(e,t,n),r=Object.keys(i.added).length+Object.keys(i.removed).length+Object.keys(i.changed).length;return r>0},classCallCheck:function classCallCheck(e,t){if(!(e instanceof t))throw O.err(""+t.name)(500,"Cannot call a class as a function")},copy:function copy(e,t,n,i,o,a){if(t){if(e===t)throw O.err(r+".copy")(500,"Cannot copy! Source and destination are identical.");if(n=n||[],i=i||[],O.isObject(e)){var s=n.indexOf(e);if(s!==-1)return i[s];n.push(e),i.push(t)}var u=void 0;if(O.isArray(e)){var c=void 0;for(t.length=0,c=0;c1?t-1:0),i=1;i=0&&e.splice(n,1)}},resolve:function resolve(e){return O.Promise.resolve(e)},set:function set(e,t,n){if(O.isObject(t))O.forOwn(t,function(t,n){O.set(e,n,t)});else{var i=v.exec(t);i?A(e,i[1])[i[2]]=n:e[t]=n}},deepEqual:function deepEqual(e,t){if(e===t)return!0;var n=!0;if(O.isObject(e)&&O.isObject(t)){if(O.forOwn(e,function(e,i){n=n&&O.deepEqual(e,t[i])}),!n)return n;O.forOwn(t,function(t,i){n=n&&O.deepEqual(t,e[i])})}else{if(!O.isArray(e)||!O.isArray(t))return!1;e.forEach(function(e,i){if(n=n&&O.deepEqual(e,t[i]),!n)return!1})}return n},toJson:JSON.stringify,unset:function unset(e,t){for(var n=t.split("."),i=n.pop();t=n.shift();)if(e=e[t],null==e)return;e[i]=void 0}};Settable.extend=O.extend;var _=Settable.extend({constructor:Component});Component.extend=O.extend,O.logify(Component.prototype),O.eventify(Component.prototype,function(){return this._listeners},function(e){this._listeners=e});var x="Query",w="Index inaccessible after first operation",C={limit:"",offset:"",orderBy:"",skip:"",sort:"",where:""},F=/([.*+?^=!:${}()|[\]\/\\])/g,R=/%/g,E=/_/g,k=function escape(e){return e.replace(F,"\\$1")},I=_.extend({constructor:Query,_applyWhereFromObject:function _applyWhereFromObject(e){var t=[],n=[],i=[];return O.forOwn(e,function(e,r){O.isObject(e)||(e={"==":e}),O.forOwn(e,function(e,o){t.push(r),n.push(o),i.push(e)})}),{fields:t,ops:n,predicates:i}},_applyWhereFromArray:function _applyWhereFromArray(e){var t=this,n=[];return e.forEach(function(i,r){if(!O.isString(i)){var o=e[r-1],a=O.isArray(i)?t._applyWhereFromArray:t._applyWhereFromObject,s=a.call(t,i);"or"===o&&(s.isOr=!0),n.push(s)}}),n.isArray=!0,n},_testObjectGroup:function _testObjectGroup(e,t,n,i){var r=void 0,o=n.fields,a=n.ops,s=n.predicates,u=a.length;for(r=0;ra?1:t1?t-1:0),i=1;i":function _(e,t){return e>t},">=":function _(e,t){return e>=t},"<":function _(e,t){return e=0;i--){var r=n[i];t=r.isIndex?t.concat(r.getAll(e)):t.concat(r)}else for(var o=0;oo)break}else if(this.keys[s]>=o)break;if(i=this.values[s].isIndex?i.concat(this.values[s].getAll()):i.concat(this.values[s]),n.limit&&i.length>=n.limit+n.offset)break}}else for(var u=a.index;uo)break;if(i=this.values[u].isIndex?c===r?i.concat(this.values[u]._between(O.copy(e),t.map(function(){}),n)):c===o?i.concat(this.values[u]._between(e.map(function(){}),O.copy(t),n)):i.concat(this.values[u].getAll()):i.concat(this.values[u]),n.limit&&i.length>=n.limit+n.offset)break}return n.limit?i.slice(0,n.limit+n.offset):i},peek:function peek(){return this.values.length?this.values[0].isIndex?this.values[0].peek():this.values[0]:[]},clear:function clear(){this.keys=[],this.values=[]},insertRecord:function insertRecord(e){var t=this.fieldList.map(function(t){return O.isFunction(t)?t(e)||void 0:e[t]||void 0});this.set(t,e)},removeRecord:function removeRecord(e){var t=this,n=void 0,i=void 0!==this.hashCode(e);return this.values.forEach(function(r,o){if(r.isIndex){if(r.removeRecord(e))return 0===r.keys.length&&(removeAt(t.keys,o),removeAt(t.values,o)),n=!0,!1}else{var a={};if(void 0!==t.keys[o]&&i)i&&(a=binarySearch(r,e,t.hashCode));else for(var s=r.length-1;s>=0;s--)if(r[s]===e){a={found:!0,index:s};break}if(a.found)return removeAt(r,a.index),0===r.length&&(removeAt(t.keys,o),removeAt(t.values,o)),n=!0,!1}}),n?e:void 0},updateRecord:function updateRecord(e){var t=this.removeRecord(e);void 0!==t&&this.insertRecord(e)}});var j="Collection",S={commitOnMerge:!0,idAttribute:"id",onConflict:"merge"},L=_.extend({constructor:Collection,_onRecordEvent:function _onRecordEvent(){this.emit.apply(this,arguments)},add:function add(e,t){var n=this;t||(t={}),O._(t,this),e=this.beforeAdd(e,t)||e;var i=!1,r=this.recordId();if(!O.isArray(e)){if(!O.isObject(e))throw O.err(j+"#add","records")(400,"object or array",e);e=[e],i=!0}e=e.map(function(e){var i=n.recordId(e),o=void 0===i?i:n.get(i);if(e===o)return o;if(o){var a=t.onConflict||n.onConflict;if("merge"===a)O.deepMixIn(o,e);else{if("replace"!==a)throw O.err(j+"#add","opts.onConflict")(400,"one of (merge, replace)",a,!0);O.forOwn(o,function(t,n){n!==r&&void 0===e[n]&&(o[n]=void 0)}),o.set(e)}e=o,t.commitOnMerge&&O.isFunction(e.commit)&&e.commit(),n.updateIndexes(e)}else e=n.mapper?n.mapper.createRecord(e,t):e,n.index.insertRecord(e),O.forOwn(n.indexes,function(t,n){t.insertRecord(e)}),e&&O.isFunction(e.on)&&e.on("all",n._onRecordEvent,n);return e});var o=i?e[0]:e;return this.emit("add",o),this.afterAdd(e,t,o)||o},afterAdd:function afterAdd(){},afterRemove:function afterRemove(){},afterRemoveAll:function afterRemoveAll(){},beforeAdd:function beforeAdd(){},beforeRemove:function beforeRemove(){},beforeRemoveAll:function beforeRemoveAll(){},between:function between(e,t,n){return this.query().between(e,t,n).run()},createIndex:function createIndex(e,t,n){var i=this;O.isString(e)&&void 0===t&&(t=[e]),n||(n={}),n.hashCode||(n.hashCode=function(e){return i.recordId(e)});var r=this.indexes[e]=new Index(t,n);this.index.visitAll(r.insertRecord,r)},filter:function filter(e,t){return this.query().filter(e,t).run()},forEach:function forEach(e,t){this.index.visitAll(e,t)},get:function get(e){var t=this.query().get(e).run();return t.length?t[0]:void 0},getAll:function getAll(){var e;return(e=this.query()).getAll.apply(e,arguments).run()},getIndex:function getIndex(e){var t=e?this.indexes[e]:this.index;if(!t)throw O.err(j+"#getIndex",e)(404,"index");return t},limit:function limit(e){return this.query().limit(e).run()},map:function map(e,t){var n=[];return this.index.visitAll(function(i){n.push(e.call(t,i))}),n},mapCall:function mapCall(e){for(var t=arguments.length,n=Array(t>1?t-1:0),i=1;ir)return J(t.length,"length no more than "+r,i)},U=function minLengthCommon(e,t,n,i){var r=n[e];if(t.lengthe:maximum>=e))return r?J(e,"no more than nor equal to "+maximum,i):J(e,"no more than "+maximum,i)},maxItems:function maxItems(e,t,n){if(O.isArray(e))return B("maxItems",e,t,n)},maxLength:function maxLength(e,t,n){return B("maxLength",e,t,n)},maxProperties:function maxProperties(e,t,n){if(O.isObject(e)){var maxProperties=t.maxProperties,i=Object.keys(e).length;return i>maxProperties?J(i,"no more than "+maxProperties+" properties",n):void 0}},minimum:function minimum(e,n,i){ -var minimum=n.minimum,r=n.exclusiveMinimum;if(("undefined"==typeof e?"undefined":t(e))===("undefined"==typeof minimum?"undefined":t(minimum))&&!(r?e>minimum:e>=minimum))return r?J(e,"no less than nor equal to "+minimum,i):J(e,"no less than "+minimum,i)},minItems:function minItems(e,t,n){if(O.isArray(e))return U("minItems",e,t,n)},minLength:function minLength(e,t,n){return U("minLength",e,t,n)},minProperties:function minProperties(e,t,n){if(O.isObject(e)){var minProperties=t.minProperties,i=Object.keys(e).length;return i0;o--)for(r=e[o],a=o-1;a>=0;a--)if(O.deepEqual(r,e[a]))return J(r,"no duplicates",n)}}},G=function validateKeyword(e,t,n,i){return void 0!==n[e]&&$[e](t,n,i)},V=function runOps(e,t,n,i){var r=[];return e.forEach(function(e){r=r.concat(G(e,t,n,i)||[])}),r.length?r:void 0},H=["enum","type","allOf","anyOf","oneOf","not"],W=["items","maxItems","minItems","uniqueItems"],Y=["multipleOf","maximum","minimum"],z=["maxProperties","minProperties","required","properties","dependencies"],X=["maxLength","minLength","pattern"],Z=function validateAny(e,t,n){return V(H,e,t,n)},ee=function _validate(e,t,n){var i=[];n||(n={}),n.ctx||(n.ctx={value:e,schema:t});var r=void 0,o=n.prop;if(void 0!==t){if(!O.isObject(t))throw O.err(N+"#validate")(500,'Invalid schema at path: "'+n.path+'"');return void 0===n.path&&(n.path=[]),void 0!==n.prop&&(r=!0,n.path.push(n.prop),n.prop=void 0),t.extends&&(i=O.isFunction(t.extends.validate)?i.concat(t.extends.validate(e,n)||[]):i.concat(_validate(e,t.extends,n)||[])),void 0===e?(t.required!==!0||n.existingOnly||Q(e,"a value",n,i),r&&(n.path.pop(),n.prop=o),i.length?i:void 0):(i=i.concat(Z(e,t,n)||[]),r&&(n.path.pop(),n.prop=o),i.length?i:void 0)}},te="changing",ne="changed",ie="history",re="creating",oe="eventId",ae="noValidate",se="silent",ue="validation failed",ce=function makeDescriptor(e,t,n){var i={configurable:!0,enumerable:void 0===t.enumerable||!!t.enumerable},r="props."+e,o="previous."+e,a=n.getter,s=n.setter,u=n.unsetter,c=O.isBoolean(n.track)?n.track:t.track;return i.get=function(){return this._get(r)},O.isFunction(t.get)&&!function(){var e=i.get;i.get=function(){return t.get.call(this,e)}}(),i.set=function(n){var i=this,l=this[a],f=this[s],d=this[u];if(!l(ae)){var h=t.validate(n,{path:[e]});if(h){var p=new Error(ue);throw p.errors=h,p}}return c&&!l(re)&&!function(){var t=l(o),a=l(r),s=l(te),u=l(ne);s||(u=[]);var c=u.indexOf(e);a!==n&&c===-1&&u.push(e),t===n&&c>=0&&u.splice(c,1),u.length||(s=!1,d(te),d(ne),l(oe)&&(clearTimeout(l(oe)),d(oe))),!s&&u.length&&(f(ne,u),f(te,!0),f(oe,setTimeout(function(){if(d(ne),d(oe),d(te),!l(se)){var e=void 0;for(e=0;e")(400,"string",r)},canFindLinkFor:function canFindLinkFor(e){var t=this.foreignKey||this.foreignKeys;return!!(t||this.localKeys&&O.get(e,this.localKeys))},unlinkInverseRecords:function unlinkInverseRecords(e){if(e){var t=this.getInverse(this.mapper).localField;e.forEach(function(e){O.set(e,t,void 0)})}},linkRecord:function linkRecord(e,t){var n=this,i=this.relatedCollection,r=this.canAutoAddLinks,o=this.foreignKey,a=this.relatedCollection.unsaved();return t.map(function(t){var s=i.recordId(t);return(void 0===s&&a.indexOf(t)===-1||t!==i.get(s))&&(o&&n.setForeignKey(e,t),r&&(t=i.add(t))),t})},findExistingLinksFor:function findExistingLinksFor(e){var t=O.get(e,this.mapper.idAttribute),n=this.localKeys?O.get(e,this.localKeys):null,i=void 0;if(void 0!==t&&this.foreignKey?i=this.findExistingLinksByForeignKey(t):this.localKeys&&n?i=this.findExistingLinksByLocalKeys(n):void 0!==t&&this.foreignKeys&&(i=this.findExistingLinksByForeignKeys(t)),i&&i.length)return i},findExistingLinksByLocalKeys:function findExistingLinksByLocalKeys(e){return this.relatedCollection.filter({where:n({},this.mapper.idAttribute,{in:e})})},findExistingLinksByForeignKeys:function findExistingLinksByForeignKeys(e){return this.relatedCollection.filter({where:n({},this.foreignKeys,{contains:e})})}},{TYPE_NAME:"hasMany"}),me=Relation.extend({findExistingLinksFor:function findExistingLinksFor(e,t){var n=O.get(t,e.idAttribute),i=this.findExistingLinksByForeignKey(n);if(i.length)return i[0]}},{TYPE_NAME:"hasOne"});[ge,ye,me].forEach(function(e){Relation[e.TYPE_NAME]=function(t,n){return new e(t,n)}});var be=function belongsTo(e,t){return function(n){Relation.belongsTo(e,t).assignTo(n)}},Ae=function hasMany(e,t){return function(n){Relation.hasMany(e,t).assignTo(n)}},Oe=function hasOne(e,t){return function(n){Relation.hasOne(e,t).assignTo(n)}},_e="Mapper",xe=["beforeCreate","beforeCreateMany"],we=["beforeCreate","beforeCreateMany","beforeUpdate","beforeUpdateAll","beforeUpdateMany"],Ce=function makeNotify(e){return function(){for(var t=this,n=arguments.length,i=Array(n),r=0;r1?n-1:0),o=1;o1?t-1:0),i=1;i1?i-1:0),o=1;o1?t-1:0),i=1;i1?t-1:0),i=1;i1?i-1:0),o=1;ot?1:0)}function insertAt(e,t,n){return e.splice(t,0,n),e}function removeAt(e,t){return e.splice(t,1),e}function binarySearch(e,t,n){for(var i=0,r=e.length,o=void 0,a=void 0;i=0?o=r:(a=O._getIndex(e.with,t.localField))>=0&&(o=t.localField),e.withAll)return void n.call(i,t,{});if(o){var s={};O.fillIn(s,t.getRelation()),O.fillIn(s,e),s.with=e.with.slice(),s._activeWith=s.with.splice(a,1)[0],s.with.forEach(function(e,t){e&&0===e.indexOf(o)&&e.length>=o.length&&"."===e[o.length]?s.with[t]=e.substr(o.length+1):s.with[t]=""}),n.call(i,t,s)}},_getIndex:function _getIndex(e,t){var n=-1;return e.forEach(function(e,i){return e===t?(n=i,!1):O.isObject(e)&&e.relation===t?(n=i,!1):void 0}),n},addHiddenPropsToTarget:function addHiddenPropsToTarget(e,t){var n={};Object.keys(t).forEach(function(e){var i=Object.getOwnPropertyDescriptor(t,e);i.enumerable=!1,n[e]=i}),Object.defineProperties(e,n)},areDifferent:function areDifferent(e,t,n){n||(n={});var i=O.diffObjects(e,t,n),r=Object.keys(i.added).length+Object.keys(i.removed).length+Object.keys(i.changed).length;return r>0},classCallCheck:function classCallCheck(e,t){if(!(e instanceof t))throw O.err(""+t.name)(500,"Cannot call a class as a function")},copy:function copy(e,t,n,i,o,a){if(t){if(e===t)throw O.err(r+".copy")(500,"Cannot copy! Source and destination are identical.");if(n=n||[],i=i||[],O.isObject(e)){var s=n.indexOf(e);if(s!==-1)return i[s];n.push(e),i.push(t)}var u=void 0;if(O.isArray(e)){var c=void 0;for(t.length=0,c=0;c1?t-1:0),i=1;i=0&&e.splice(n,1)}},resolve:function resolve(e){return O.Promise.resolve(e)},set:function set(e,t,n){if(O.isObject(t))O.forOwn(t,function(t,n){O.set(e,n,t)});else{var i=v.exec(t);i?A(e,i[1])[i[2]]=n:e[t]=n}},deepEqual:function deepEqual(e,t){if(e===t)return!0;var n=!0;if(O.isObject(e)&&O.isObject(t)){if(O.forOwn(e,function(e,i){n=n&&O.deepEqual(e,t[i])}),!n)return n;O.forOwn(t,function(t,i){n=n&&O.deepEqual(t,e[i])})}else{if(!O.isArray(e)||!O.isArray(t))return!1;e.forEach(function(e,i){if(n=n&&O.deepEqual(e,t[i]),!n)return!1})}return n},toJson:JSON.stringify,unset:function unset(e,t){for(var n=t.split("."),i=n.pop();t=n.shift();)if(e=e[t],null==e)return;e[i]=void 0}},x=function safeSetProp(e,t,n){e&&e._set?e._set("props."+t,n):O.set(e,t,n)},_=function safeSetLink(e,t,n){e&&e._set?e._set("links."+t,n):O.set(e,t,n)};Settable.extend=O.extend;var w=Settable.extend({constructor:Component});Component.extend=O.extend,O.logify(Component.prototype),O.eventify(Component.prototype,function(){return this._listeners},function(e){this._listeners=e});var C="Query",F="Index inaccessible after first operation",R={limit:"",offset:"",orderBy:"",skip:"",sort:"",where:""},E=/([.*+?^=!:${}()|[\]\/\\])/g,k=/%/g,I=/_/g,j=function escape(e){return e.replace(E,"\\$1")},S=w.extend({constructor:Query,_applyWhereFromObject:function _applyWhereFromObject(e){var t=[],n=[],i=[];return O.forOwn(e,function(e,r){O.isObject(e)||(e={"==":e}),O.forOwn(e,function(e,o){t.push(r),n.push(o),i.push(e)})}),{fields:t,ops:n,predicates:i}},_applyWhereFromArray:function _applyWhereFromArray(e){var t=this,n=[];return e.forEach(function(i,r){if(!O.isString(i)){var o=e[r-1],a=O.isArray(i)?t._applyWhereFromArray:t._applyWhereFromObject,s=a.call(t,i);"or"===o&&(s.isOr=!0),n.push(s)}}),n.isArray=!0,n},_testObjectGroup:function _testObjectGroup(e,t,n,i){var r=void 0,o=n.fields,a=n.ops,s=n.predicates,u=a.length;for(r=0;ra?1:t1?t-1:0),i=1;i":function _(e,t){return e>t},">=":function _(e,t){return e>=t},"<":function _(e,t){return e=0;i--){var r=n[i];t=r.isIndex?t.concat(r.getAll(e)):t.concat(r)}else for(var o=0;oo)break}else if(this.keys[s]>=o)break;if(i=this.values[s].isIndex?i.concat(this.values[s].getAll()):i.concat(this.values[s]),n.limit&&i.length>=n.limit+n.offset)break}}else for(var u=a.index;uo)break;if(i=this.values[u].isIndex?c===r?i.concat(this.values[u]._between(O.copy(e),t.map(function(){}),n)):c===o?i.concat(this.values[u]._between(e.map(function(){}),O.copy(t),n)):i.concat(this.values[u].getAll()):i.concat(this.values[u]),n.limit&&i.length>=n.limit+n.offset)break}return n.limit?i.slice(0,n.limit+n.offset):i},peek:function peek(){return this.values.length?this.values[0].isIndex?this.values[0].peek():this.values[0]:[]},clear:function clear(){this.keys=[],this.values=[]},insertRecord:function insertRecord(e){var t=this.fieldList.map(function(t){return O.isFunction(t)?t(e)||void 0:e[t]||void 0});this.set(t,e)},removeRecord:function removeRecord(e){var t=this,n=void 0,i=void 0!==this.hashCode(e);return this.values.forEach(function(r,o){if(r.isIndex){if(r.removeRecord(e))return 0===r.keys.length&&(removeAt(t.keys,o),removeAt(t.values,o)),n=!0,!1}else{var a={};if(void 0!==t.keys[o]&&i)i&&(a=binarySearch(r,e,t.hashCode));else for(var s=r.length-1;s>=0;s--)if(r[s]===e){a={found:!0,index:s};break}if(a.found)return removeAt(r,a.index),0===r.length&&(removeAt(t.keys,o),removeAt(t.values,o)),n=!0,!1}}),n?e:void 0},updateRecord:function updateRecord(e){var t=this.removeRecord(e);void 0!==t&&this.insertRecord(e)}});var L="Collection",M={commitOnMerge:!0,idAttribute:"id",onConflict:"merge"},P=w.extend({constructor:Collection,_onRecordEvent:function _onRecordEvent(){this.emit.apply(this,arguments)},add:function add(e,t){var n=this;t||(t={}),O._(t,this),e=this.beforeAdd(e,t)||e;var i=!1,r=this.recordId();if(!O.isArray(e)){if(!O.isObject(e))throw O.err(L+"#add","records")(400,"object or array",e);e=[e],i=!0}e=e.map(function(e){var i=n.recordId(e),o=void 0===i?i:n.get(i);if(e===o)return o;if(o){var a=t.onConflict||n.onConflict;if("merge"===a)O.deepMixIn(o,e);else{if("replace"!==a)throw O.err(L+"#add","opts.onConflict")(400,"one of (merge, replace)",a,!0);O.forOwn(o,function(t,n){n!==r&&void 0===e[n]&&(o[n]=void 0)}),o.set(e)}e=o,t.commitOnMerge&&O.isFunction(e.commit)&&e.commit(),n.updateIndexes(e)}else e=n.mapper?n.mapper.createRecord(e,t):e,n.index.insertRecord(e),O.forOwn(n.indexes,function(t,n){t.insertRecord(e)}),e&&O.isFunction(e.on)&&e.on("all",n._onRecordEvent,n);return e});var o=i?e[0]:e;return this.emit("add",o),this.afterAdd(e,t,o)||o},afterAdd:function afterAdd(){},afterRemove:function afterRemove(){},afterRemoveAll:function afterRemoveAll(){},beforeAdd:function beforeAdd(){},beforeRemove:function beforeRemove(){},beforeRemoveAll:function beforeRemoveAll(){},between:function between(e,t,n){return this.query().between(e,t,n).run()},createIndex:function createIndex(e,t,n){var i=this;O.isString(e)&&void 0===t&&(t=[e]),n||(n={}),n.hashCode||(n.hashCode=function(e){return i.recordId(e)});var r=this.indexes[e]=new Index(t,n);this.index.visitAll(r.insertRecord,r)},filter:function filter(e,t){return this.query().filter(e,t).run()},forEach:function forEach(e,t){this.index.visitAll(e,t)},get:function get(e){var t=this.query().get(e).run();return t.length?t[0]:void 0},getAll:function getAll(){var e;return(e=this.query()).getAll.apply(e,arguments).run()},getIndex:function getIndex(e){var t=e?this.indexes[e]:this.index;if(!t)throw O.err(L+"#getIndex",e)(404,"index");return t},limit:function limit(e){return this.query().limit(e).run()},map:function map(e,t){var n=[];return this.index.visitAll(function(i){n.push(e.call(t,i))}),n},mapCall:function mapCall(e){for(var t=arguments.length,n=Array(t>1?t-1:0),i=1;i")(400,"string",r)},canFindLinkFor:function canFindLinkFor(e){var t=this.foreignKey||this.foreignKeys;return!!(t||this.localKeys&&O.get(e,this.localKeys))},linkRecord:function linkRecord(e,t){var n=this,i=this.relatedCollection,r=this.canAutoAddLinks,o=this.foreignKey,a=this.relatedCollection.unsaved();return t.map(function(t){var s=i.recordId(t);return(void 0===s&&a.indexOf(t)===-1||t!==i.get(s))&&(o&&n.setForeignKey(e,t),r&&(t=i.add(t))),t})},findExistingLinksFor:function findExistingLinksFor(e){var t=O.get(e,this.mapper.idAttribute),n=this.localKeys?O.get(e,this.localKeys):null,i=void 0;if(void 0!==t&&this.foreignKey?i=this.findExistingLinksByForeignKey(t):this.localKeys&&n?i=this.findExistingLinksByLocalKeys(n):void 0!==t&&this.foreignKeys&&(i=this.findExistingLinksByForeignKeys(t)),i&&i.length)return i},findExistingLinksByLocalKeys:function findExistingLinksByLocalKeys(e){return this.relatedCollection.filter({where:n({},this.mapper.idAttribute,{in:e})})},findExistingLinksByForeignKeys:function findExistingLinksByForeignKeys(e){return this.relatedCollection.filter({where:n({},this.foreignKeys,{contains:e})})}},{TYPE_NAME:"hasMany"}),Q=Relation.extend({findExistingLinksFor:function findExistingLinksFor(e,t){var n=O.get(t,e.idAttribute),i=this.findExistingLinksByForeignKey(n);if(i&&i.length)return i[0]}},{TYPE_NAME:"hasOne"});[q,J,Q].forEach(function(e){Relation[e.TYPE_NAME]=function(t,n){return new e(t,n)}});var B=function belongsTo(e,t){return function(n){Relation.belongsTo(e,t).assignTo(n)}},U=function hasMany(e,t){return function(n){Relation.hasMany(e,t).assignTo(n)}},$=function hasOne(e,t){return function(n){Relation.hasOne(e,t).assignTo(n)}},G="Record",V=function superMethod(e,t){var n=e.datastore;return n&&n[t]?function(){for(var i=arguments.length,r=Array(i),o=0;or)return Z(t.length,"length no more than "+r,i)},ne=function minLengthCommon(e,t,n,i){var r=n[e];if(t.lengthe:maximum>=e))return r?Z(e,"no more than nor equal to "+maximum,i):Z(e,"no more than "+maximum,i)},maxItems:function maxItems(e,t,n){if(O.isArray(e))return te("maxItems",e,t,n)},maxLength:function maxLength(e,t,n){return te("maxLength",e,t,n)},maxProperties:function maxProperties(e,t,n){if(O.isObject(e)){var maxProperties=t.maxProperties,i=Object.keys(e).length;return i>maxProperties?Z(i,"no more than "+maxProperties+" properties",n):void 0}},minimum:function minimum(e,n,i){var minimum=n.minimum,r=n.exclusiveMinimum;if(("undefined"==typeof e?"undefined":t(e))===("undefined"==typeof minimum?"undefined":t(minimum))&&!(r?e>minimum:e>=minimum))return r?Z(e,"no less than nor equal to "+minimum,i):Z(e,"no less than "+minimum,i)},minItems:function minItems(e,t,n){if(O.isArray(e))return ne("minItems",e,t,n)},minLength:function minLength(e,t,n){return ne("minLength",e,t,n)},minProperties:function minProperties(e,t,n){if(O.isObject(e)){var minProperties=t.minProperties,i=Object.keys(e).length;return i0;o--)for(r=e[o],a=o-1;a>=0;a--)if(O.deepEqual(r,e[a]))return Z(r,"no duplicates",n)}}},re=function validateKeyword(e,t,n,i){return void 0!==n[e]&&ie[e](t,n,i)},oe=function runOps(e,t,n,i){var r=[];return e.forEach(function(e){r=r.concat(re(e,t,n,i)||[])}),r.length?r:void 0},ae=["enum","type","allOf","anyOf","oneOf","not"],se=["items","maxItems","minItems","uniqueItems"],ue=["multipleOf","maximum","minimum"],ce=["maxProperties","minProperties","required","properties","dependencies"],le=["maxLength","minLength","pattern"],fe=function validateAny(e,t,n){return oe(ae,e,t,n)},de=function _validate(e,t,n){var i=[];n||(n={}),n.ctx||(n.ctx={value:e,schema:t});var r=void 0,o=n.prop;if(void 0!==t){if(!O.isObject(t))throw O.err(W+"#validate")(500,'Invalid schema at path: "'+n.path+'"');return void 0===n.path&&(n.path=[]),void 0!==n.prop&&(r=!0,n.path.push(n.prop),n.prop=void 0),t.extends&&(i=O.isFunction(t.extends.validate)?i.concat(t.extends.validate(e,n)||[]):i.concat(_validate(e,t.extends,n)||[])),void 0===e?(t.required!==!0||n.existingOnly||ee(e,"a value",n,i),r&&(n.path.pop(),n.prop=o),i.length?i:void 0):(i=i.concat(fe(e,t,n)||[]),r&&(n.path.pop(),n.prop=o),i.length?i:void 0)}},he="changing",pe="changed",ve="history",ge="creating",ye="eventId",me="noValidate",be="silent",Ae="validation failed",Oe=function makeDescriptor(e,t,n){var i={configurable:!0,enumerable:void 0===t.enumerable||!!t.enumerable},r="props."+e,o="previous."+e,a=n.getter,s=n.setter,u=n.unsetter,c=O.isBoolean(n.track)?n.track:t.track;return i.get=function(){return this._get(r)},O.isFunction(t.get)&&!function(){var e=i.get;i.get=function(){return t.get.call(this,e)}}(),i.set=function(n){var i=this,l=this[a],f=this[s],d=this[u];if(!l(me)){var h=t.validate(n,{path:[e]});if(h){var p=new Error(Ae);throw p.errors=h,p}}return c&&!l(ge)&&!function(){var t=l(o),a=l(r),s=l(he),u=l(pe);s||(u=[]);var c=u.indexOf(e);a!==n&&c===-1&&u.push(e),t===n&&c>=0&&u.splice(c,1),u.length||(s=!1,d(he),d(pe),l(ye)&&(clearTimeout(l(ye)),d(ye))),!s&&u.length&&(f(pe,u),f(he,!0),f(ye,setTimeout(function(){if(d(pe),d(ye),d(he),!l(be)){var e=void 0;for(e=0;e1?n-1:0),o=1;o1?t-1:0),i=1;i1?i-1:0),o=1;o1?t-1:0),i=1;i1?i-1:0),o=1;o",">=","<","<=","isectEmpty","isectNotEmpty","in","_in","notIn","contains","notContains","pos","dataLocation","newIndex","results","order","_i","visitAll","cb","leftInclusive","rightInclusive","_between","leftKey","rightKey","_i2","currKey","peek","clear","insertRecord","removeRecord","isUnique","j","updateRecord","DOMAIN$1","commitOnMerge","onConflict","_onRecordEvent","beforeAdd","singular","commit","updateIndexes","createRecord","afterAdd","afterRemove","afterRemoveAll","beforeRemove","beforeRemoveAll","createIndex","instances","_query","prune","removeAll","unsaved","Ctor","reduce","initialValue","idOrRecord","silent","queryOrRecords","toJSON","updateIndex","DOMAIN$5","superMethod","store","bind","_mapper","afterLoadRelations","beforeLoadRelations","changeHistory","changes","destroy","hasChanges","quickHasChanges","isNew","isValid","validate","loadRelations","relations","adapter","getAdapterName","then","tasks","task","raw","load","foreignKey","relatedData","localKeys","foreignKeys","setLocalField","previous","revert","preserve","save","postProcess","changesOnly","_this4","_ret","v","DOMAIN$6","types","boolean","integer","null","number","string","segmentToString","segment","str","makePath","segments","makeError","actual","expected","addError","errors","maxLengthCommon","keyword","max","minLengthCommon","validationKeywords","allOf","allErrors","_schema","_validate","anyOf","validated","dependencies","enum","_enum","possibleValues","join","checkingTuple","maximum","exclusiveMaximum","maxItems","maxLength","maxProperties","minimum","exclusiveMinimum","minItems","minLength","minProperties","multipleOf","not","oneOf","additionalProperties","toValidate","patternProperties","undef","required","existingOnly","prevProp","validType","_type","validator","typeGroupValidators","uniqueItems","validateKeyword","runOps","ANY_OPS","ARRAY_OPS","NUMERIC_OPS","OBJECT_OPS","STRING_OPS","validateAny","ctx","shouldPop","changingPath","changedPath","changeHistoryPath","creatingPath","eventIdPath","noValidatePath","silentPath","validationFailureMsg","makeDescriptor","keyPath","previousPath","unsetter","track","originalGet","error","current","changing","clearTimeout","setTimeout","changeRecord","timestamp","originalSet","numeric","applyDefaults","hasSet","orig","belongsToType","hasManyType","hasOneType","DOMAIN$7","canAutoAddLinks","relatedCollection","getCollection","related","DOMAIN_ERR","localKey","assignTo","relationFields","canFindLinkFor","getForeignKey","setForeignKey","relatedRecord","_setForeignKey","relatedRecords","getLocalField","getInverse","inverse","findInverseRelation","isInversedTo","addLinkedRecords","linkRecord","isEmptyLinks","findExistingLinksFor","removeLinkedRecords","unlinkInverseRecords","relatedId","findExistingLinksByForeignKey","BelongsToRelation","HasManyRelation","hasForeignKeys","ids","findExistingLinksByLocalKeys","findExistingLinksByForeignKeys","HasOneRelation","RelationType","belongsTo","hasMany","hasOne","applyDefaultsHooks","validatingHooks","makeNotify","getSchema","toProcess","originalExistingOnly","notify","notify2","count","defaults","destroyAll","find","findAll","sum","update","adapterArgs","beforeAssign","updateAll","updateMany","defaultAdapter","afterCount","afterCreate","afterCreateMany","afterDestroy","afterDestroyAll","afterFind","afterFindAll","afterSum","afterUpdate","afterUpdateAll","afterUpdateMany","beforeCreate","beforeCreateMany","beforeCount","beforeDestroy","beforeDestroyAll","beforeFind","beforeFindAll","beforeSum","beforeUpdate","beforeUpdateAll","beforeUpdateMany","_end","_data","wrap","belongsTo$$","crud","originalRecord","belongsToRelationData","relationData","relatedIdAttribute","createMany","getAdapter","pass","createdRecordData","_result","createInstance","originalRecords","_records","createdRecordsData","belongsToData","_this5","RecordCtor","is","method","_this6","config","upper","before","after","_getAdapter","getAdapters","hasMany$$","hasOne$$","registerAdapter","default","_this7","strict","_opts","_record","hasErrors","defineRelations","_this8","_name","getMapperByName","getMapper","DOMAIN$3","proxiedMapperMethods","_onMapperEvent","as","original","defineMapper","defineResource","warn","_getMapper","_addMeta","_clearMeta","event","DOMAIN$8","proxiedCollectionMethods","ownMethodsForScoping","safeSetProp","safeSetLink","cachedFn","hashOrId","cached","unlinkOnDestroy","usePendingFind","usePendingFindAll","props$1","_callSuper","addToCache","_onCollectionEvent","cachedFind","cachedFindAll","cacheFind","cacheFindAll","hash","self","indexed","_key5","updateOpts","currentParent","inverseDef","children","child","_children","foreignKeyDescriptor","currentParentId","storeRecord","inverseLocalField","toLink","toLinkIds","currentChildrenOfParent","parents","parent","origGet","_this9","_len5","_key6","origSet","_this10","_this11","_this12","hashQuery","eject","ejectAll","_this13","pendingQuery","promise","force","_this14","inject","removeRelated","_this15","_this16","_this17","_this18","_getCollection","_len6","_key7","DataStore$1","version","full","major","minor","patch"],"mappings":"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","file":"dist/js-data.min.js"} \ No newline at end of file +{"version":3,"sources":["dist/js-data.js"],"names":["global","factory","exports","module","define","amd","JSData","this","Settable","_props","Object","defineProperties","_get","value","key","utils","get","_set","_value","set","_unset","unset","Component","opts","call","debug","hasOwnProperty","defineProperty","writable","Query","collection","classCallCheck","data","sort","a","b","hashCode","undefined","insertAt","array","index","splice","removeAt","binarySearch","field","lo","hi","length","compared","mid","found","Index","fieldList","isArray","Error","fieldGetter","isIndex","keys","values","Collection","records","Component$1","isString","idAttribute","mapper","queryClass","fillIn","copy","COLLECTION_DEFAULTS","Query$1","recordId","obj","indexes","isObject","add","Relation","relatedMapper","options","arguments","type","constructor","TYPE_NAME","validateOptions","_typeof","Record","props","noValidate","id","plainCopy","Schema","definition","_this2","properties","forOwn","_definition","prop","items","forEach","validationKeyword","i","Mapper","_adapters","datastore","lifecycleMethods","LIFECYCLE_METHODS","recordClass","schema","MAPPER_DEFAULTS","name","err","DOMAIN$4","Schema$1","superClass","Record$1","extend","subClass","methods","addHiddenPropsToTarget","prototype","isPrototypeOf","create","apply","applySchema","Container","_mappers","mapperClass","mapperDefaults","Mapper$1","LinkedCollection","_added","Collection$1","DOMAIN$9","DataStore","DATASTORE_DEFAULTS","collectionClass","LinkedCollection$1","_collections","_pendingQueries","_completedQueries","Symbol","iterator","enumerable","configurable","toConsumableArray","arr","Array","arr2","from","DOMAIN","INFINITY","MAX_INTEGER","BOOL_TAG","DATE_TAG","FUNC_TAG","NUMBER_TAG","OBJECT_TAG","REGEXP_TAG","STRING_TAG","objToString","toString","PATH","ERRORS","400","_","404","toInteger","sign","remainder","toStr","isPlainObject","mkdirP","object","path","parts","split","Promise","dest","src","isFunction","indexOf","_forRelation","def","fn","thisArg","relationName","relation","containedName","with","_getIndex","localField","withAll","optsCopy","getRelation","slice","_activeWith","substr","list","_relation","target","map","propName","descriptor","getOwnPropertyDescriptor","areDifferent","newObject","oldObject","diff","diffObjects","diffCount","added","removed","changed","instance","ctor","to","stackFrom","stackTo","blacklist","plain","push","result","isBlacklisted","isDate","Date","getTime","isRegExp","RegExp","source","match","lastIndex","getPrototypeOf","deepFillIn","existing","deepMixIn","equalsFn","ignore","deepEqual","newKeys","filter","oldKeys","oldValue","newValue","equal","domain","code","prefix","message","eventify","getter","setter","_events","emit","events","_len","args","_key","shift","listeners","f","c","all","unshift","off","func","on","classProps","_subClass","_len2","_key2","setPrototypeOf","strictEs6Class","__proto__","findIndex","record","forEachRelation","relationList","len","fromJson","json","JSON","parse","last","pop","getSuper","isCtor","__super__","intersection","array1","array2","item","matches","test","isBoolean","isInteger","isNull","isNumber","isSorN","isUndefined","logify","dbg","log","_len3","_key3","concat","level","_len4","_key4","toUpperCase","console","_console","_console2","noDupeAdd","omit","pick","reject","remove","resolve","_path","exec","_equal","toJson","stringify","safeSetProp","safeSetLink","_listeners","DOMAIN$2","INDEX_ERR","reserved","limit","offset","orderBy","skip","where","escapeRegExp","percentRegExp","underscoreRegExp","escape","pattern","replace","_applyWhereFromObject","fields","ops","predicates","clause","==","expr","op","_applyWhereFromArray","_this","groups","_where","prev","parser","group","isOr","_testObjectGroup","keep","first","charAt","evaluate","_testArrayGroup","between","leftKeys","rightKeys","getIndex","compare","cA","cB","temp","predicate","like","query","getData","forEachFn","keyList","getAll","_this3","flags","num","Math","min","mapFn","mapCall","funcName","run","=","===","!=","!==",">",">=","<","<=","isectEmpty","isectNotEmpty","in","_in","notIn","contains","notContains","pos","dataLocation","newIndex","results","order","_i","visitAll","cb","leftInclusive","rightInclusive","_between","leftKey","rightKey","_i2","currKey","peek","clear","insertRecord","removeRecord","isUnique","j","updateRecord","DOMAIN$1","commitOnMerge","onConflict","_onRecordEvent","beforeAdd","singular","commit","updateIndexes","createRecord","afterAdd","afterRemove","afterRemoveAll","beforeRemove","beforeRemoveAll","createIndex","instances","_query","prune","removeAll","unsaved","Ctor","reduce","initialValue","idOrRecord","silent","queryOrRecords","toJSON","updateIndex","belongsToType","hasManyType","hasOneType","DOMAIN$6","canAutoAddLinks","relatedCollection","getCollection","related","DOMAIN_ERR","foreignKey","localKey","assignTo","relationFields","canFindLinkFor","getForeignKey","setForeignKey","relatedRecord","_setForeignKey","relatedRecords","getLocalField","setLocalField","relatedData","getInverse","inverse","findInverseRelation","isInversedTo","addLinkedRecords","linkRecord","isEmptyLinks","findExistingLinksFor","removeLinkedRecords","relatedId","findExistingLinksByForeignKey","BelongsToRelation","HasManyRelation","localKeys","foreignKeys","hasForeignKeys","ids","findExistingLinksByLocalKeys","findExistingLinksByForeignKeys","HasOneRelation","RelationType","belongsTo","hasMany","hasOne","DOMAIN$5","superMethod","store","bind","_mapper","afterLoadRelations","beforeLoadRelations","changeHistory","changes","destroy","hasChanges","quickHasChanges","isNew","isValid","validate","removeInverseRelation","currentParent","inverseDef","children","child","setupInverseRelation","loadRelations","relations","adapter","getAdapterName","then","tasks","task","raw","load","previous","revert","_this4","preserve","save","_this5","postProcess","changesOnly","_this6","_ret","v","DOMAIN$7","types","boolean","integer","null","number","string","segmentToString","segment","str","makePath","segments","makeError","actual","expected","addError","errors","maxLengthCommon","keyword","max","minLengthCommon","validationKeywords","allOf","allErrors","_schema","_validate","anyOf","validated","dependencies","enum","_enum","possibleValues","join","checkingTuple","maximum","exclusiveMaximum","maxItems","maxLength","maxProperties","minimum","exclusiveMinimum","minItems","minLength","minProperties","multipleOf","not","oneOf","additionalProperties","toValidate","patternProperties","undef","required","existingOnly","prevProp","validType","_type","validator","typeGroupValidators","uniqueItems","validateKeyword","runOps","ANY_OPS","ARRAY_OPS","NUMERIC_OPS","OBJECT_OPS","STRING_OPS","validateAny","ctx","shouldPop","changingPath","changedPath","changeHistoryPath","creatingPath","eventIdPath","noValidatePath","silentPath","validationFailureMsg","makeDescriptor","keyPath","previousPath","unsetter","track","originalGet","error","current","changing","clearTimeout","setTimeout","changeRecord","timestamp","originalSet","numeric","applyDefaults","hasSet","orig","applyDefaultsHooks","validatingHooks","makeNotify","getSchema","toProcess","originalExistingOnly","notify","notify2","count","defaults","destroyAll","find","findAll","sum","update","adapterArgs","beforeAssign","updateAll","updateMany","defaultAdapter","afterCount","afterCreate","afterCreateMany","afterDestroy","afterDestroyAll","afterFind","afterFindAll","afterSum","afterUpdate","afterUpdateAll","afterUpdateMany","beforeCreate","beforeCreateMany","beforeCount","beforeDestroy","beforeDestroyAll","beforeFind","beforeFindAll","beforeSum","beforeUpdate","beforeUpdateAll","beforeUpdateMany","_end","_data","wrap","belongsTo$$","crud","originalRecord","belongsToRelationData","relationData","relatedIdAttribute","createMany","getAdapter","pass","createdRecordData","_result","createInstance","originalRecords","_records","createdRecordsData","belongsToData","RecordCtor","is","method","config","upper","before","after","_getAdapter","getAdapters","hasMany$$","hasOne$$","registerAdapter","default","_this7","strict","_opts","_record","hasErrors","defineRelations","_this8","_name","getMapperByName","getMapper","DOMAIN$3","proxiedMapperMethods","_onMapperEvent","as","original","defineMapper","defineResource","warn","_getMapper","_addMeta","_clearMeta","event","DOMAIN$8","proxiedCollectionMethods","ownMethodsForScoping","cachedFn","hashOrId","cached","unlinkOnDestroy","usePendingFind","usePendingFindAll","props$1","addToCache","_onCollectionEvent","cachedFind","cachedFindAll","cacheFind","cacheFindAll","hash","self","indexed","updateOpts","foreignKeyDescriptor","currentParentId","storeRecord","inverseLocalField","toLink","toLinkIds","currentChildrenOfParent","parents","parent","origGet","_key5","origSet","_this9","_this10","_this11","hashQuery","eject","ejectAll","_this12","pendingQuery","promise","force","_this13","inject","removeRelated","_this14","_this15","_this16","_this17","_getCollection","_len5","_key6","DataStore$1","version","full","major","minor","patch"],"mappings":"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","file":"dist/js-data.min.js"} \ No newline at end of file