UNPKG

@kingdom-sdk/core

Version:

Core module to design DDD applications in TypeScript

152 lines (122 loc) 3.29 kB
"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;