UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

139 lines 7.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const decorator_validation_1 = require("@decaf-ts/decorator-validation"); const validation_1 = require("./../model/validation.cjs"); const decoration_1 = require("@decaf-ts/decoration"); const constants_1 = require("./../model/constants.cjs"); const constants_2 = require("./../operations/constants.cjs"); const errors_1 = require("./../repository/errors.cjs"); decorator_validation_1.Model.prototype.isTransient = function () { return decoration_1.Metadata.isTransient(this); }; /** * @description Validates the model and checks for errors * @summary Validates the current model state and optionally compares with a previous version * @template M - Type extending Model * @param {M|any} [previousVersion] - Optional previous version of the model for comparison * @param {...any[]} exclusions - Properties to exclude from validation * @return {ModelErrorDefinition|undefined} Error definition if validation fails, undefined otherwise * @function hasErrors * @memberOf module:db-decorators */ decorator_validation_1.Model.prototype.hasErrors = function (previousVersion, ...exclusions) { if (previousVersion && !(previousVersion instanceof decorator_validation_1.Model)) { exclusions.unshift(previousVersion); previousVersion = undefined; } const async = this.isAsync(); const errs = (0, decorator_validation_1.validate)(this, async, ...exclusions); if (async) { return Promise.resolve(errs).then((resolvedErrs) => { if (resolvedErrs || !previousVersion) { return resolvedErrs; } return (0, validation_1.validateCompare)(previousVersion, this, async, ...exclusions); }); } if (errs || !previousVersion) return errs; // @ts-expect-error Overriding Model prototype method with dynamic conditional return type. return (0, validation_1.validateCompare)(previousVersion, this, async, ...exclusions); }; decorator_validation_1.Model.prototype.segregate = function segregate() { return decorator_validation_1.Model.segregate(this); }; decorator_validation_1.Model.segregate = function segregate(model) { if (!decoration_1.Metadata.isTransient(model)) return { model: model }; const decoratedProperties = decoration_1.Metadata.validatableProperties(model.constructor); const transientProps = decoration_1.Metadata.get(model.constructor, constants_1.DBKeys.TRANSIENT); const result = { model: {}, transient: {}, }; for (const key of decoratedProperties) { const isTransient = Object.keys(transientProps).includes(key); if (isTransient) { result.transient = result.transient || {}; try { result.transient[key] = model[key]; } catch (e) { throw new errors_1.SerializationError(`Failed to serialize transient property ${key}: ${e}`); } } else { result.model = result.model || {}; result.model[key] = model[key]; } } result.model = decorator_validation_1.Model.build(result.model, model.constructor.name); return result; }; decorator_validation_1.Model.pk = function pk(model, keyValue = false) { if (!model) throw new Error("No model was provided"); const constr = model instanceof decorator_validation_1.Model ? model.constructor : model; const idProp = decoration_1.Metadata.get(constr, constants_1.DBKeys.ID); if (!idProp) { throw new Error(`No Id property defined for model ${constr?.name || "Unknown Model"}`); } const key = Object.keys(idProp)[0]; if (!keyValue) return key; if (model instanceof decorator_validation_1.Model) return model[key]; throw new Error("Cannot get the value of the pk from the constructor"); }.bind(decorator_validation_1.Model); decorator_validation_1.Model.pkProps = function pkProps(model) { return decoration_1.Metadata.get(model, decoration_1.Metadata.key(constants_1.DBKeys.ID, decorator_validation_1.Model.pk(model))); }.bind(decorator_validation_1.Model); decorator_validation_1.Model.isTransient = function isTransient(model) { return !!decoration_1.Metadata.get(typeof model !== "function" ? model.constructor : model, constants_1.DBKeys.TRANSIENT); }.bind(decorator_validation_1.Model); decorator_validation_1.Model.composed = function composed(model, prop) { const constr = model instanceof decorator_validation_1.Model ? model.constructor : model; if (prop) return decoration_1.Metadata.get(constr, decoration_1.Metadata.key(constants_1.DBKeys.COMPOSED, prop)); return !!decoration_1.Metadata.get(constr, constants_1.DBKeys.COMPOSED); }.bind(decorator_validation_1.Model); /** * @description Merges two model instances into a new instance. * @summary Creates a new model instance by combining properties from an old model and a new model. * Properties from the new model override properties from the old model if they are defined. * @template {M} - Type extending Model * @param {M} oldModel - The original model instance * @param {M} model - The new model instance with updated properties * @return {M} A new model instance with merged properties */ decorator_validation_1.Model.merge = function merge(oldModel, newModel, constructor) { constructor = constructor || oldModel.constructor; const extract = (model) => Object.entries(model).reduce((accum, [key, val]) => { if (typeof val !== "undefined") accum[key] = val; return accum; }, {}); return new constructor(Object.assign({}, extract(oldModel), extract(newModel))); }.bind(decorator_validation_1.Model); decoration_1.Metadata.saveOperation = function saveOperation(model, propertyKey, operation, metadata) { if (!propertyKey) return; decoration_1.Metadata.set(model, decoration_1.Metadata.key(constants_2.ModelOperations.OPERATIONS, propertyKey, operation), metadata); }.bind(decoration_1.Metadata); decoration_1.Metadata.readOperation = function readOperation(model, propertyKey, operation) { if (!propertyKey || !operation) return; return decoration_1.Metadata.get(model, decoration_1.Metadata.key(constants_2.ModelOperations.OPERATIONS, propertyKey, operation)); }.bind(decoration_1.Metadata); decoration_1.Metadata.isTransient = function isTransient(model) { return !!decoration_1.Metadata.get(typeof model !== "function" ? model.constructor : model, constants_1.DBKeys.TRANSIENT); }.bind(decoration_1.Metadata); decorator_validation_1.Model.generated = function generated(model, prop) { return !!decoration_1.Metadata.get(typeof model !== "function" ? model.constructor : model, decoration_1.Metadata.key(constants_1.DBKeys.GENERATED, prop)); }.bind(decorator_validation_1.Model); decorator_validation_1.Model.shouldGenerate = function shouldGenerate(model, prop, ctx) { if (ctx.get("allowGenerationOverride") && typeof model[prop] !== "undefined") return false; return true; }.bind(decorator_validation_1.Model); //# sourceMappingURL=overrides.js.map