@decaf-ts/db-decorators
Version:
Agnostic database decorators and repository
139 lines • 7.19 kB
JavaScript
;
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