UNPKG

@martinmilo/verve

Version:

TypeScript domain modeling library with field-level authorization, business rule validation, and context-aware access control

217 lines 8.5 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _Model_proxy, _Model_initializer, _Model_fields, _Model_state, _Model_initialState, _Model_changeLog; Object.defineProperty(exports, "__esModule", { value: true }); exports.Model = void 0; const ModelInitializer_1 = require("../initializers/ModelInitializer"); const utils_1 = require("./utils"); const errors_1 = require("../../errors"); const IdField_1 = require("../../field/fields/IdField"); const constants_1 = require("../../constants"); class Model { constructor() { _Model_proxy.set(this, this); _Model_initializer.set(this, 'make'); _Model_fields.set(this, {}); _Model_state.set(this, {}); _Model_initialState.set(this, {}); _Model_changeLog.set(this, []); } [(_Model_proxy = new WeakMap(), _Model_initializer = new WeakMap(), _Model_fields = new WeakMap(), _Model_state = new WeakMap(), _Model_initialState = new WeakMap(), _Model_changeLog = new WeakMap(), constants_1.MODEL_INITIALIZER)](initializer) { __classPrivateFieldSet(this, _Model_initializer, initializer, "f"); } [constants_1.MODEL_INITIAL_STATE](state) { __classPrivateFieldSet(this, _Model_initialState, (0, utils_1.deepClone)(state), "f"); } [constants_1.MODEL_CHANGE_LOG](change) { if (change.currentValue === undefined) { __classPrivateFieldSet(this, _Model_changeLog, __classPrivateFieldGet(this, _Model_changeLog, "f").filter(log => log.field !== change.field), "f"); return; } __classPrivateFieldGet(this, _Model_changeLog, "f").push(change); } [constants_1.MODEL_PROXY](proxyRef) { if (proxyRef) { __classPrivateFieldSet(this, _Model_proxy, proxyRef, "f"); } return __classPrivateFieldGet(this, _Model_proxy, "f"); } [constants_1.MODEL_STATE]() { return __classPrivateFieldGet(this, _Model_state, "f"); } [constants_1.MODEL_FIELDS]() { return __classPrivateFieldGet(this, _Model_fields, "f"); } isNew() { return __classPrivateFieldGet(this, _Model_initializer, "f") === 'make'; } isExisting() { return __classPrivateFieldGet(this, _Model_initializer, "f") === 'from'; } getChanges() { const changes = {}; const changedFields = []; for (const log of this.getChangeLog()) { if (changedFields.includes(log.field)) { continue; } if (__classPrivateFieldGet(this, _Model_initialState, "f")[log.field] === log.currentValue) { changedFields.push(log.field); continue; } changes[log.field] = log.currentValue; changedFields.push(log.field); } return changes; } getChangeLog() { return [...__classPrivateFieldGet(this, _Model_changeLog, "f")].reverse(); } validate(keys) { const keysArray = keys ? (Array.isArray(keys) ? keys : [keys]) : undefined; const errors = errors_1.VerveErrorList.new(); for (const field of Object.values(this[constants_1.MODEL_FIELDS]())) { if (keysArray && !keysArray.includes(field.metadata.name)) { continue; } const fieldErrors = field.validate(); errors.merge(fieldErrors); } return errors; } generate(keys) { const keysArray = keys ? (Array.isArray(keys) ? keys : [keys]) : undefined; const fields = this[constants_1.MODEL_FIELDS](); for (const field of Object.values(fields)) { if (keysArray && !keysArray.includes(field.metadata.name)) { continue; } // If the field has a generator and is not initialized, generate the value if (field.options.generator && field.unsafeGet() === undefined) { field.generate(); } } return this; } unsafeGet(key) { const fields = this[constants_1.MODEL_FIELDS](); const field = fields[key]; return field.unsafeGet(); } set(data) { const fields = this[constants_1.MODEL_FIELDS](); for (const [key, value] of Object.entries(data)) { // We do not allow setting undefined values if (value === undefined) { continue; } fields[key].set(value); } return this; } unset(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const key of keysArray) { fields[key].unset(); } return this; } only(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const [fieldName, field] of Object.entries(fields)) { if (keysArray.includes(fieldName)) { continue; } if (field instanceof IdField_1.IdField) { continue; } field.unset(); } return this; } except(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const [fieldName, field] of Object.entries(fields)) { if (!keysArray.includes(fieldName)) { continue; } if (field instanceof IdField_1.IdField) { throw new errors_1.VerveError(errors_1.ErrorCode.ID_FIELD_CANNOT_BE_EXCLUDED); } field.unset(); } return this; } isValid() { const keys = Object.keys(this); return this.hasValid(keys); } hasValid(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const field of Object.values(fields)) { if (!keysArray.includes(field.metadata.name)) { continue; } if (!field.isValid()) { return false; } } return true; } isEmpty() { const keys = Object.keys(this); return this.hasEmpty(keys); } hasEmpty(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const field of Object.values(fields)) { if (!keysArray.includes(field.metadata.name)) { continue; } if (!field.isEmpty()) { return false; } } return true; } isPresent() { const keys = Object.keys(this); return this.hasPresent(keys); } hasPresent(keys) { const keysArray = Array.isArray(keys) ? keys : [keys]; const fields = this[constants_1.MODEL_FIELDS](); for (const field of Object.values(fields)) { if (!keysArray.includes(field.metadata.name)) { continue; } if (!field.isPresent()) { return false; } } return true; } static Untyped() { return (0, ModelInitializer_1.createModelClass)(); } static Typed() { return (0, ModelInitializer_1.createModelClass)(); } } exports.Model = Model; //# sourceMappingURL=Model.js.map