objection
Version:
An SQL-friendly ORM for Node.js
1,643 lines (1,202 loc) • 127 kB
JavaScript
'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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