@kingdom-sdk/core
Version:
Core module to design DDD applications in TypeScript
152 lines (122 loc) • 3.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Entity = void 0;
var _objectHash = _interopRequireDefault(require("object-hash"));
var _EntityDiscardedError = require("../exceptions/EntityDiscardedError");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Represent the base element in the domain model, for entities and its aggregates.
*/
class Entity {
/**
* Create an Entity.
*
* @param {Id_T} id - Unique identifier.
* @param {number} version - Value used to handle optmistic concurrency.
* @param {boolean} is_discarded - Flag used by the no-deletion convention.
* @param {Date} registered_at - Timestamp when the entity had created.
* @param {Date} updated_at - Timestamp when the last modification had done.
*/
constructor(id, version, isDiscarded, registeredAt, updatedAt) {
this._id = id;
this._version = version;
this._isDiscarded = isDiscarded;
this._registeredAt = registeredAt;
this._updatedAt = updatedAt;
}
/**
* Call this method before every update action.
*/
check_not_discarded() {
if (this._isDiscarded) {
const classname = this.constructor.name;
throw new _EntityDiscardedError.EntityDiscardedError(`${classname} object is discarded`);
}
}
/**
* Use this method in the toString() implementation.
*/
baseRepr(identifier, props) {
const pairs = Object.entries(props || {}).map(item => `${item[0]}="${item[1]}"`).join(', ');
const prefix = this._isDiscarded ? '**DISCARDED** ' : '';
const classname = this.constructor.name;
const extra = props ? ` (${pairs})` : '';
return `${prefix}<${classname} '${identifier}'${extra}>`;
}
/**
* Default hashing operation.
*
* You shuold override it on every subclass.
*/
toHash() {
return (0, _objectHash.default)({ ...this,
_version: null,
_isDiscarded: null,
_registeredAt: null,
_updatedAt: null
});
}
/**
* Default equality operation.
*
* You shuold override it on every subclass.
*/
equals(other) {
if (!(other instanceof Entity)) {
return false;
}
return this.toHash() === other.toHash();
}
get id() {
return this._id;
}
/**
* Required by ORM to auto generate the ID.
*/
set id(value) {
this._id = value;
}
get version() {
return this._version;
}
get isDiscarded() {
return this._isDiscarded;
}
get registeredAt() {
return this._registeredAt;
}
get updatedAt() {
return this._updatedAt;
}
get props() {
const objectProps = {};
Object.keys(this).forEach(key => {
if (key.charAt(0) === '_') {
/* @ts-ignore */
objectProps[key.substring(1)] = this[key];
}
});
return Object.freeze(objectProps);
}
/**
* Remember to call this method before commiting a change.
*/
update() {
this.check_not_discarded();
this._update();
}
_update() {
this._version += 1;
this._updatedAt = new Date();
}
/**
* By convention, isn't necessary delete an object, only mark it as discarded.
*/
discard() {
this._isDiscarded = true;
this._update();
}
}
exports.Entity = Entity;