UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

126 lines (125 loc) 5.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hashOnCreateUpdate = hashOnCreateUpdate; exports.hash = hash; exports.composedFromCreateUpdate = composedFromCreateUpdate; exports.composedFromKeys = composedFromKeys; exports.composed = composed; exports.versionCreateUpdate = versionCreateUpdate; exports.version = version; const constants_1 = require("./constants.cjs"); const reflection_1 = require("@decaf-ts/reflection"); const decorator_validation_1 = require("@decaf-ts/decorator-validation"); const decorators_1 = require("../operations/decorators.cjs"); const errors_1 = require("../repository/errors.cjs"); const Repository_1 = require("../repository/Repository.cjs"); const operations_1 = require("../operations/index.cjs"); /** * * @param {str} str * @memberOf db-decorators.model */ function hashOnCreateUpdate(data, key, model, oldModel) { if (!model[key]) return; const hash = decorator_validation_1.Hashing.hash(model[key]); if (oldModel && model[key] === hash) return; model[key] = hash; } function hash() { return (0, reflection_1.apply)((0, decorators_1.onCreateUpdate)(hashOnCreateUpdate), (0, decorator_validation_1.propMetadata)(Repository_1.Repository.key(constants_1.DBKeys.HASH), {})); } function composedFromCreateUpdate(context, data, key, model) { try { const { args, type, prefix, suffix, separator } = data; const composed = args.map((arg) => { if (!(arg in model)) throw new errors_1.InternalError((0, decorator_validation_1.sf)("Property {0} not found to compose from", arg)); if (type === "keys") return arg; if (typeof model[arg] === "undefined") throw new errors_1.InternalError((0, decorator_validation_1.sf)("Property {0} does not contain a value to compose from", arg)); return model[arg].toString(); }); if (prefix) composed.unshift(prefix); if (suffix) composed.push(suffix); model[key] = composed.join(separator); } catch (e) { throw new errors_1.InternalError(`Failed to compose value: ${e}`); } } function composedFrom(args, hashResult = false, separator = constants_1.DefaultSeparator, type = "values", prefix = "", suffix = "") { const data = { args: args, hashResult: hashResult, separator: separator, type: type, prefix: prefix, suffix: suffix, }; const decorators = [ (0, decorators_1.onCreateUpdate)(composedFromCreateUpdate, data), (0, decorator_validation_1.propMetadata)(Repository_1.Repository.key(constants_1.DBKeys.COMPOSED), data), ]; if (hashResult) decorators.push(hash()); return (0, reflection_1.apply)(...decorators); } function composedFromKeys(args, separator = constants_1.DefaultSeparator, hash = false, prefix = "", suffix = "") { return composedFrom(args, hash, separator, "keys", prefix, suffix); } function composed(args, separator = constants_1.DefaultSeparator, hash = false, prefix = "", suffix = "") { return composedFrom(args, hash, separator, "values", prefix, suffix); } /** * Creates a decorator function that updates the version of a model during create or update operations. * * @param {CrudOperations} operation - The type of operation being performed (CREATE or UPDATE). * @returns {function} A function that updates the version of the model based on the operation type. * * @template M - Type extending Model * @template V - Type extending IRepository<M> * * @this {V} - The repository instance * @param {Context<M>} context - The context of the operation * @param {unknown} data - Additional data for the operation (not used in this function) * @param {string} key - The key of the version property in the model * @param {M} model - The model being updated * @throws {InternalError} If an invalid operation is provided or if version update fails */ function versionCreateUpdate(operation) { return function versionCreateUpdate(context, data, key, model) { try { switch (operation) { case operations_1.OperationKeys.CREATE: model[key] = 1; break; case operations_1.OperationKeys.UPDATE: model[key]++; break; default: throw new errors_1.InternalError(`Invalid operation: ${operation}`); } } catch (e) { throw new errors_1.InternalError(`Failed to update version: ${e}`); } }; } /** * @description Creates a decorator for versioning a property in a model. * @summary This decorator applies multiple sub-decorators to handle version management during create and update operations. * * @returns {Function} A composite decorator that: * - Sets the type of the property to Number * - Applies a version update on create operations * - Applies a version update on update operations * - Adds metadata indicating this property is used for versioning */ function version() { return (0, reflection_1.apply)((0, decorator_validation_1.type)(Number.name), (0, decorators_1.onCreate)(versionCreateUpdate(operations_1.OperationKeys.CREATE)), (0, decorators_1.onUpdate)(versionCreateUpdate(operations_1.OperationKeys.UPDATE)), (0, decorator_validation_1.propMetadata)(Repository_1.Repository.key(constants_1.DBKeys.VERSION), true)); }