UNPKG

objection

Version:
1,643 lines (1,202 loc) 127 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _typeof2 = require('babel-runtime/helpers/typeof'); var _typeof3 = _interopRequireDefault(_typeof2); var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor'); var _getOwnPropertyDescriptor2 = _interopRequireDefault(_getOwnPropertyDescriptor); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _create = require('babel-runtime/core-js/object/create'); var _create2 = _interopRequireDefault(_create); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _desc, _value, _class, _class2, _temp; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _AjvValidator = require('./AjvValidator'); var _AjvValidator2 = _interopRequireDefault(_AjvValidator); var _QueryBuilder = require('../queryBuilder/QueryBuilder'); var _QueryBuilder2 = _interopRequireDefault(_QueryBuilder); var _inheritModel = require('./inheritModel'); var _inheritModel2 = _interopRequireDefault(_inheritModel); var _RelationExpression = require('../queryBuilder/RelationExpression'); var _RelationExpression2 = _interopRequireDefault(_RelationExpression); var _modelVisitor = require('./modelVisitor'); var _classUtils = require('../utils/classUtils'); var _hiddenData = require('../utils/hiddenData'); var _hiddenData2 = require('../utils/decorators/hiddenData'); var _hiddenData3 = _interopRequireDefault(_hiddenData2); var _memoize = require('../utils/decorators/memoize'); var _memoize2 = _interopRequireDefault(_memoize); var _Relation = require('../relations/Relation'); var _Relation2 = _interopRequireDefault(_Relation); var _HasOneRelation = require('../relations/hasOne/HasOneRelation'); var _HasOneRelation2 = _interopRequireDefault(_HasOneRelation); var _HasManyRelation = require('../relations/hasMany/HasManyRelation'); var _HasManyRelation2 = _interopRequireDefault(_HasManyRelation); var _ManyToManyRelation = require('../relations/manyToMany/ManyToManyRelation'); var _ManyToManyRelation2 = _interopRequireDefault(_ManyToManyRelation); var _BelongsToOneRelation = require('../relations/belongsToOne/BelongsToOneRelation'); var _BelongsToOneRelation2 = _interopRequireDefault(_BelongsToOneRelation); var _HasOneThroughRelation = require('../relations/hasOneThrough/HasOneThroughRelation'); var _HasOneThroughRelation2 = _interopRequireDefault(_HasOneThroughRelation); var _InstanceFindOperation = require('../queryBuilder/operations/InstanceFindOperation'); var _InstanceFindOperation2 = _interopRequireDefault(_InstanceFindOperation); var _InstanceInsertOperation = require('../queryBuilder/operations/InstanceInsertOperation'); var _InstanceInsertOperation2 = _interopRequireDefault(_InstanceInsertOperation); var _InstanceUpdateOperation = require('../queryBuilder/operations/InstanceUpdateOperation'); var _InstanceUpdateOperation2 = _interopRequireDefault(_InstanceUpdateOperation); var _InstanceDeleteOperation = require('../queryBuilder/operations/InstanceDeleteOperation'); var _InstanceDeleteOperation2 = _interopRequireDefault(_InstanceDeleteOperation); var _JoinEagerOperation = require('../queryBuilder/operations/JoinEagerOperation'); var _JoinEagerOperation2 = _interopRequireDefault(_JoinEagerOperation); var _WhereInEagerOperation = require('../queryBuilder/operations/WhereInEagerOperation'); var _WhereInEagerOperation2 = _interopRequireDefault(_WhereInEagerOperation); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } var JoinEagerAlgorithm = function JoinEagerAlgorithm() { return new _JoinEagerOperation2.default('eager'); }; var WhereInEagerAlgorithm = function WhereInEagerAlgorithm() { return new _WhereInEagerOperation2.default('eager'); }; /** * @typedef {Object} ModelOptions * * @property {boolean} [patch] * @property {boolean} [skipValidation] * @property {Model} [old] */ var Model = (_dec = (0, _hiddenData3.default)({ name: 'omitFromJson', append: true }), _dec2 = (0, _hiddenData3.default)({ name: 'omitFromDatabaseJson', append: true }), _dec3 = (0, _hiddenData3.default)(), _dec4 = (0, _hiddenData3.default)(), _dec5 = (0, _hiddenData3.default)(), _dec6 = (0, _hiddenData3.default)(), (_class = (_temp = _class2 = function () { function Model() { (0, _classCallCheck3.default)(this, Model); } /** * @param {*=} id * @returns {*} */ /** * @type {object} */ /** * @type {boolean} */ /** * @type {Object.<string, RelationMapping>} */ /** * @type {Array.<string>} */ /** * @type {string} */ /** * @type {string} */ /** * @type {Object} */ Model.prototype.$id = function $id(id) { if (arguments.length > 0) { return setId(this, arguments[0]); } else { return getId(this); } }; /** * @returns {knex} */ /** * @private */ /** * @type {Constructor.<? extends EagerOperation>} */ /** * @type {Array.<string>} */ /** * @type {Array.<string>} */ /** * @type {RegExp} */ /** * @type {string} */ /** * @type {string|Array.<string>} */ /** * @type {string} */ Model.prototype.$knex = function $knex() { return this.constructor.knex(); }; /** * @returns {knex} */ Model.prototype.$transaction = function $transaction() { return this.constructor.transaction(); }; /** * @param {Transaction=} trx * @returns {QueryBuilder} */ Model.prototype.$query = function $query(trx) { var _this = this; var ModelClass = this.constructor; return ModelClass.QueryBuilder.forClass(ModelClass).transacting(trx).findOperationFactory(function () { return new _InstanceFindOperation2.default('find', { instance: _this }); }).insertOperationFactory(function () { return new _InstanceInsertOperation2.default('insert', { instance: _this }); }).updateOperationFactory(function () { return new _InstanceUpdateOperation2.default('update', { instance: _this }); }).patchOperationFactory(function () { return new _InstanceUpdateOperation2.default('patch', { instance: _this, modelOptions: { patch: true } }); }).deleteOperationFactory(function () { return new _InstanceDeleteOperation2.default('delete', { instance: _this }); }).relateOperationFactory(function () { throw new Error('`relate` makes no sense in this context'); }).unrelateOperationFactory(function () { throw new Error('`unrelate` makes no sense in this context'); }); }; /** * @param {string} relationName * @param {Transaction=} trx * @returns {QueryBuilder} */ Model.prototype.$relatedQuery = function $relatedQuery(relationName, trx) { var _this2 = this; var ModelClass = this.constructor; var relation = ModelClass.getRelation(relationName); var RelatedModelClass = relation.relatedModelClass; return ModelClass.RelatedQueryBuilder.forClass(RelatedModelClass).transacting(trx).findOperationFactory(function (builder) { return relation.find(builder, [_this2]); }).insertOperationFactory(function (builder) { return relation.insert(builder, _this2); }).updateOperationFactory(function (builder) { return relation.update(builder, _this2); }).patchOperationFactory(function (builder) { return relation.patch(builder, _this2); }).deleteOperationFactory(function (builder) { return relation.delete(builder, _this2); }).relateOperationFactory(function (builder) { return relation.relate(builder, _this2); }).unrelateOperationFactory(function (builder) { return relation.unrelate(builder, _this2); }); }; /** * @param {string|RelationExpression} relationExpression * @param {Object.<string, function(QueryBuilder)>=} filters * @returns {QueryBuilder} */ Model.prototype.$loadRelated = function $loadRelated(relationExpression, filters) { return this.constructor.loadRelated(this, relationExpression, filters); }; /** * @param {Constructor.<Model>=} filterConstructor * @param {function(Model)} callback * @return {Model} */ Model.prototype.$traverse = function $traverse(filterConstructor, callback) { if (_lodash2.default.isUndefined(callback)) { callback = filterConstructor; filterConstructor = null; } this.constructor.traverse(filterConstructor, this, callback); return this; }; /** * @param {Object} jsonSchema * @param {Object} json * @param {ModelOptions=} options * @return {Object} */ Model.prototype.$beforeValidate = function $beforeValidate(jsonSchema, json, options) { /* istanbul ignore next */ return jsonSchema; }; /** * @param {Object=} json * @param {ModelOptions=} options * @throws {ValidationError} * @return {Object} */ Model.prototype.$validate = function $validate() { var json = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (json instanceof Model) { // Strip away relations and other internal stuff. json = cloneModel(json, true, true); } if (options.skipValidation) { return json; } var validator = this.constructor.getValidator(); var args = { options: options, model: this, json: json, ctx: (0, _create2.default)(null) }; validator.beforeValidate(args); json = validator.validate(args); validator.afterValidate(args); return json; }; /** * @param {Object=} json * @param {ModelOptions=} options */ Model.prototype.$afterValidate = function $afterValidate(json, options) {} // Do nothing by default. /** * @param {Object} json * @return {Object} */ ; Model.prototype.$parseDatabaseJson = function $parseDatabaseJson(json) { var jsonAttr = this.constructor.getJsonAttributes(); if (jsonAttr.length) { for (var i = 0, l = jsonAttr.length; i < l; ++i) { var attr = jsonAttr[i]; var value = json[attr]; if (_lodash2.default.isString(value)) { var parsed = tryParseJson(value); // tryParseJson returns undefined if parsing failed. if (parsed !== undefined) { json[attr] = parsed; } } } } return json; }; /** * @param {Object} json * @return {Object} */ Model.prototype.$formatDatabaseJson = function $formatDatabaseJson(json) { var jsonAttr = this.constructor.getJsonAttributes(); if (jsonAttr.length) { for (var i = 0, l = jsonAttr.length; i < l; ++i) { var attr = jsonAttr[i]; var value = json[attr]; if (_lodash2.default.isObject(value)) { json[attr] = (0, _stringify2.default)(value); } } } return json; }; /** * @param {Object} json * @param {ModelOptions=} options * @return {Object} */ Model.prototype.$parseJson = function $parseJson(json, options) { return json; }; /** * @param {Object} json * @return {Object} */ Model.prototype.$formatJson = function $formatJson(json) { return json; }; /** * @param {Object} json * @param {ModelOptions=} options * @returns {Model} * @throws ValidationError */ Model.prototype.$setJson = function $setJson(json) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; json = json || {}; if (!_lodash2.default.isObject(json) || _lodash2.default.isString(json) || _lodash2.default.isNumber(json) || _lodash2.default.isDate(json) || _lodash2.default.isArray(json) || _lodash2.default.isFunction(json) || _lodash2.default.isTypedArray(json) || _lodash2.default.isRegExp(json)) { throw new Error('You should only pass objects to $setJson method. ' + '$setJson method was given an invalid value ' + json); } json = this.$parseJson(json, options); json = this.$validate(json, options); // TODO Move to bottom. this.$set(json); var relations = this.constructor.getRelationArray(); // Parse relations into Model instances. for (var i = 0, l = relations.length; i < l; ++i) { var relation = relations[i]; var relationName = relation.name; if (_lodash2.default.has(json, relationName)) { var relationJson = json[relationName]; if (Array.isArray(relationJson)) { this[relationName] = relation.relatedModelClass.ensureModelArray(relationJson, options); } else if (relationJson) { this[relationName] = relation.relatedModelClass.ensureModel(relationJson, options); } else { this[relationName] = null; } } } }; /** * @param {Object} json * @returns {Model} */ Model.prototype.$setDatabaseJson = function $setDatabaseJson(json) { json = this.$parseDatabaseJson(json); if (json) { var keys = (0, _keys2.default)(json); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; this[key] = json[key]; } } return this; }; /** * @param {Object} obj * @returns {Model} */ Model.prototype.$set = function $set(obj) { if (obj) { var keys = (0, _keys2.default)(obj); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; var value = obj[key]; if (key.charAt(0) !== '$' && typeof value !== 'function') { this[key] = value; } } } return this; }; /** * @param {boolean=} shallow */ Model.prototype.$toJson = function $toJson(shallow) { if (shallow) { return this.$$toJson(false, this.constructor.getRelations(), null); } else { return this.$$toJson(false, null, null); } }; Model.prototype.toJSON = function toJSON() { return this.$toJson(); }; /** * @override */ Model.prototype.$toDatabaseJson = function $toDatabaseJson() { var jsonSchema = this.constructor.getJsonSchema(); if (jsonSchema && this.constructor.pickJsonSchemaProperties) { return this.$$toJson(true, null, jsonSchema.properties); } else { return this.$$toJson(true, this.constructor.getRelations(), null); } }; /** * @param {Object} queryContext * @returns {Promise|*} */ Model.prototype.$beforeInsert = function $beforeInsert(queryContext) {}; /** * @param {Object} queryContext * @returns {Promise|*} */ Model.prototype.$afterInsert = function $afterInsert(queryContext) {}; /** * @param {ModelOptions} opt * @param {QueryBuilderContext} queryContext * @returns {Promise|*} */ Model.prototype.$beforeUpdate = function $beforeUpdate(opt, queryContext) {}; /** * @param {ModelOptions} opt * @param {QueryBuilderContext} queryContext * @returns {Promise|*} */ Model.prototype.$afterUpdate = function $afterUpdate(opt, queryContext) {}; /** * @param {QueryBuilderContext} queryContext * @returns {Promise|*} */ Model.prototype.$afterGet = function $afterGet(queryContext) {}; /** * @param {QueryBuilderContext} queryContext * @returns {Promise|*} */ Model.prototype.$beforeDelete = function $beforeDelete(queryContext) {}; /** * @param {QueryBuilderContext} queryContext * @returns {Promise|*} */ Model.prototype.$afterDelete = function $afterDelete(queryContext) {}; /** * @param {string|Array.<string>|Object.<string, boolean>} keys * @returns {Model} */ Model.prototype.$omit = function $omit() { if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { var keys = arguments[0]; if (Array.isArray(keys)) { omitArray(this, keys); } else { omitObject(this, keys); } } else { omitArray(this, _lodash2.default.toArray(arguments)); } return this; }; /** * @param {string|Array.<string>|Object.<string, boolean>} keys * @returns {Model} `this` for chaining. */ Model.prototype.$pick = function $pick() { if (arguments.length === 1 && _lodash2.default.isObject(arguments[0])) { var keys = arguments[0]; if (Array.isArray(keys)) { pickArray(this, keys); } else { pickObject(this, keys); } } else { pickArray(this, _lodash2.default.toArray(arguments)); } return this; }; /** * @param {Array.<string>} props * @return {Array.<*>} */ Model.prototype.$values = function $values() { if (arguments.length === 0) { return _lodash2.default.values(this); } else { var args = arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments; switch (args.length) { case 1: return [this[args[0]]]; case 2: return [this[args[0]], this[args[1]]]; case 3: return [this[args[0]], this[args[1]], this[args[2]]]; default: { var ret = new Array(args.length); for (var i = 0, l = args.length; i < l; ++i) { ret[i] = this[args[i]]; } return ret; } } } }; /** * @param {Array.<string>} props * @return {string} */ Model.prototype.$propKey = function $propKey(props) { switch (props.length) { case 1: return this[props[0]] + ''; case 2: return this[props[0]] + ',' + this[props[1]]; case 3: return this[props[0]] + ',' + this[props[1]] + ',' + this[props[2]]; default: { var key = ''; for (var i = 0, l = props.length; i < l; ++i) { key += this[props[i]] + (i < props.length - 1 ? ',' : ''); } return key; } } }; /** * @param {boolean} shallow * @return {Model} */ Model.prototype.$clone = function $clone(shallow) { return cloneModel(this, shallow, false); }; /** * @param {Array.<string>=} keys * @returns {Array.<string>} */ Model.prototype.$omitFromJson = function $omitFromJson(keys) {}; /** * @param {Array.<string>=} keys * @returns {Array.<string>} */ Model.prototype.$omitFromDatabaseJson = function $omitFromDatabaseJson(keys) {}; /** * @protected */ Model.prototype.$$toJson = function $$toJson(createDbJson, omit, pick) { var json = toJsonImpl(this, createDbJson, omit, pick); if (createDbJson) { return this.$formatDatabaseJson(json); } else { return this.$formatJson(json); } }; /** * @param {function=} subclassConstructor * @return {Constructor.<Model>} */ Model.extend = function extend(subclassConstructor) { if (_lodash2.default.isEmpty(subclassConstructor.name)) { throw new Error('Each Model subclass constructor must have a name'); } (0, _classUtils.inherits)(subclassConstructor, this); return subclassConstructor; }; /** * @param {Object=} json * @param {ModelOptions=} options * @returns {Model} * @throws ValidationError */ Model.fromJson = function fromJson(json, options) { var model = new this(); model.$setJson(json || {}, options); return model; }; /** * @param {Object=} json * @returns {Model} */ Model.fromDatabaseJson = function fromDatabaseJson(json) { var model = new this(); model.$setDatabaseJson(json || {}); return model; }; /** * @param {Object} obj * @param {string} prop */ Model.omitImpl = function omitImpl(obj, prop) { delete obj[prop]; }; /** * @return {Validator} */ Model.createValidator = function createValidator() { return new _AjvValidator2.default({ onCreateAjv: function onCreateAjv(ajv) {/* Do Nothing by default */}, options: { allErrors: true, validateSchema: false, ownProperties: true, v5: true } }); }; /** * @return {Validator} */ Model.getValidator = function getValidator() { return this.createValidator(); }; /** * @return {Object} */ Model.getJsonSchema = function getJsonSchema() { // Memoized getter in case jsonSchema is a getter property (usually is with ES6). return this.jsonSchema; }; /** * @param {string} columnName * @returns {string} */ Model.columnNameToPropertyName = function columnNameToPropertyName(columnName) { var model = new this(); var addedProps = _lodash2.default.keys(model.$parseDatabaseJson({})); var row = {}; row[columnName] = null; var props = _lodash2.default.keys(model.$parseDatabaseJson(row)); var propertyName = _lodash2.default.first(_lodash2.default.difference(props, addedProps)); return propertyName || null; }; /** * @param {string} propertyName * @returns {string} */ Model.propertyNameToColumnName = function propertyNameToColumnName(propertyName) { var model = new this(); var addedCols = _lodash2.default.keys(model.$formatDatabaseJson({})); var obj = {}; obj[propertyName] = null; var cols = _lodash2.default.keys(model.$formatDatabaseJson(obj)); var columnName = _lodash2.default.first(_lodash2.default.difference(cols, addedCols)); return columnName || null; }; /** * @param {Transaction=} trx * @returns {QueryBuilder} */ Model.query = function query(trx) { var ModelClass = this; return ModelClass.QueryBuilder.forClass(ModelClass).transacting(trx).relateOperationFactory(function () { throw new Error('`relate` makes no sense in this context'); }).unrelateOperationFactory(function () { throw new Error('`unrelate` makes no sense in this context'); }); }; /** * @param {knex=} knex * @returns {knex} */ Model.knex = function knex(_knex) { if (arguments.length) { this.$$knex = _knex; } else { return this.$$knex; } }; /** * @returns {knex} */ Model.transaction = function transaction() { return this.knex(); }; /** * @return {Raw} */ Model.raw = function raw() { var knex = this.knex(); return knex.raw.apply(knex, arguments); }; /** * @return {Object} */ Model.fn = function fn() { var knex = this.knex(); return knex.fn; }; /** * @return {Formatter} */ Model.formatter = function formatter() { return this.knex().client.formatter(); }; /** * @returns {knex.QueryBuilder} */ Model.knexQuery = function knexQuery() { return this.knex().table(this.tableName); }; /** * @returns {string} */ Model.uniqueTag = function uniqueTag() { return this.tableName; }; /** * @param {knex} knex * @returns {Constructor.<Model>} */ Model.bindKnex = function bindKnex(knex) { var ModelClass = this; if (!knex.$$objection) { Object.defineProperty(knex, '$$objection', { enumerable: false, writable: false, value: { boundModels: (0, _create2.default)(null) } }); } // Check if this model class has already been bound to the given knex. if (knex.$$objection.boundModels[ModelClass.uniqueTag()]) { return knex.$$objection.boundModels[ModelClass.uniqueTag()]; } // Create a new subclass of this class. var BoundModelClass = (0, _inheritModel2.default)(ModelClass); // The bound model is equal to the source model in every way. We want to copy // the hidden data as-is from the source so that we don't get the performance // penalty of calculating all memoized etc. values again. (0, _hiddenData.inheritHiddenData)(ModelClass, BoundModelClass); BoundModelClass.knex(knex); knex.$$objection.boundModels[ModelClass.uniqueTag()] = BoundModelClass; var boundRelations = (0, _create2.default)(null); var relations = ModelClass.getRelationArray(); for (var i = 0, l = relations.length; i < l; ++i) { var relation = relations[i]; boundRelations[relation.name] = relation.bindKnex(knex); } BoundModelClass.relations = boundRelations; BoundModelClass.relationArray = _lodash2.default.values(boundRelations); return BoundModelClass; }; /** * @param {knex} trx * @returns {Constructor.<Model>} */ Model.bindTransaction = function bindTransaction(trx) { return this.bindKnex(trx); }; /** * @param {Model|Object} model * @param {ModelOptions=} options * @returns {Model} */ Model.ensureModel = function ensureModel(model, options) { var ModelClass = this; if (!model) { return null; } if (model instanceof ModelClass) { return model; } else { return ModelClass.fromJson(model, options); } }; /** * @param {Array.<Model|Object>} input * @param {ModelOptions=} options * @returns {Array.<Model>} */ Model.ensureModelArray = function ensureModelArray(input, options) { if (!input) { return []; } if (Array.isArray(input)) { var models = new Array(input.length); for (var i = 0, l = input.length; i < l; ++i) { models[i] = this.ensureModel(input[i], options); } return models; } else { return [this.ensureModel(input, options)]; } }; /** * @returns {Array.<string>} */ Model.getIdColumnArray = function getIdColumnArray() { if (Array.isArray(this.idColumn)) { return this.idColumn; } else { return [this.idColumn]; } }; /** * @returns {string|Array.<string>} */ Model.getFullIdColumn = function getFullIdColumn() { var _this3 = this; if (Array.isArray(this.idColumn)) { return this.idColumn.map(function (col) { return _this3.tableName + '.' + col; }); } else { return this.tableName + '.' + this.idColumn; } }; /** * @returns {Array.<string>} */ Model.getIdPropertyArray = function getIdPropertyArray() { var _this4 = this; return this.getIdColumnArray().map(function (col) { return idColumnToIdProperty(_this4, col); }); }; /** * @returns {string|Array.<string>} */ Model.getIdProperty = function getIdProperty() { var _this5 = this; if (Array.isArray(this.idColumn)) { return this.idColumn.map(function (col) { return idColumnToIdProperty(_this5, col); }); } else { return idColumnToIdProperty(this, this.idColumn); } }; /** * @private */ /** * @return {Object.<string, Relation>} */ Model.getRelations = function getRelations() { var _this6 = this; var relations = this.relations; if (!relations) { relations = _lodash2.default.reduce(_lodash2.default.result(this, 'relationMappings'), function (relations, mapping, relationName) { relations[relationName] = new mapping.relation(relationName, _this6); relations[relationName].setMapping(mapping); return relations; }, (0, _create2.default)(null)); this.relations = relations; } return relations; }; /** * @return {Array.<Relation>} */ Model.getRelationArray = function getRelationArray() { var relationArray = this.relationArray; if (!relationArray) { relationArray = _lodash2.default.values(this.getRelations()); this.relationArray = relationArray; } return relationArray; }; /** * @return {Relation} */ Model.getRelation = function getRelation(name) { var relation = this.getRelations()[name]; if (!relation) { throw new Error('A model class (tableName = ' + this.tableName + ') doesn\'t have relation ' + name); } return relation; }; /** * @param {Array.<Model|Object>} $models * @param {string|RelationExpression} expression * @param {Object.<string, function(QueryBuilder)>=} filters * @returns {QueryBuilder} */ Model.loadRelated = function loadRelated($models, expression, filters) { return this.query().resolve(this.ensureModelArray($models)).findOptions({ dontCallAfterGet: true }).eager(expression, filters).runAfter(function (models) { return Array.isArray($models) ? models : models[0]; }); }; /** * @param {Constructor.<Model>=} filterConstructor * @param {Model|Array.<Model>} models * @param {function(Model, Model, string)} traverser * @return {Model} */ Model.traverse = function traverse(filterConstructor, models, traverser) { filterConstructor = filterConstructor || null; if (_lodash2.default.isUndefined(traverser)) { traverser = models; models = filterConstructor; filterConstructor = null; } if (!_lodash2.default.isFunction(traverser)) { throw new Error('traverser must be a function'); } if (!models) { return; } var modelClass = Array.isArray(models) ? models[0].constructor : models.constructor; (0, _modelVisitor.visitModels)(models, modelClass, function (model, modelClass, parent, relation) { if (!filterConstructor || model instanceof filterConstructor) { traverser(model, parent, relation && relation.name); } }); return this; }; /** * @protected * @returns {Array.<string>} */ Model.getJsonAttributes = function getJsonAttributes() { var _this7 = this; // If the jsonAttributes property is not set, try to create it based // on the jsonSchema. All properties that are objects or arrays must // be converted to JSON. if (!this.jsonAttributes && this.getJsonSchema()) { this.jsonAttributes = []; _lodash2.default.forOwn(this.getJsonSchema().properties, function (prop, propName) { var types = _lodash2.default.compact(ensureArray(prop.type)); if (types.length === 0 && Array.isArray(prop.anyOf)) { types = _lodash2.default.flattenDeep(_lodash2.default.map(prop.anyOf, 'type')); } if (types.length === 0 && Array.isArray(prop.oneOf)) { types = _lodash2.default.flattenDeep(_lodash2.default.map(prop.oneOf, 'type')); } if (_lodash2.default.includes(types, 'object') || _lodash2.default.includes(types, 'array')) { _this7.jsonAttributes.push(propName); } }); } if (!Array.isArray(this.jsonAttributes)) { this.jsonAttributes = []; } return this.jsonAttributes; }; (0, _createClass3.default)(Model, null, [{ key: 'relations', get: function get() {} /** * @private */ , set: function set(value) {} /** * @private */ }, { key: 'relationArray', get: function get() {} /** * @private */ , set: function set(value) {} }]); return Model; }(), _class2.QueryBuilder = _QueryBuilder2.default, _class2.RelatedQueryBuilder = _QueryBuilder2.default, _class2.HasOneRelation = _HasOneRelation2.default, _class2.HasManyRelation = _HasManyRelation2.default, _class2.ManyToManyRelation = _ManyToManyRelation2.default, _class2.BelongsToOneRelation = _BelongsToOneRelation2.default, _class2.HasOneThroughRelation = _HasOneThroughRelation2.default, _class2.JoinEagerAlgorithm = JoinEagerAlgorithm, _class2.WhereInEagerAlgorithm = WhereInEagerAlgorithm, _class2.tableName = null, _class2.jsonSchema = null, _class2.idColumn = 'id', _class2.uidProp = '#id', _class2.uidRefProp = '#ref', _class2.dbRefProp = '#dbRef', _class2.propRefRegex = /#ref{([^\.]+)\.([^}]+)}/g, _class2.jsonAttributes = null, _class2.virtualAttributes = null, _class2.relationMappings = null, _class2.modelPaths = [], _class2.pickJsonSchemaProperties = true, _class2.defaultEagerAlgorithm = WhereInEagerAlgorithm, _class2.defaultEagerOptions = null, _class2.$$knex = null, _temp), (_applyDecoratedDescriptor(_class.prototype, '$omitFromJson', [_dec], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$omitFromJson'), _class.prototype), _applyDecoratedDescriptor(_class.prototype, '$omitFromDatabaseJson', [_dec2], (0, _getOwnPropertyDescriptor2.default)(_class.prototype, '$omitFromDatabaseJson'), _class.prototype), _applyDecoratedDescriptor(_class, 'getValidator', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getValidator'), _class), _applyDecoratedDescriptor(_class, 'getJsonSchema', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getJsonSchema'), _class), _applyDecoratedDescriptor(_class, 'columnNameToPropertyName', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'columnNameToPropertyName'), _class), _applyDecoratedDescriptor(_class, 'propertyNameToColumnName', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'propertyNameToColumnName'), _class), _applyDecoratedDescriptor(_class, 'getIdColumnArray', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdColumnArray'), _class), _applyDecoratedDescriptor(_class, 'getFullIdColumn', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getFullIdColumn'), _class), _applyDecoratedDescriptor(_class, 'getIdPropertyArray', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdPropertyArray'), _class), _applyDecoratedDescriptor(_class, 'getIdProperty', [_memoize2.default], (0, _getOwnPropertyDescriptor2.default)(_class, 'getIdProperty'), _class), _applyDecoratedDescriptor(_class, 'relations', [_dec3], (0, _getOwnPropertyDescriptor2.default)(_class, 'relations'), _class), _applyDecoratedDescriptor(_class, 'relationArray', [_dec4], (0, _getOwnPropertyDescriptor2.default)(_class, 'relationArray'), _class), _applyDecoratedDescriptor(_class, 'relations', [_dec5], (0, _getOwnPropertyDescriptor2.default)(_class, 'relations'), _class), _applyDecoratedDescriptor(_class, 'relationArray', [_dec6], (0, _getOwnPropertyDescriptor2.default)(_class, 'relationArray'), _class)), _class)); exports.default = Model; function setId(model, id) { var idProp = model.constructor.getIdProperty(); var isArray = Array.isArray(idProp); if (Array.isArray(id)) { if (isArray) { if (id.length !== idProp.length) { throw new Error('trying to set an invalid identifier for a model'); } for (var i = 0; i < id.length; ++i) { model[idProp[i]] = id[i]; } } else { if (id.length !== 1) { throw new Error('trying to set an invalid identifier for a model'); } model[idProp] = id[0]; } } else { if (isArray) { if (idProp.length > 1) { throw new Error('trying to set an invalid identifier for a model'); } model[idProp[0]] = id; } else { model[idProp] = id; } } } function getId(model) { var idProp = model.constructor.getIdProperty(); if (Array.isArray(idProp)) { return model.$values(idProp); } else { return model[idProp]; } } function tryParseJson(maybeJsonStr) { try { return JSON.parse(maybeJsonStr); } catch (err) { // Ignore error. } return undefined; } function toJsonImpl(model, createDbJson, omit, pick) { if (createDbJson) { return toDatabaseJsonImpl(model, omit, pick); } else { return toExternalJsonImpl(model, omit, pick); } } function toDatabaseJsonImpl(model, omit, pick) { var json = {}; var omitFromJson = model.$omitFromDatabaseJson(); var keys = (0, _keys2.default)(model); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; assignJsonValue(json, key, model[key], omit, pick, omitFromJson, true); } return json; } function toExternalJsonImpl(model, omit, pick) { var json = {}; var omitFromJson = model.$omitFromJson(); var keys = (0, _keys2.default)(model); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; assignJsonValue(json, key, model[key], omit, pick, omitFromJson, false); } if (model.constructor.virtualAttributes) { var vAttr = model.constructor.virtualAttributes; for (var _i = 0, _l = vAttr.length; _i < _l; ++_i) { var _key = vAttr[_i]; var value = model[_key]; if (_lodash2.default.isFunction(value)) { value = value.call(model); } assignJsonValue(json, _key, value, omit, pick, omitFromJson, false); } } return json; } function assignJsonValue(json, key, value, omit, pick, omitFromJson, createDbJson) { if (key.charAt(0) !== '$' && !_lodash2.default.isFunction(value) && !_lodash2.default.isUndefined(value) && (!omit || !omit[key]) && (!pick || pick[key]) && (!omitFromJson || !contains(omitFromJson, key))) { if (value !== null && (typeof value === 'undefined' ? 'undefined' : (0, _typeof3.default)(value)) === 'object') { json[key] = toJsonObject(value, createDbJson); } else { json[key] = value; } } } function toJsonObject(value, createDbJson) { if (Array.isArray(value)) { return toJsonArray(value, createDbJson); } else if (value instanceof Model) { if (createDbJson) { return value.$toDatabaseJson(); } else { return value.$toJson(); } } else if (Buffer.isBuffer(value)) { return value; } else { return _lodash2.default.cloneDeep(value); } } function toJsonArray(value, createDbJson) { var ret = new Array(value.length); for (var i = 0, l = ret.length; i < l; ++i) { ret[i] = toJsonObject(value[i], createDbJson); } return ret; } function cloneModel(model, shallow, stripInternal) { var clone = new model.constructor(); var relations = model.constructor.getRelations(); var keys = (0, _keys2.default)(model); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; var value = model[key]; if (shallow && relations[key]) { continue; } if (stripInternal && key.charAt(0) === '$') { continue; } if (_lodash2.default.isObject(value)) { clone[key] = cloneObject(value); } else { clone[key] = value; } } if (model.$omitFromDatabaseJson()) { clone.$omitFromDatabaseJson(model.$omitFromDatabaseJson()); } if (model.$omitFromJson()) { clone.$omitFromJson(model.$omitFromJson()); } return clone; } function cloneObject(value) { if (Array.isArray(value)) { return cloneArray(value); } else if (value instanceof Model) { return value.$clone(); } else if (Buffer.isBuffer(value)) { return new Buffer(value); } else { return _lodash2.default.cloneDeep(value); } } function cloneArray(value) { var ret = new Array(value.length); for (var i = 0, l = ret.length; i < l; ++i) { ret[i] = cloneObject(value[i]); } return ret; } function omitObject(model, keyObj) { var ModelClass = model.constructor; var keys = (0, _keys2.default)(keyObj); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; var value = keyObj[key]; if (value && key.charAt(0) !== '$' && _lodash2.default.has(model, key)) { ModelClass.omitImpl(model, key); } } } function omitArray(model, keys) { var ModelClass = model.constructor; for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; if (key.charAt(0) !== '$' && _lodash2.default.has(model, key)) { ModelClass.omitImpl(model, key); } } } function pickObject(model, keyObj) { var ModelClass = model.constructor; var keys = (0, _keys2.default)(model); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; if (key.charAt(0) !== '$' && !keyObj[key]) { ModelClass.omitImpl(model, key); } } } function pickArray(model, pick) { var ModelClass = model.constructor; var keys = (0, _keys2.default)(model); for (var i = 0, l = keys.length; i < l; ++i) { var key = keys[i]; if (key.charAt(0) !== '$' && !contains(pick, key)) { ModelClass.omitImpl(model, key); } } } function contains(arr, value) { for (var i = 0, l = arr.length; i < l; ++i) { if (arr[i] === value) { return true; } } return false; } function ensureArray(obj) { if (Array.isArray(obj)) { return obj; } else { return [obj]; } } function idColumnToIdProperty(ModelClass, idColumn) { var idProperty = ModelClass.columnNameToPropertyName(idColumn); if (!idProperty) { throw new Error(ModelClass.tableName + '.$parseDatabaseJson probably changes the value of the id column `' + idColumn + '` which is a no-no.'); } return idProperty; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIk1vZGVsLmpzIl0sIm5hbWVzIjpbIkpvaW5FYWdlckFsZ29yaXRobSIsIldoZXJlSW5FYWdlckFsZ29yaXRobSIsIk1vZGVsIiwibmFtZSIsImFwcGVuZCIsIiRpZCIsImlkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwic2V0SWQiLCJnZXRJZCIsIiRrbmV4IiwiY29uc3RydWN0b3IiLCJrbmV4IiwiJHRyYW5zYWN0aW9uIiwidHJhbnNhY3Rpb24iLCIkcXVlcnkiLCJ0cngiLCJNb2RlbENsYXNzIiwiUXVlcnlCdWlsZGVyIiwiZm9yQ2xhc3MiLCJ0cmFuc2FjdGluZyIsImZpbmRPcGVyYXRpb25GYWN0b3J5IiwiaW5zdGFuY2UiLCJpbnNlcnRPcGVyYXRpb25GYWN0b3J5IiwidXBkYXRlT3BlcmF0aW9uRmFjdG9yeSIsInBhdGNoT3BlcmF0aW9uRmFjdG9yeSIsIm1vZGVsT3B0aW9ucyIsInBhdGNoIiwiZGVsZXRlT3BlcmF0aW9uRmFjdG9yeSIsInJlbGF0ZU9wZXJhdGlvbkZhY3RvcnkiLCJFcnJvciIsInVucmVsYXRlT3BlcmF0aW9uRmFjdG9yeSIsIiRyZWxhdGVkUXVlcnkiLCJyZWxhdGlvbk5hbWUiLCJyZWxhdGlvbiIsImdldFJlbGF0aW9uIiwiUmVsYXRlZE1vZGVsQ2xhc3MiLCJyZWxhdGVkTW9kZWxDbGFzcyIsIlJlbGF0ZWRRdWVyeUJ1aWxkZXIiLCJmaW5kIiwiYnVpbGRlciIsImluc2VydCIsInVwZGF0ZSIsImRlbGV0ZSIsInJlbGF0ZSIsInVucmVsYXRlIiwiJGxvYWRSZWxhdGVkIiwicmVsYXRpb25FeHByZXNzaW9uIiwiZmlsdGVycyIsImxvYWRSZWxhdGVkIiwiJHRyYXZlcnNlIiwiZmlsdGVyQ29uc3RydWN0b3IiLCJjYWxsYmFjayIsImlzVW5kZWZpbmVkIiwidHJhdmVyc2UiLCIkYmVmb3JlVmFsaWRhdGUiLCJqc29uU2NoZW1hIiwianNvbiIsIm9wdGlvbnMiLCIkdmFsaWRhdGUiLCJjbG9uZU1vZGVsIiwic2tpcFZhbGlkYXRpb24iLCJ2YWxpZGF0b3IiLCJnZXRWYWxpZGF0b3IiLCJhcmdzIiwibW9kZWwiLCJjdHgiLCJiZWZvcmVWYWxpZGF0ZSIsInZhbGlkYXRlIiwiYWZ0ZXJWYWxpZGF0ZSIsIiRhZnRlclZhbGlkYXRlIiwiJHBhcnNlRGF0YWJhc2VKc29uIiwianNvbkF0dHIiLCJnZXRKc29uQXR0cmlidXRlcyIsImkiLCJsIiwiYXR0ciIsInZhbHVlIiwiaXNTdHJpbmciLCJwYXJzZWQiLCJ0cnlQYXJzZUpzb24iLCJ1bmRlZmluZWQiLCIkZm9ybWF0RGF0YWJhc2VKc29uIiwiaXNPYmplY3QiLCIkcGFyc2VKc29uIiwiJGZvcm1hdEpzb24iLCIkc2V0SnNvbiIsImlzTnVtYmVyIiwiaXNEYXRlIiwiaXNBcnJheSIsImlzRnVuY3Rpb24iLCJpc1R5cGVkQXJyYXkiLCJpc1JlZ0V4cCIsIiRzZXQiLCJyZWxhdGlvbnMiLCJnZXRSZWxhdGlvbkFycmF5IiwiaGFzIiwicmVsYXRpb25Kc29uIiwiQXJyYXkiLCJlbnN1cmVNb2RlbEFycmF5IiwiZW5zdXJlTW9kZWwiLCIkc2V0RGF0YWJhc2VKc29uIiwia2V5cyIsImtleSIsIm9iaiIsImNoYXJBdCIsIiR0b0pzb24iLCJzaGFsbG93IiwiJCR0b0pzb24iLCJnZXRSZWxhdGlvbnMiLCJ0b0pTT04iLCIkdG9EYXRhYmFzZUpzb24iLCJnZXRKc29uU2NoZW1hIiwicGlja0pzb25TY2hlbWFQcm9wZXJ0aWVzIiwicHJvcGVydGllcyIsIiRiZWZvcmVJbnNlcnQiLCJxdWVyeUNvbnRleHQiLCIkYWZ0ZXJJbnNlcnQiLCIkYmVmb3JlVXBkYXRlIiwib3B0IiwiJGFmdGVyVXBkYXRlIiwiJGFmdGVyR2V0IiwiJGJlZm9yZURlbGV0ZSIsIiRhZnRlckRlbGV0ZSIsIiRvbWl0Iiwib21pdEFycmF5Iiwib21pdE9iamVjdCIsInRvQXJyYXkiLCIkcGljayIsInBpY2tBcnJheSIsInBpY2tPYmplY3QiLCIkdmFsdWVzIiwidmFsdWVzIiwicmV0IiwiJHByb3BLZXkiLCJwcm9wcyIsIiRjbG9uZSIsIiRvbWl0RnJvbUpzb24iLCIkb21pdEZyb21EYXRhYmFzZUpzb24iLCJjcmVhdGVEYkpzb24iLCJvbWl0IiwicGljayIsInRvSnNvbkltcGwiLCJleHRlbmQiLCJzdWJjbGFzc0NvbnN0cnVjdG9yIiwiaXNFbXB0eSIsImZyb21Kc29uIiwiZnJvbURhdGFiYXNlSnNvbiIsIm9taXRJbXBsIiwicHJvcCIsImNyZWF0ZVZhbGlkYXRvciIsIm9uQ3JlYXRlQWp2IiwiYWp2IiwiYWxsRXJyb3JzIiwidmFsaWRhdGVTY2hlbWEiLCJvd25Qcm9wZXJ0aWVzIiwidjUiLCJjb2x1bW5OYW1lVG9Qcm9wZXJ0eU5hbWUiLCJjb2x1bW5OYW1lIiwiYWRkZWRQcm9wcyIsInJvdyIsInByb3BlcnR5TmFtZSIsImZpcnN0IiwiZGlmZmVyZW5jZSIsInByb3BlcnR5TmFtZVRvQ29sdW1uTmFtZSIsImFkZGVkQ29scyIsImNvbHMiLCJxdWVyeSIsIiQka25leCIsInJhdyIsImFwcGx5IiwiZm4iLCJmb3JtYXR0ZXIiLCJjbGllbnQiLCJrbmV4UXVlcnkiLCJ0YWJsZSIsInRhYmxlTmFtZSIsInVuaXF1ZVRhZyIsImJpbmRLbmV4IiwiJCRvYmplY3Rpb24iLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImVudW1lcmFibGUiLCJ3cml0YWJsZSIsImJvdW5kTW9kZWxzIiwiQm91bmRNb2RlbENsYXNzIiwiYm91bmRSZWxhdGlvbnMiLCJyZWxhdGlvbkFycmF5IiwiYmluZFRyYW5zYWN0aW9uIiwiaW5wdXQiLCJtb2RlbHMiLCJnZXRJZENvbHVtbkFycmF5IiwiaWRDb2x1bW4iLCJnZXRGdWxsSWRDb2x1bW4iLCJtYXAiLCJjb2wiLCJnZXRJZFByb3BlcnR5QXJyYXkiLCJpZENvbHVtblRvSWRQcm9wZXJ0eSIsImdldElkUHJvcGVydHkiLCJyZWR1Y2UiLCJyZXN1bHQiLCJtYXBwaW5nIiwic2V0TWFwcGluZyIsIiRtb2RlbHMiLCJleHByZXNzaW9uIiwicmVzb2x2ZSIsImZpbmRPcHRpb25zIiwiZG9udENhbGxBZnRlckdldCIsImVhZ2VyIiwicnVuQWZ0ZXIiLCJ0cmF2ZXJzZXIiLCJtb2RlbENsYXNzIiwicGFyZW50IiwianNvbkF0dHJpYnV0ZXMiLCJmb3JPd24iLCJwcm9wTmFtZSIsInR5cGVzIiwiY29tcGFjdCIsImVuc3VyZUFycmF5IiwidHlwZSIsImFueU9mIiwiZmxhdHRlbkRlZXAiLCJvbmVPZiIsImluY2x1ZGVzIiwicHVzaCIsIkhhc09uZVJlbGF0aW9uIiwiSGFzTWFueVJlbGF0aW9uIiwiTWFueVRvTWFueVJlbGF0aW9uIiwiQmVsb25nc1RvT25lUmVsYXRpb24iLCJIYXNPbmVUaHJvdWdoUmVsYXRpb24iLCJ1aWRQcm9wIiwidWlkUmVmUHJvcCIsImRiUmVmUHJvcCIsInByb3BSZWZSZWdleCIsInZpcnR1YWxBdHRyaWJ1dGVzIiwicmVsYXRpb25NYXBwaW5ncyIsIm1vZGVsUGF0aHMiLCJkZWZhdWx0RWFnZXJBbGdvcml0aG0iLCJkZWZhdWx0RWFnZXJPcHRpb25zIiwiaWRQcm9wIiwibWF5YmVKc29uU3RyIiwiSlNPTiIsInBhcnNlIiwiZXJyIiwidG9EYXRhYmFzZUpzb25JbXBsIiwidG9FeHRlcm5hbEpzb25JbXBsIiwib21pdEZyb21Kc29uIiwiYXNzaWduSnNvblZhbHVlIiwidkF0dHIiLCJjYWxsIiwiY29udGFpbnMiLCJ0b0pzb25PYmplY3QiLCJ0b0pzb25BcnJheSIsIkJ1ZmZlciIsImlzQnVmZmVyIiwiY2xvbmVEZWVwIiwic3RyaXBJbnRlcm5hbCIsImNsb25lIiwiY2xvbmVPYmplY3QiLCJjbG9uZUFycmF5Iiwia2V5T2JqIiwiYXJyIiwiaWRQcm9wZXJ0eSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFFQTs7QUFDQTs7QUFDQTs7OztBQUNBOzs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBRUE7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