UNPKG

cheetah-framework

Version:

Cheetah Framework JS used in all our applications

140 lines (111 loc) 3.76 kB
class Model { constructor (data = null) { this.uid = getUid() Object.defineProperty(this, '_attributes', { value: {}, writable: true, enumerable: true, configurable: true }) this._postMutators = [...this.constructor.defaultPostMutators, ...this.constructor.postMutators] /** * LARAVEL ACCESSORS & MUTATORS * To use it, define a function in the Model * following the Laravel naming convention * https://laravel.com/docs/master/eloquent-mutators * * If you need to have access to properties in your mutator, * you can make it a post mutator by adding it to the postMutators array */ this.defineMutators() const values = _.defaultsDeep(data ? _.cloneDeep(data) : data, this.defaultValue) _.extend( this, _.omit( values, ['_attributes', 'uid', '_postMutators', ...this._postMutators] ) ) this.defineMutators(true) _.extend(this, _.pick(values, this._postMutators)) } /** * Do not override in model, use postMutators getter instead * This exists to allow other classes to add post mutators (ex: StateHandler) */ static defaultPostMutators = [] static _cachedMutators = null static _cachedPostMutators = null static get postMutators () { return [] } getMutatorMethods (post) { const cachedMutatorsVar = post ? '_cachedMutators' : '_cachedPostMutators' if (this.constructor[cachedMutatorsVar]) { return this.constructor[cachedMutatorsVar] } const properties = Object.getOwnPropertyNames(Object.getPrototypeOf(this)) .filter(prop => prop !== 'constructor') /** * Return an object * the key's of the object is set to the attributes name * and it contains objects with the type as a key and the method as a value * eg: { name:{ 'set': 'setNameAttribute', 'get': 'getNameAttribute' } } */ this.constructor[cachedMutatorsVar] = _.reduce(properties, (methods, value) => { const information = /^(set|get)(.*)Attribute$/.exec(value) if (information) { const attribute = _.snakeCase(information[2]) const isPostMutator = this._postMutators.includes(attribute) if (!post && isPostMutator) { return methods } else if (post && !isPostMutator) { return methods } if (!methods[attribute]) { methods[attribute] = {} } methods[attribute][information[1]] = information[0] } return methods }, {}) return this.constructor[cachedMutatorsVar] } defineMutators (post = false) { const mutators = this.getMutatorMethods(post) _.each(mutators, (mutator, attributeName) => { // Setter and getter to retrieve Accessors and/or set Mutators Object.defineProperty(this, attributeName, { enumerable: true, get: mutator['get'] ? () => this[mutator['get']](this._attributes[attributeName]) : () => this._attributes[attributeName], set: mutator['set'] ? (newValue, oldValue) => { this[mutator['set']](newValue, oldValue) } : newValue => { this._attributes[attributeName] = newValue } }) }) } serializeData () { return JSON.parse(JSON.stringify(this)) } toJSON () { return _.omit(this, ['_attributes', '_postMutators', 'uid', 'notification']) } get defaultValue () { return {} } } function TranslatedFieldValue (defaultValue) { const translated = {} _.each(Cheetah.contentLanguages, langKey => { translated[langKey] = defaultValue || '' }) return translated } let uidCount = 0 function getUid () { return ++uidCount } export default Model export { Model, TranslatedFieldValue }