121 lines
3.5 KiB
JavaScript
121 lines
3.5 KiB
JavaScript
const Model = require('flitter-orm/src/model/Model');
|
|
const uuid = require('uuid/v4');
|
|
|
|
class VersionedModel extends Model {
|
|
static get schema() {
|
|
return {
|
|
version_archive: [Object],
|
|
version_num: { type: Number, default: 1 },
|
|
version_create_date: { type: Date, default: () => new Date },
|
|
version_user_id: String,
|
|
}
|
|
}
|
|
|
|
__is_version_instantation = false
|
|
__version_base = undefined
|
|
__version_data = undefined
|
|
|
|
is_a_version() {
|
|
return this.__is_version_instantation
|
|
}
|
|
|
|
version_base() {
|
|
return this.__version_base
|
|
}
|
|
|
|
raw_version_data() {
|
|
return this.__version_data
|
|
}
|
|
|
|
__initialize_version(base, data = {}) {
|
|
this.__is_version_instantation = true
|
|
this.__version_base = base
|
|
this.__version_data = data
|
|
}
|
|
|
|
async version_save(message = undefined, user_id = undefined) {
|
|
await this.new_version(message, user_id)
|
|
return this.save()
|
|
}
|
|
|
|
async new_version(message = undefined, user_id = undefined) {
|
|
if ( !this.version_num ) this.version_num = 1
|
|
if ( !this.version_archive ) this.version_archive = []
|
|
|
|
this.version_num += 1
|
|
this.version_create_date = new Date()
|
|
this.version_user_id = user_id
|
|
|
|
const version_data = await this.cast_to_version_data()
|
|
version_data.version_UUID = uuid()
|
|
version_data.version_message = message
|
|
|
|
this.version_archive.push(version_data)
|
|
}
|
|
|
|
async cast_to_version_data() {
|
|
const schema = this.constructor.__schema
|
|
const shallow_object = {}
|
|
for ( const prop in schema.schema ) {
|
|
if ( prop in this ) {
|
|
shallow_object[prop] = this[prop]
|
|
}
|
|
}
|
|
|
|
const data = await this.__scope_limit_save(schema.cast_to_schema(shallow_object))
|
|
delete data.version_archive
|
|
return data
|
|
}
|
|
|
|
async get_version_data(version_num = undefined) {
|
|
if ( typeof version_num === 'undefined' ) {
|
|
return await this.cast_to_version_data()
|
|
} else {
|
|
return this.version_archive.find(data => Number(data.version_num) === Number(version_num))
|
|
}
|
|
}
|
|
|
|
has_version(version_num = undefined) {
|
|
return !!this.version_archive.find(data => {
|
|
return Number(data.version_num) === Number(version_num)
|
|
})
|
|
}
|
|
|
|
toJSON() {
|
|
const data = {...this}
|
|
delete data.__version_data
|
|
delete data.__version_base
|
|
delete data.__is_version_instantation
|
|
delete data.version_archive
|
|
|
|
if ( this.is_a_version() ) {
|
|
data.version_message = this.__version_data.version_message
|
|
data.version_user_id = this.__version_data.version_user_id
|
|
}
|
|
|
|
return data
|
|
}
|
|
|
|
async as_version(version_num = undefined) {
|
|
const data = await this.get_version_data(version_num)
|
|
const inst = new this.constructor(data)
|
|
inst.__initialize_version(this, data)
|
|
return inst
|
|
}
|
|
|
|
async revert_to_version(version_num, user_id = undefined) {
|
|
const inst = await this.as_version(version_num)
|
|
inst.version_archive = this.version_archive
|
|
inst._id = this._id
|
|
inst.__is_version_instantation = false
|
|
inst.__version_base = undefined
|
|
inst.__version_data = undefined
|
|
inst.version_num = this.version_num
|
|
await inst.new_version(`Revert to version ${version_num}`, user_id)
|
|
await inst.save()
|
|
return inst
|
|
}
|
|
}
|
|
|
|
module.exports = exports = VersionedModel
|