UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

227 lines (226 loc) 8.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readonly = readonly; exports.timestampHandler = timestampHandler; exports.timestamp = timestamp; exports.serializeOnCreateUpdate = serializeOnCreateUpdate; exports.serializeAfterAll = serializeAfterAll; exports.serialize = serialize; const decorator_validation_1 = require("@decaf-ts/decorator-validation"); const constants_1 = require("../model/constants.cjs"); const constants_2 = require("./constants.cjs"); const constants_3 = require("../operations/constants.cjs"); const decorators_1 = require("../operations/decorators.cjs"); const errors_1 = require("../repository/errors.cjs"); const reflection_1 = require("@decaf-ts/reflection"); const repository_1 = require("../repository/index.cjs"); /** * Marks the property as readonly. * * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES.READONLY.INVALID} * * @decorator readonly * * @category Decorators */ function readonly(message = constants_2.DEFAULT_ERROR_MESSAGES.READONLY.INVALID) { return (0, decorator_validation_1.propMetadata)(decorator_validation_1.Validation.updateKey(constants_1.DBKeys.READONLY), { message: message, }); } async function timestampHandler(context, data, key, model) { model[key] = context.timestamp; } /** * Marks the property as timestamp. * Makes it {@link required} * Makes it a {@link date} * * Date Format: * * <pre> * Using similar formatting as Moment.js, Class DateTimeFormatter (Java), and Class SimpleDateFormat (Java), * I implemented a comprehensive solution formatDate(date, patternStr) where the code is easy to read and modify. * You can display date, time, AM/PM, etc. * * Date and Time Patterns * yy = 2-digit year; yyyy = full year * M = digit month; MM = 2-digit month; MMM = short month name; MMMM = full month name * EEEE = full weekday name; EEE = short weekday name * d = digit day; dd = 2-digit day * h = hours am/pm; hh = 2-digit hours am/pm; H = hours; HH = 2-digit hours * m = minutes; mm = 2-digit minutes; aaa = AM/PM * s = seconds; ss = 2-digit seconds * S = miliseconds * </pre> * * @param {string[]} operation The {@link DBOperations} to act on. Defaults to {@link DBOperations.CREATE_UPDATE} * @param {string} [format] The TimeStamp format. defaults to {@link DEFAULT_TIMESTAMP_FORMAT} * @param {{new: UpdateValidator}} [validator] defaults to {@link TimestampValidator} * * @decorator timestamp * * @category Decorators */ function timestamp(operation = constants_3.DBOperations.CREATE_UPDATE, format = constants_1.DEFAULT_TIMESTAMP_FORMAT) { const decorators = [ (0, decorator_validation_1.date)(format, constants_2.DEFAULT_ERROR_MESSAGES.TIMESTAMP.DATE), (0, decorator_validation_1.required)(constants_2.DEFAULT_ERROR_MESSAGES.TIMESTAMP.REQUIRED), (0, decorators_1.on)(operation, timestampHandler), ]; if (operation.indexOf(constants_3.OperationKeys.UPDATE) !== -1) decorators.push((0, decorator_validation_1.propMetadata)(decorator_validation_1.Validation.updateKey(constants_1.DBKeys.TIMESTAMP), { message: constants_2.DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID, })); return (0, reflection_1.apply)(...decorators); } async function serializeOnCreateUpdate(data, key, model, oldModel) { if (!model[key]) return; try { model[key] = JSON.stringify(model[key]); } catch (e) { throw new errors_1.SerializationError((0, decorator_validation_1.sf)("Failed to serialize {0} property on {1} model: {2}", key, model.constructor.name, e.message)); } } async function serializeAfterAll(data, key, model) { if (!model[key]) return; if (typeof model[key] !== "string") return; try { model[key] = JSON.parse(model[key]); } catch (e) { throw new errors_1.SerializationError((0, decorator_validation_1.sf)("Failed to deserialize {0} property on {1} model: {2}", key, model.constructor.name, e.message)); } } /** * @summary Serialize Decorator * @description properties decorated will the serialized before stored in the db * * @function serialize * * @memberOf module:wallet-db.Decorators */ function serialize() { return (0, reflection_1.apply)((0, decorators_1.onCreateUpdate)(serializeOnCreateUpdate), (0, decorators_1.after)(constants_3.DBOperations.ALL, serializeAfterAll), (0, decorator_validation_1.type)([String.name, Object.name]), (0, reflection_1.metadata)(repository_1.Repository.key(constants_1.DBKeys.SERIALIZE), {})); } // // /** // * @summary One To One relation Decorators // * // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence} // * @param {CascadeMetadata} [cascadeOptions] // * @param {boolean} _populate If true, replaces the specified key in the document with the corresponding record from the database // * // * @function onToOne // * // * @memberOf module:wallet-db.Decorators // * // * @see oneToMany // * @see manyToOne // */ // export function oneToOne( // clazz: Constructor<any>, // cascadeOptions: CascadeMetadata = DefaultCascade, // _populate: boolean = true, // ) { // Model.register(clazz); // return (target: any, propertyKey: string) => { // type([clazz.name, String.name])(target, propertyKey); // onCreate(oneToOneOnCreate)(target, propertyKey); // onUpdate(oneToOneOnUpdate, cascadeOptions as any)(target, propertyKey); // onDelete(oneToOneOnDelete, cascadeOptions)(target, propertyKey); // // afterCreate(populate, _populate)(target, propertyKey); // afterUpdate(populate, _populate)(target, propertyKey); // afterRead(populate, _populate)(target, propertyKey); // afterDelete(populate, _populate)(target, propertyKey); // // Reflect.defineMetadata( // getDBKey(WalletDbKeys.ONE_TO_ONE), // { // constructor: clazz.name, // cascade: cascadeOptions, // populate: _populate, // }, // target, // propertyKey, // ); // }; // } // // /** // * @summary One To Many relation Decorators // * // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence} // * @param {CascadeMetadata} [cascadeOptions] // * // * @function onToMany // * // * @memberOf module:wallet-db.Decorators // * // * @see oneToOne // * @see manyToOne // */ // export function oneToMany( // clazz: Constructor<any>, // cascadeOptions: CascadeMetadata = DefaultCascade, // _populate: boolean = true, // ) { // Model.register(clazz); // return (target: any, propertyKey: string) => { // list([clazz, String])(target, propertyKey); // onCreate(oneToManyOnCreate)(target, propertyKey); // onUpdate(oneToManyOnUpdate, cascadeOptions)(target, propertyKey); // onDelete(oneToManyOnDelete, cascadeOptions)(target, propertyKey); // // afterCreate(populate, _populate)(target, propertyKey); // afterUpdate(populate, _populate)(target, propertyKey); // afterRead(populate, _populate)(target, propertyKey); // afterDelete(populate, _populate)(target, propertyKey); // // Reflect.defineMetadata( // getDBKey(WalletDbKeys.ONE_TO_MANY), // { // constructor: clazz.name, // cascade: cascadeOptions, // }, // target, // propertyKey, // ); // }; // } // // /** // * @summary Many To One relation Decorators // * // * @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence} // * @param {CascadeMetadata} [cascadeOptions] // * // * @function manyToOne // * // * @memberOf module:wallet-db.Decorators // * // * @see oneToMany // * @see oneToOne // */ // export function manyToOne( // clazz: Constructor<any>, // cascadeOptions: CascadeMetadata = DefaultCascade, // ) { // Model.register(clazz); // return (target: any, propertyKey: string) => { // Reflect.defineMetadata( // getDBKey(WalletDbKeys.MANY_TO_ONE), // { // constructor: clazz.name, // cascade: cascadeOptions, // }, // target, // propertyKey, // ); // }; // }