UNPKG

redink

Version:
965 lines (804 loc) 88.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* eslint-disable no-param-reassign */ var _rethinkdb = require('rethinkdb'); var _rethinkdb2 = _interopRequireDefault(_rethinkdb); var _ResourceArray = require('./ResourceArray'); var _ResourceArray2 = _interopRequireDefault(_ResourceArray); var _update = require('./constraints/update'); var _utils = require('./utils'); var _queries = require('./queries'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Resource = function () { /** * Instantiates a Resource. * * @class Resource * @param {Object} conn - RethinkDB connection object. * @param {Schema} schema * @param {Object} record */ function Resource(conn, schema, record) { var _this = this; _classCallCheck(this, Resource); if (!conn) { throw new TypeError('A valid RethinkDB connection is required to instantiate a Resource.'); } if (!schema) { throw new TypeError('A valid schema is required to instantiate a Resource.'); } if (!record) { throw new TypeError('A valid record is required to instantiate a Resource.'); } this.conn = conn; this.schema = schema; this.id = record.id; this.meta = record._meta || {}; this.attributes = {}; // FIXME: ensure this clones deeply enough this.relationships = _extends({}, schema.relationships); Object.keys(record).forEach(function (field) { // hydrate attributes if (schema.hasAttribute(field)) { _this.attributes[field] = record[field]; return; } // hydrate relationships if (schema.hasRelationship(field)) { var relationship = _this.relationships[field]; var recordOrRecords = relationship.relation === 'hasMany' ? 'records' : 'record'; _this.relationships[field] = _extends({}, relationship, _defineProperty({}, recordOrRecords, record[field])); } }); } /** * Returns an attribute. * * ```javascript * model('user').fetchResource('1').then(user => { * user.attribute('name') === 'Dylan' * }); * ``` * * @method attribute * @param {String} attribute * @return {Any} */ _createClass(Resource, [{ key: 'attribute', value: function attribute(_attribute) { return this.attributes[_attribute]; } /** * Returns a relationship of the resource. * * ```javascript * model('user').fetchResource('1').then(user => { * user.relationship('pets') === { * type: 'animal', * field: 'pets', * schema: Schema, * relation: 'hasMany', * inverse: { * type: 'user', * relation: 'belongsTo', * field: 'owner', * }, * } * * user.relationship('teachers') === { * type: 'teacher', * field: 'teachers', * schema: Schema, * relation: 'hasMany', * records: [{ * id: '1', * _archived: false, * _related: true, * }, { * id: '2', * _archived: false, * _related: true, * }], * inverse: { * type: 'user', * relation: 'hasMany', * field: 'students', * }, * } * * user.relationship('company') === { * type: 'company', * field: 'company', * schema: Schema, * relation: 'hasOne', * record: { * id: '2', * _archived: false, * _related: true, * }, * inverse: { * type: 'user', * relation: 'hasMany', * field: 'employees', * }, * } * }); * ``` * * @method relationship * @param {String} relationship * @return {Object} */ }, { key: 'relationship', value: function relationship(_relationship) { if (typeof _relationship !== 'string') { throw new TypeError('Tried calling \'relationship\' method with an argument that was not a String.'); } return this.relationships[_relationship]; } /** * Returns an updated version of the resource. * * @async * @method reload * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'reload', value: function reload() { var pre = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var post = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var schema = this.schema; var id = this.id; var conn = this.conn; var table = _rethinkdb2.default.table(schema.type); table = table.get(id); table = (0, _utils.applyOptions)(table, pre); table = (0, _utils.mergeRelationships)(table, schema, pre); table = (0, _utils.applyOptions)(table, post); return table.run(conn).then(function (record) { return new Resource(conn, schema, record); }); } /** * Fetches either the `Resource` or `ResourceArray` related to this resource by `relationship`. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.fetch('company'); * }).then(company => { * // Resource * }); * ``` * * @async * @method fetch * @param {String} relationship * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource|ResourceArray>} */ }, { key: 'fetch', value: function fetch(relationship) { var pre = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var post = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (!this.relationship(relationship)) { return Promise.resolve(null); } var conn = this.conn; var id = this.id; var _relationship2 = this.relationship(relationship); var type = _relationship2.type; var schema = _relationship2.schema; var relation = _relationship2.relation; var inverse = _relationship2.inverse; var relatedRecord = _relationship2.record; var relatedRecords = _relationship2.records; var table = _rethinkdb2.default.table(type); if (relation === 'hasMany') { if ((0, _utils.requiresIndex)(relation, inverse.relation)) { table = table.getAll(id, { index: inverse.field }); } else { table = table.getAll(_rethinkdb2.default.args(relatedRecords.map(function (record) { return record.id; }))); } table = table.coerceTo('array'); } else { table = table.get(relatedRecord.id); } table = (0, _utils.applyOptions)(table, pre); table = (0, _utils.mergeRelationships)(table, schema, pre); table = (0, _utils.applyOptions)(table, post); return table.run(conn).then(function (recordOrRecords) { if (relation === 'hasMany') return new _ResourceArray2.default(conn, schema, recordOrRecords); return new Resource(conn, schema, recordOrRecords); }); } /** * Returns the resource pointer(s) based on the multipicity of `relationship`. For example, * if `relationship` is a M:N relationship, this method will return an array of pointers. If * `relationship` is a 1:M relationship, this method will return a single pointer. * * ```javascript * model('user').fetchResource('1').then(user => { * user.retrieve('pets') === [{ * id: '1', * _archived: false, * _related: false, * }] * * user.retrieve('company') === { * id: '1', * _archived: false, * _related: false, * } * }); * ``` * * @method relationship * @param {String} relationship * @return {(Object[]|Object)} */ }, { key: 'retrieve', value: function retrieve(relationship) { if (!this.relationship(relationship)) return null; var _relationship3 = this.relationship(relationship); var relation = _relationship3.relation; var record = _relationship3.record; var records = _relationship3.records; return relation === 'hasMany' ? records : record; } /** * Updates this resource's attributes. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.update({ * name: 'CJ', * }); * }).then(user => { * // Resource * }); * ``` * * @async * @method update * @param {Object} fields * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'update', value: function update(fields) { var _this2 = this; var pre = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var post = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var schema = this.schema; var id = this.id; var conn = this.conn; var type = schema.type; var table = _rethinkdb2.default.table(type); var reloadWithOptions = function reloadWithOptions() { return _this2.reload(pre, post); }; Object.keys(fields).forEach(function (field) { if (!schema.hasAttribute(field)) delete fields[field]; }); return table.get(id).update(fields).run(conn).then(reloadWithOptions); } /** * Removes the 'idToRemove' from this resource's 'hasOne' or 'belongsTo' relationship by setting * the resource pointer's _archived to true. * * @async * @private * @param {String} idToRemove * @param {String} field * @return {Object} */ }, { key: 'archiveRemoveIdFromRecordField', value: function archiveRemoveIdFromRecordField(idToRemove, field) { if (typeof idToRemove !== 'string') { throw new TypeError('Tried calling \'archiveRemoveIdFromRecordField\' with ' + '\'idToRemove\' that was not a string.'); } if (typeof field !== 'string') { throw new TypeError('Tried calling \'archiveRemoveIdFromRecordField\' with \'field\' that was not a string.'); } var type = this.schema.type; var id = this.id; var conn = this.conn; return (0, _queries.archiveRemoveIdFromRecordField)(type, id, field, idToRemove).run(conn); } /** * Removes the 'idToRemove' from each resource, indicated by the array of 'ids', by setting * each resource pointer's _archived to true. * * @async * @private * @param {String} type * @param {String[]} ids * @param {String} field * @return {Object} */ }, { key: 'archiveRemoveIdFromManyRecordsField', value: function archiveRemoveIdFromManyRecordsField(type, ids, field) { if (typeof type !== 'string') { throw new TypeError('Tried calling \'archiveRemoveIdFromManyRecordsField\' with ' + '\'type\' that was not a String.'); } if (!Array.isArray(ids) || !ids.every(function (item) { return typeof item === 'string'; })) { throw new TypeError('Tried calling \'archiveRemoveIdFromManyRecordsField\' with ' + '\'ids\' that was not an Array of Strings.'); } if (typeof field !== 'string') { throw new TypeError('Tried calling \'archiveRemoveIdFromManyRecordsField\' with ' + '\'field\' that was not a String.'); } var idToRemove = this.id; var conn = this.conn; return (0, _queries.archiveRemoveIdFromManyRecordsField)(type, ids, field, idToRemove).run(conn); } /** * Splices all of the `idsToUpdate` from this resource's 'hasMany' relationship by setting each * resource pointer's `_archived` to true. * * @async * @private * @param {String} inverseType * @param {String} inverseField * @param {String[]} idsToUpdate * @param {String} idToSplice * @return {Object} */ }, { key: 'archiveSpliceIdFromInverseField', value: function archiveSpliceIdFromInverseField(inverseType, inverseField, idsToUpdate, idToSplice) { if (typeof inverseType !== 'string') { throw new TypeError('Tried calling \'archiveSpliceIdFromInverseField\' with ' + '\'inverseType\' that was not a String.'); } if (typeof inverseField !== 'string') { throw new TypeError('Tried calling \'archiveSpliceIdFromInverseField\' with ' + '\'inverseField\' that was not a String.'); } if (!Array.isArray(idsToUpdate) || !idsToUpdate.every(function (item) { return typeof item === 'string'; })) { throw new TypeError('Tried calling \'archiveSpliceIdFromInverseField\' with ' + '\'idsToUpdate\' that was not an Array of Strings.'); } if (typeof idToSplice !== 'string') { throw new TypeError('Tried calling \'archiveSpliceIdFromInverseField\' with ' + '\'idToSplice\' that was not a String.'); } return (0, _queries.archiveSpliceIdFromInverseField)(inverseType, inverseField, idsToUpdate, idToSplice).run(this.conn); } /** * Archives this resource and recursively archives its corresponding relationships. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.archive(); * }).then(user => { * // Resource * }); * ``` * * @async * @method archive * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'archive', value: function archive() { var _this3 = this; var pre = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var post = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var type = this.schema.type; var id = this.id; var conn = this.conn; var updateObject = (0, _utils.getArchiveOriginalUpdateObject)(this); var reloadWithOptions = function reloadWithOptions() { return _this3.reload(pre, post); }; return _rethinkdb2.default.table(type).get(id).update(updateObject).run(conn).then(this.recursivelyArchive.bind(this)).then(reloadWithOptions); } /** * Recursively archives this resource's corresponding relationships. * * @async * @private * @return {Promise} */ }, { key: 'recursivelyArchive', value: function recursivelyArchive() { var _this4 = this; var id = this.id; return Promise.all(Object.keys(this.relationships).map(function (field) { var _relationship4 = _this4.relationship(field); var type = _relationship4.type; var relation = _relationship4.relation; var _relationship4$invers = _relationship4.inverse; var inverseRelation = _relationship4$invers.relation; var inverseField = _relationship4$invers.field; var inverseType = _relationship4$invers.type; if (relation === 'hasMany') { switch (inverseRelation) { case 'hasMany': return _this4.fetch(field).then(function (resources) { var idsToUpdate = resources.map(function (resource) { return resource.id; }); return _this4.archiveSpliceIdFromInverseField.call(_this4, inverseType, inverseField, idsToUpdate, id); }); case 'belongsTo': return _this4.fetch(field).then(function (resources) { return Promise.all(resources.map(function (resource) { return Promise.all([resource.archive(), resource.archiveRemoveIdFromRecordField(id, inverseField)]); })); }); case 'hasOne': return _this4.fetch(field).then(function (resources) { var ids = resources.map(function (resource) { return resource.id; }); return _this4.archiveRemoveIdFromManyRecordsField.call(_this4, type, ids, inverseField); }); default: return true; } } if (relation === 'hasOne') { switch (inverseRelation) { case 'hasMany': return true; case 'belongsTo': return _this4.fetch(field).then(function (resource) { return Promise.all([resource.archive(), resource.archiveRemoveIdFromRecordField(id, inverseField)]); }); case 'hasOne': return _this4.fetch(field).then(function (resource) { return resource.archiveRemoveIdFromRecordField(id, inverseField); }); default: return true; } } if (relation === 'belongsTo') { switch (inverseRelation) { case 'hasMany': return true; case 'belongsTo': return true; case 'hasOne': return _this4.fetch(field).then(function (resource) { return resource.archiveRemoveIdFromRecordField(id, inverseField); }); default: return true; } } return true; })); } /** * Assigns a resource to this resource's `hasOne` or `belongsTo` relationship identified * by `relationship`. The `data` argument can either be a Resource or String id. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.put('company', '1'); * }).then(user => { * // Resource * }); * * model('user', 'company').map({ * user(model) { * return model.fetchResource('1'); * }, * company(model) { * return model.fetchResource('1'); * }, * }).then(results => { * const { user, company } = results; * return user.put('company', company); * }).then(user => { * // Resource * }); * ``` * * @async * @method put * @param {String} relationship * @param {(String|Resource)} data * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'put', value: function put(relationship, data) { var _this5 = this; var pre = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var post = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var relationshipObject = this.relationship(relationship); var relation = relationshipObject.relation; var inverse = relationshipObject.inverse; var field = relationshipObject.field; var conn = this.conn; var schema = this.schema; var id = this.id; var reloadWithOptions = function reloadWithOptions() { return _this5.reload(pre, post); }; var idToPut = void 0; if (relation !== 'hasOne' && relation !== 'belongsTo') { throw new TypeError('Tried calling \'put\' on a resource whose \'relationship\' is \'' + relation + '\'. This method ' + 'only works for resources whose \'relationship\' is \'hasOne\' or \'belongsTo\'.'); } if (!(data instanceof Resource || typeof data === 'string')) { throw new TypeError('Tried calling \'put\' with \'data\' that was neither a Resource nor a String.'); } var putData = function putData(isCompliant) { if (!isCompliant) { throw new Error('Tried calling \'put\' with \'data\' that violated Redink\'s update constraints.'); } switch (inverse.relation) { case 'hasMany': return (0, _queries.putIdToRecordField)(schema.type, id, field, idToPut).run(conn); case 'hasOne': return _rethinkdb2.default.do((0, _queries.putIdToRecordField)(schema.type, id, field, idToPut), (0, _queries.putIdToRecordField)(inverse.type, idToPut, inverse.field, id)).run(conn); default: throw new TypeError('Tried calling \'put\' on a resource whose inverse \'relationship\' ' + ('is \'' + inverse.relation + '\'.')); } }; // Ensure `id` is an id string if (typeof data === 'string') idToPut = data; if (data instanceof Resource) idToPut = data.id; return (0, _update.isPutCompliant)(relationshipObject, idToPut, conn).then(putData).then(reloadWithOptions); } /** * Removes this resource's `hasOne` relationship. The `relationship` argument must be a * relationship String. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.remove('company'); * }).then(user => { * // Resource * }); * ``` * * @async * @method remove * @param {String} relationship * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'remove', value: function remove(relationship) { var _this6 = this; var pre = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var post = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var relationshipObject = this.relationship(relationship); var relation = relationshipObject.relation; var inverse = relationshipObject.inverse; var record = relationshipObject.record; var field = relationshipObject.field; var inverseRelation = inverse.relation; var schema = this.schema; var id = this.id; var conn = this.conn; var reloadWithOptions = function reloadWithOptions() { return _this6.reload(pre, post); }; if (relation !== 'hasOne') { throw new TypeError('Tried calling \'remove\' on a resource whose \'relationship\' is \'' + relation + '\'. This method ' + 'only works for resources whose \'relationship\' is \'hasOne\'.'); } var removeData = function removeData() { if (!(0, _update.isRemoveCompliant)(inverseRelation)) { throw new Error('Tried calling \'remove\' with a relationship that violated Redink\'s update constraints.'); } switch (inverseRelation) { case 'hasMany': return (0, _queries.removeIdFromRecordField)(schema.type, id, field, record.id).run(conn); case 'hasOne': return _rethinkdb2.default.do((0, _queries.removeIdFromRecordField)(schema.type, id, field, record.id), (0, _queries.removeIdFromRecordField)(inverse.type, record.id, inverse.field, id)).run(conn); default: throw new TypeError('Tried calling \'remove\' on a resource whose inverse \'relationship\' ' + ('is \'' + inverseRelation + '\'.')); } }; return removeData().then(reloadWithOptions); } /** * Pushes data to this resource's `relationship`. The `data` can either be a `Resource`, * `ResourceArray`, array of Strings representing ids, or a String id. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.push('pets', ['1', '2']); * }).then(user => { * const newPets = user.relationship('pets'); // will include pets with ids '1' and '2' * }); * * model('user', 'animal:pets').map({ * user(model) { * return model.fetchResource('1'); * }, * pets(model) { * return model.find({ filter: { name: 'Lassy' } }), * }, * }).then(results => { * const { user, pets } = results; * return user.push('pets', pets); * }).then(user => { * const newPets = user.relationship('pets'); // will include pets with name of 'Lassy' * }); * ``` * * @async * @method push * @param {String} relationship * @param {(String|String[]|Resource|ResourceArray)} data * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'push', value: function push(relationship, data) { var _this7 = this; var pre = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var post = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var relationshipObject = this.relationship(relationship); var relation = relationshipObject.relation; var inverse = relationshipObject.inverse; var field = relationshipObject.field; var records = relationshipObject.records; var schema = this.schema; var id = this.id; var conn = this.conn; var reloadWithOptions = function reloadWithOptions() { return _this7.reload(pre, post); }; var idsToPush = void 0; if (relation !== 'hasMany') { throw new TypeError('Tried calling \'push\' on a resource whose \'relationship\' is \'' + relation + '\'. This method ' + 'only works for resources whose \'relationship\' is \'hasMany\'.'); } if (!(0, _utils.isDataValidForSpliceAndPush)(data)) { throw new TypeError('Tried calling \'push\' with \'data\' that was neither a Resource, ResourceArray, ' + 'Array of Strings, nor a String ID.'); } var checkIsCompliantAndPushData = function checkIsCompliantAndPushData(isCompliant) { if (!isCompliant) { throw new Error('Tried calling \'push\' with \'data\' that violated Redink\'s update constraints.'); } return _rethinkdb2.default.do((0, _queries.pushIdToOriginalField)(schema.type, id, field, records, idsToPush), (0, _queries.pushIdToInverseField)(inverse.type, inverse.field, records, idsToPush, id)).run(conn); }; // Ensure `ids` is an array of id strings if (Array.isArray(data)) idsToPush = data; if (data instanceof _ResourceArray2.default) idsToPush = data.map(function (resource) { return resource.id; }); if (typeof data === 'string') idsToPush = [data]; return (0, _update.isPushCompliant)(relationshipObject, idsToPush, conn).then(checkIsCompliantAndPushData).then(reloadWithOptions); } /** * Splices data from the resource's `relationship`. The `data` can either be a `Resource`, * `ResourceArray`, array of Strings representing ids, or a String id. * * ```javascript * model('user').fetchResource('1').then(user => { * return user.splice('pets', ['1', '2']); * }).then(user => { * const newPets = user.relationship('pets'); // will not include pets with ids '1' and '2' * }); * * model('user', 'animal:pets').map({ * user(model) { * return model.fetchResource('1'); * }, * pets(model) { * return model.find({ filter: { name: 'Lassy' } }), * }, * }).then(results => { * const { user, pets } = results; * return user.splice('pets', pets); * }).then(user => { * const newPets = user.relationship('pets'); // will not include any pets with the name 'Lassy' * }); * ``` * * @async * @method splice * @param {String} relationship * @param {(String|String[]|Resource|ResourceArray)} data * @param {Object} [pre={}] - Critera before merging relationships. * @param {Object} [post={}] - Critera after merging relationships. * @return {Promise<Resource>} */ }, { key: 'splice', value: function splice(relationship, data) { var _this8 = this; var pre = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var post = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var relationshipObject = this.relationship(relationship); var relation = relationshipObject.relation; var inverse = relationshipObject.inverse; var field = relationshipObject.field; var inverseRelation = inverse.relation; var schema = this.schema; var id = this.id; var conn = this.conn; var reloadWithOptions = function reloadWithOptions() { return _this8.reload(pre, post); }; var idsToSplice = void 0; if (relation !== 'hasMany') { throw new TypeError('Tried calling \'splice\' on a resource whose \'relationship\' is \'' + relation + '\'. This method ' + 'only works for resources whose \'relationship\' is \'hasMany\'.'); } if (!(0, _utils.isDataValidForSpliceAndPush)(data)) { throw new TypeError('Tried calling \'splice\' with \'data\' that was neither a Resource, ResourceArray, ' + 'Array of Strings, nor a String ID.'); } var spliceData = function spliceData() { if (!(0, _update.isSpliceCompliant)(inverseRelation)) { throw new Error('Tried calling \'splice\' with a relationship that violated Redink\'s update constraints.'); } // Ensure `ids` is an array of id strings if (Array.isArray(data)) idsToSplice = data; if (data instanceof _ResourceArray2.default) idsToSplice = data.map(function (resource) { return resource.id; }); if (typeof data === 'string') idsToSplice = [data]; return _rethinkdb2.default.do((0, _queries.spliceIdFromOriginalField)(schema.type, field, id, idsToSplice), (0, _queries.spliceIdFromInverseField)(inverse.type, inverse.field, idsToSplice, id)).run(conn); }; return spliceData().then(reloadWithOptions); } /** * Returns true if this is archived. * * @method isArchived * @return {Boolean} */ }, { key: 'isArchived', value: function isArchived() { // eslint-disable-next-line return this.meta._archived; } /** * Returns a plain object with the `id` key, an `attributes` key, a `relationships` key, and a * `meta` key. * * @method toObject * @return {Object} */ }, { key: 'toObject', value: function toObject() { return { id: this.id, attributes: _extends({}, this.attributes), relationships: _extends({}, this.relationships), meta: _extends({}, this.meta) }; } }]); return Resource; }(); exports.default = Resource; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXNvdXJjZS5qcyJdLCJuYW1lcyI6WyJSZXNvdXJjZSIsImNvbm4iLCJzY2hlbWEiLCJyZWNvcmQiLCJUeXBlRXJyb3IiLCJpZCIsIm1ldGEiLCJfbWV0YSIsImF0dHJpYnV0ZXMiLCJyZWxhdGlvbnNoaXBzIiwiT2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJoYXNBdHRyaWJ1dGUiLCJmaWVsZCIsImhhc1JlbGF0aW9uc2hpcCIsInJlbGF0aW9uc2hpcCIsInJlY29yZE9yUmVjb3JkcyIsInJlbGF0aW9uIiwiYXR0cmlidXRlIiwicHJlIiwicG9zdCIsInRhYmxlIiwidHlwZSIsImdldCIsInJ1biIsInRoZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsImludmVyc2UiLCJyZWxhdGVkUmVjb3JkIiwicmVsYXRlZFJlY29yZHMiLCJyZWNvcmRzIiwiZ2V0QWxsIiwiaW5kZXgiLCJhcmdzIiwibWFwIiwiY29lcmNlVG8iLCJmaWVsZHMiLCJyZWxvYWRXaXRoT3B0aW9ucyIsInJlbG9hZCIsInVwZGF0ZSIsImlkVG9SZW1vdmUiLCJpZHMiLCJBcnJheSIsImlzQXJyYXkiLCJldmVyeSIsIml0ZW0iLCJpbnZlcnNlVHlwZSIsImludmVyc2VGaWVsZCIsImlkc1RvVXBkYXRlIiwiaWRUb1NwbGljZSIsInVwZGF0ZU9iamVjdCIsInJlY3Vyc2l2ZWx5QXJjaGl2ZSIsImFsbCIsImludmVyc2VSZWxhdGlvbiIsImZldGNoIiwicmVzb3VyY2VzIiwicmVzb3VyY2UiLCJhcmNoaXZlU3BsaWNlSWRGcm9tSW52ZXJzZUZpZWxkIiwiYXJjaGl2ZSIsImFyY2hpdmVSZW1vdmVJZEZyb21SZWNvcmRGaWVsZCIsImFyY2hpdmVSZW1vdmVJZEZyb21NYW55UmVjb3Jkc0ZpZWxkIiwiZGF0YSIsInJlbGF0aW9uc2hpcE9iamVjdCIsImlkVG9QdXQiLCJwdXREYXRhIiwiaXNDb21wbGlhbnQiLCJFcnJvciIsImRvIiwicmVtb3ZlRGF0YSIsImlkc1RvUHVzaCIsImNoZWNrSXNDb21wbGlhbnRBbmRQdXNoRGF0YSIsImlkc1RvU3BsaWNlIiwic3BsaWNlRGF0YSIsIl9hcmNoaXZlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7cWpCQUFBOzs7QUFDQTs7OztBQUNBOzs7O0FBRUE7O0FBT0E7O0FBUUE7Ozs7Ozs7O0lBWXFCQSxRO0FBQ25COzs7Ozs7OztBQVFBLG9CQUFZQyxJQUFaLEVBQWtCQyxNQUFsQixFQUEwQkMsTUFBMUIsRUFBa0M7QUFBQTs7QUFBQTs7QUFDaEMsUUFBSSxDQUFDRixJQUFMLEVBQVc7QUFDVCxZQUFNLElBQUlHLFNBQUosQ0FBYyxxRUFBZCxDQUFOO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDRixNQUFMLEVBQWE7QUFDWCxZQUFNLElBQUlFLFNBQUosQ0FBYyx1REFBZCxDQUFOO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDRCxNQUFMLEVBQWE7QUFDWCxZQUFNLElBQUlDLFNBQUosQ0FBYyx1REFBZCxDQUFOO0FBQ0Q7O0FBRUQsU0FBS0gsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsU0FBS0MsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsU0FBS0csRUFBTCxHQUFVRixPQUFPRSxFQUFqQjtBQUNBLFNBQUtDLElBQUwsR0FBWUgsT0FBT0ksS0FBUCxJQUFnQixFQUE1Qjs7QUFFQSxTQUFLQyxVQUFMLEdBQWtCLEVBQWxCOztBQUVBO0FBQ0EsU0FBS0MsYUFBTCxnQkFBMEJQLE9BQU9PLGFBQWpDOztBQUVBQyxXQUFPQyxJQUFQLENBQVlSLE1BQVosRUFBb0JTLE9BQXBCLENBQTRCLGlCQUFTO0FBQ25DO0FBQ0EsVUFBSVYsT0FBT1csWUFBUCxDQUFvQkMsS0FBcEIsQ0FBSixFQUFnQztBQUM5QixjQUFLTixVQUFMLENBQWdCTSxLQUFoQixJQUF5QlgsT0FBT1csS0FBUCxDQUF6QjtBQUNBO0FBQ0Q7O0FBRUQ7QUFDQSxVQUFJWixPQUFPYSxlQUFQLENBQXVCRCxLQUF2QixDQUFKLEVBQW1DO0FBQ2pDLFlBQU1FLGVBQWUsTUFBS1AsYUFBTCxDQUFtQkssS0FBbkIsQ0FBckI7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