UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

110 lines 14.9 kB
import "./validation"; import { date, Decoration, propMetadata, required, type, Validation, } from "@decaf-ts/decorator-validation"; import { DBKeys, DEFAULT_TIMESTAMP_FORMAT } from "../model/constants"; import { DEFAULT_ERROR_MESSAGES } from "./constants"; import { DBOperations, OperationKeys } from "../operations/constants"; import { after, on, onCreateUpdate } from "../operations/decorators"; import { SerializationError } from "../repository/errors"; import { apply, metadata } from "@decaf-ts/reflection"; import { Repository } from "../repository"; /** * Marks the property as readonly. * * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES.READONLY.INVALID} * * @decorator readonly * * @category Decorators */ export function readonly(message = DEFAULT_ERROR_MESSAGES.READONLY.INVALID) { const key = Validation.updateKey(DBKeys.READONLY); return Decoration.for(key) .define(propMetadata(key, { message: message, })) .apply(); } export 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 */ export function timestamp(operation = DBOperations.CREATE_UPDATE, format = DEFAULT_TIMESTAMP_FORMAT) { const key = Validation.updateKey(DBKeys.TIMESTAMP); const decorators = [ date(format, DEFAULT_ERROR_MESSAGES.TIMESTAMP.DATE), required(DEFAULT_ERROR_MESSAGES.TIMESTAMP.REQUIRED), on(operation, timestampHandler), ]; if (operation.indexOf(OperationKeys.UPDATE) !== -1) decorators.push(propMetadata(Validation.updateKey(DBKeys.TIMESTAMP), { message: DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID, })); return Decoration.for(key) .define(...decorators) .apply(); } export async function serializeOnCreateUpdate(context, data, key, model) { if (!model[key]) return; try { model[key] = JSON.stringify(model[key]); // eslint-disable-next-line @typescript-eslint/no-unused-vars } catch (e) { throw new SerializationError(`Failed to serialize ${key.toString()} property of model ${model.constructor.name}: e`); } } export async function serializeAfterAll(context, data, key, model) { if (!model[key]) return; if (typeof model[key] !== "string") return; try { model[key] = JSON.parse(model[key]); } catch (e) { throw new SerializationError(`Failed to deserialize ${key.toString()} property of model ${model.constructor.name}: ${e}`); } } /** * @summary Serialize Decorator * @description properties decorated will the serialized before stored in the db * * @function serialize * * @memberOf module:wallet-db.Decorators */ export function serialize() { return apply(onCreateUpdate(serializeOnCreateUpdate), after(DBOperations.ALL, serializeAfterAll), type([String.name, Object.name]), metadata(Repository.key(DBKeys.SERIALIZE), {})); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjb3JhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy92YWxpZGF0aW9uL2RlY29yYXRvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxjQUFjLENBQUM7QUFDdEIsT0FBTyxFQUNMLElBQUksRUFDSixVQUFVLEVBRVYsWUFBWSxFQUNaLFFBQVEsRUFDUixJQUFJLEVBQ0osVUFBVSxHQUNYLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUFFLE1BQU0sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXJFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFELE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUkzQzs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQ3RCLFVBQWtCLHNCQUFzQixDQUFDLFFBQVEsQ0FBQyxPQUFPO0lBRXpELE1BQU0sR0FBRyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xELE9BQU8sVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7U0FDdkIsTUFBTSxDQUNMLFlBQVksQ0FBQyxHQUFHLEVBQUU7UUFDaEIsT0FBTyxFQUFFLE9BQU87S0FDakIsQ0FBQyxDQUNIO1NBQ0EsS0FBSyxFQUFFLENBQUM7QUFDYixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUss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Q2hDLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDL0MsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXCIuL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIGRhdGUsXG4gIERlY29yYXRpb24sXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG4gIHJlcXVpcmVkLFxuICB0eXBlLFxuICBWYWxpZGF0aW9uLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEQktleXMsIERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVCB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IERCT3BlcmF0aW9ucywgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYWZ0ZXIsIG9uLCBvbkNyZWF0ZVVwZGF0ZSB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFNlcmlhbGl6YXRpb25FcnJvciB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2Vycm9yc1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS90eXBlc1wiO1xuXG4vKipcbiAqIE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyByZWFkb25seS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5SRUFET05MWS5JTlZBTElEfVxuICpcbiAqIEBkZWNvcmF0b3IgcmVhZG9ubHlcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZG9ubHkoXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVBRE9OTFkuSU5WQUxJRFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5SRUFET05MWSk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGltZXN0YW1wSGFuZGxlcjxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gY29udGV4dC50aW1lc3RhbXA7XG59XG5cbi8qKlxuICogTWFya3MgdGhlIHByb3BlcnR5IGFzIHRpbWVzdGFtcC5cbiAqIE1ha2VzIGl0IHtAbGluayByZXF1aXJlZH1cbiAqIE1ha2VzIGl0IGEge0BsaW5rIGRhdGV9XG4gKlxuICogRGF0ZSBGb3JtYXQ6XG4gKlxuICogPHByZT5cbiAqICAgICAgVXNpbmcgc2ltaWxhciBmb3JtYXR0aW5nIGFzIE1vbWVudC5qcywgQ2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIgKEphdmEpLCBhbmQgQ2xhc3MgU2ltcGxlRGF0ZUZvcm1hdCAoSmF2YSksXG4gKiAgICAgIEkgaW1wbGVtZW50ZWQgYSBjb21wcmVoZW5zaXZlIHNvbHV0aW9uIGZvcm1hdERhdGUoZGF0ZSwgcGF0dGVyblN0cikgd2hlcmUgdGhlIGNvZGUgaXMgZWFzeSB0byByZWFkIGFuZCBtb2RpZnkuXG4gKiAgICAgIFlvdSBjYW4gZGlzcGxheSBkYXRlLCB0aW1lLCBBTS9QTSwgZXRjLlxuICpcbiAqICAgICAgRGF0ZSBhbmQgVGltZSBQYXR0ZXJuc1xuICogICAgICB5eSA9IDItZGlnaXQgeWVhcjsgeXl5eSA9IGZ1bGwgeWVhclxuICogICAgICBNID0gZGlnaXQgbW9udGg7IE1NID0gMi1kaWdpdCBtb250aDsgTU1NID0gc2hvcnQgbW9udGggbmFtZTsgTU1NTSA9IGZ1bGwgbW9udGggbmFtZVxuICogICAgICBFRUVFID0gZnVsbCB3ZWVrZGF5IG5hbWU7IEVFRSA9IHNob3J0IHdlZWtkYXkgbmFtZVxuICogICAgICBkID0gZGlnaXQgZGF5OyBkZCA9IDItZGlnaXQgZGF5XG4gKiAgICAgIGggPSBob3VycyBhbS9wbTsgaGggPSAyLWRpZ2l0IGhvdXJzIGFtL3BtOyBIID0gaG91cnM7IEhIID0gMi1kaWdpdCBob3Vyc1xuICogICAgICBtID0gbWludXRlczsgbW0gPSAyLWRpZ2l0IG1pbnV0ZXM7IGFhYSA9IEFNL1BNXG4gKiAgICAgIHMgPSBzZWNvbmRzOyBzcyA9IDItZGlnaXQgc2Vjb25kc1xuICogICAgICBTID0gbWlsaXNlY29uZHNcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nW119IG9wZXJhdGlvbiBUaGUge0BsaW5rIERCT3BlcmF0aW9uc30gdG8gYWN0IG9uLiBEZWZhdWx0cyB0byB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURV9VUERBVEV9XG4gKiBAcGFyYW0ge3N0cmluZ30gW2Zvcm1hdF0gVGhlIFRpbWVTdGFtcCBmb3JtYXQuIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVR9XG4gKiBAcGFyYW0ge3tuZXc6IFVwZGF0ZVZhbGlkYXRvcn19IFt2YWxpZGF0b3JdIGRlZmF1bHRzIHRvIHtAbGluayBUaW1lc3RhbXBWYWxpZGF0b3J9XG4gKlxuICogQGRlY29yYXRvciB0aW1lc3RhbXBcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZXN0YW1wKFxuICBvcGVyYXRpb246IE9wZXJhdGlvbktleXNbXSA9IERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFIGFzIHVua25vd24gYXMgT3BlcmF0aW9uS2V5c1tdLFxuICBmb3JtYXQ6IHN0cmluZyA9IERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5USU1FU1RBTVApO1xuXG4gIGNvbnN0IGRlY29yYXRvcnM6IGFueVtdID0gW1xuICAgIGRhdGUoZm9ybWF0LCBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5EQVRFKSxcbiAgICByZXF1aXJlZChERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5SRVFVSVJFRCksXG4gICAgb24ob3BlcmF0aW9uLCB0aW1lc3RhbXBIYW5kbGVyKSxcbiAgXTtcblxuICBpZiAob3BlcmF0aW9uLmluZGV4T2YoT3BlcmF0aW9uS2V5cy5VUERBVEUpICE9PSAtMSlcbiAgICBkZWNvcmF0b3JzLnB1c2goXG4gICAgICBwcm9wTWV0YWRhdGEoVmFsaWRhdGlvbi51cGRhdGVLZXkoREJLZXlzLlRJTUVTVEFNUCksIHtcbiAgICAgICAgbWVzc2FnZTogREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuSU5WQUxJRCxcbiAgICAgIH0pXG4gICAgKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKC4uLmRlY29yYXRvcnMpXG4gICAgLmFwcGx5KCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemVPbkNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIW1vZGVsW2tleV0pIHJldHVybjtcbiAgdHJ5IHtcbiAgICBtb2RlbFtrZXldID0gSlNPTi5zdHJpbmdpZnkobW9kZWxba2V5XSkgYXMgTVtrZXlvZiBNXTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgYEZhaWxlZCB0byBzZXJpYWxpemUgJHtrZXkudG9TdHJpbmcoKX0gcHJvcGVydHkgb2YgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfTogZWBcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemVBZnRlckFsbDxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIW1vZGVsW2tleV0pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBtb2RlbFtrZXldICE9PSBcInN0cmluZ1wiKSByZXR1cm47XG5cbiAgdHJ5IHtcbiAgICBtb2RlbFtrZXldID0gSlNPTi5wYXJzZShtb2RlbFtrZXldKTtcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGRlc2VyaWFsaXplICR7a2V5LnRvU3RyaW5nKCl9IHByb3BlcnR5IG9mIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX06ICR7ZX1gXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFNlcmlhbGl6ZSBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBwcm9wZXJ0aWVzIGRlY29yYXRlZCB3aWxsIHRoZSBzZXJpYWxpemVkIGJlZm9yZSBzdG9yZWQgaW4gdGhlIGRiXG4gKlxuICogQGZ1bmN0aW9uIHNlcmlhbGl6ZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6d2FsbGV0LWRiLkRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIG9uQ3JlYXRlVXBkYXRlKHNlcmlhbGl6ZU9uQ3JlYXRlVXBkYXRlKSxcbiAgICBhZnRlcihEQk9wZXJhdGlvbnMuQUxMLCBzZXJpYWxpemVBZnRlckFsbCksXG4gICAgdHlwZShbU3RyaW5nLm5hbWUsIE9iamVjdC5uYW1lXSksXG4gICAgbWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlNFUklBTElaRSksIHt9KVxuICApO1xufVxuIl19