UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

370 lines (367 loc) 20.3 kB
import { GeneralOperationHandler, GeneralUpdateOperationHandler, IdOperationHandler, OperationHandler, StandardOperationHandler, UpdateOperationHandler } from "./types"; import { CrudOperations, OperationKeys } from "./constants"; import { Model } from "@decaf-ts/decorator-validation"; import { IRepository } from "../interfaces"; import { Constructor } from "@decaf-ts/decoration"; /** * @description Represents sorting parameters for grouping decorators * @summary Defines the structure for specifying group sorting options * @typedef {Object} GroupSort * @property {number} priority - The priority of the sorting operation, lower numbers represent higher priority * @property {string} [group] - Optional property to group decorators, used for grouping related operations * @property {number} [groupPriority] - Optional property to specify the priority within a group, lower numbers represent higher priority within the group * @category Type Definitions */ export type GroupSort = { priority: number; group?: string; groupPriority?: number; }; /** * @description DecoratorObject type definition * @summary Defines the structure of an object used to represent a decorator in the context of database operations. * @typedef {Object} DecoratorObject * @property {OperationHandler<any, any, any>} handler - The handler function to be executed during the operation * @property {object} data - Optional metadata to be passed to the handler function * @property {string} prop - The property key to which the decorator is applied * @category Type Definitions */ export type DecoratorObject = { handler: OperationHandler<any, any, any>; data: Record<string, any>[]; prop: string[]; }; /** * @summary retrieves the arguments for the handler * @param {any} dec the decorator * @param {string} prop the property name * @param {{}} m the model * @param {{}} [accum] accumulator used for internal recursiveness * * @function getHandlerArgs * @memberOf module:db-decorators.Repository */ export declare const getHandlerArgs: (dec: any, prop: string, m: Constructor<any>, accum?: Record<string, { args: string[]; }>) => Record<string, { args: string[]; }> | void; /** * @description Retrieves decorator objects for handling database operations * @summary Retrieves a list of decorator objects representing operation handlers for a given model and decorators * @template M - Type for the model, defaults to Model<true | false> * @template R - Type for the repository, defaults to IRepository<M, F, C> * @template V - Type for metadata, defaults to object * @template F - Type for repository flags, defaults to RepositoryFlags * @template C - Type for context, defaults to Context<F> * @param {Model} model - The model for which to retrieve decorator objects * @param {Record<string, DecoratorMetadata[]>} decorators - The decorators associated with the model properties * @param {string} prefix - The operation prefix (e.g., 'on', 'after') * @return {DecoratorObject[]} An array of decorator objects representing operation handlers * @function getHandlersDecorators * @category Function */ export declare function getHandlersDecorators<M extends Model<true | false>, R extends IRepository<M, any>, V extends object = object>(model: Model, decorators: Record<string, DecoratorMetadata[]>, prefix: string): DecoratorObject[]; /** * @description Groups decorators based on their group property * @summary Groups decorator objects by their group property, combining data and properties within each group * @param {DecoratorObject[]} decorators - The array of decorator objects to group * @return {DecoratorObject[]} An array of grouped decorator objects * @function groupDecorators * @category Function */ export declare function groupDecorators(decorators: DecoratorObject[]): DecoratorObject[]; /** * @description Sorts decorator objects based on their priority * @summary Sorts an array of decorator objects by the priority of their first data element * @param {DecoratorObject[]} decorators - The array of decorator objects to sort * @return {DecoratorObject[]} The sorted array of decorator objects * @function sortDecorators * @category Function */ export declare function sortDecorators(decorators: DecoratorObject[]): DecoratorObject[]; /** * @description Decorator for handling create and update operations * @summary Defines a behavior to execute during both create and update operations * @template V - Type for metadata, defaults to object * @param {GeneralOperationHandler<any, any, V, any, any> | GeneralUpdateOperationHandler<any, any, V, any, any>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onCreateUpdate * @category Property Decorators */ export declare function onCreateUpdate<V = object>(handler: GeneralOperationHandler<any, any, V> | GeneralUpdateOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling update operations * @summary Defines a behavior to execute during update operations * @template V - Type for metadata, defaults to object * @param {UpdateOperationHandler<any, any, V, any>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onUpdate * @category Property Decorators */ export declare function onUpdate<V = object>(handler: UpdateOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling create operations * @summary Defines a behavior to execute during create operations * @template V - Type for metadata, defaults to object * @param {GeneralOperationHandler<any, any, V>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onCreate * @category Property Decorators */ export declare function onCreate<V = object>(handler: GeneralOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling read operations * @summary Defines a behavior to execute during read operations * @template V - Type for metadata, defaults to object * @param {IdOperationHandler<any, any, V>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onRead * @category Property Decorators */ export declare function onRead<V = object>(handler: IdOperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling delete operations * @summary Defines a behavior to execute during delete operations * @template V - Type for metadata, defaults to object * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onDelete * @category Property Decorators */ export declare function onDelete<V = object>(handler: OperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling all operation types * @summary Defines a behavior to execute during any database operation * @template V - Type for metadata, defaults to object * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function onAny * @category Property Decorators */ export declare function onAny<V = object>(handler: OperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Base decorator for handling database operations * @summary Defines a behavior to execute during specified database operations * @template V - Type for metadata, defaults to object * @param {OperationKeys[] | DBOperations} [op=DBOperations.ALL] - One or more operation types to handle * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function on * @category Property Decorators * @example * // Example usage: * class MyModel { * @on(DBOperations.CREATE, myHandler) * myProperty: string; * } */ export declare function on<V = object>(op: OperationKeys[] | undefined, handler: OperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-create and post-update operations * @summary Defines a behavior to execute after both create and update operations * @template V - Type for metadata, defaults to object * @param {StandardOperationHandler<any, any, V> | UpdateOperationHandler<any, any, V, any, any>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterCreateUpdate * @category Property Decorators */ export declare function afterCreateUpdate<V = object>(handler: StandardOperationHandler<any, any, V> | UpdateOperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-update operations * @summary Defines a behavior to execute after update operations * @template V - Type for metadata, defaults to object * @param {UpdateOperationHandler<any, any, V>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterUpdate * @category Property Decorators */ export declare function afterUpdate<V = object>(handler: UpdateOperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-create operations * @summary Defines a behavior to execute after create operations * @template V - Type for metadata, defaults to object * @param {StandardOperationHandler<any, any, V>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterCreate * @category Property Decorators */ export declare function afterCreate<V = object>(handler: StandardOperationHandler<any, any, V>, data: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-read operations * @summary Defines a behavior to execute after read operations * @template V - Type for metadata, defaults to object * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterRead * @category Property Decorators */ export declare function afterRead<V = object>(handler: StandardOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-delete operations * @summary Defines a behavior to execute after delete operations * @template V - Type for metadata, defaults to object * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterDelete * @category Property Decorators */ export declare function afterDelete<V = object>(handler: StandardOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Decorator for handling post-operation for all operation types * @summary Defines a behavior to execute after any database operation * @template V - Type for metadata, defaults to object * @param {StandardOperationHandler<any, any, V>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function afterAny * @category Property Decorators */ export declare function afterAny<V = object>(handler: StandardOperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Base decorator for handling post-operation behaviors * @summary Defines a behavior to execute after specified database operations * @template V - Type for metadata, defaults to object * @param {OperationKeys[] | DBOperations} [op=DBOperations.ALL] - One or more operation types to handle * @param {OperationHandler<any, any, Vy>} handler - The method called after the operation * @param {V} [data] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function after * @category Property Decorators * @example * // Example usage: * class MyModel { * @after(DBOperations.CREATE, myHandler) * myProperty: string; * } */ export declare function after<V = object>(op: OperationKeys[] | undefined, handler: OperationHandler<any, any, V>, data?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description Core decorator factory for operation handlers * @summary Creates decorators that register handlers for database operations * @template V - Type for metadata, defaults to object * @param {OperationKeys.ON | OperationKeys.AFTER} baseOp - Whether the handler runs during or after the operation * @param {OperationKeys[]} [operation=DBOperations.ALL] - The specific operations to handle * @param {OperationHandler<any, any, V>} handler - The handler function to execute * @param {V} [dataToAdd] - Optional metadata to pass to the handler * @return {PropertyDecorator} A decorator that can be applied to class properties * @function operation * @category Property Decorators * @mermaid * sequenceDiagram * participant Client * participant Decorator as @operation * participant Operations as Operations Registry * participant Handler * * Client->>Decorator: Apply to property * Decorator->>Operations: Register handler * Decorator->>Decorator: Store metadata * * Note over Client,Handler: Later, during operation execution * Client->>Operations: Execute operation * Operations->>Handler: Call registered handler * Handler-->>Operations: Return result * Operations-->>Client: Return final result */ export declare function operation<V = object>(baseOp: OperationKeys.ON | OperationKeys.AFTER, operation: OperationKeys[] | undefined, handler: OperationHandler<any, any, V>, dataToAdd?: V, groupsort?: GroupSort): (target: any, propertyKey?: any) => void; /** * @description * Creates a higher-order function that attaches a metadata entry containing a handler * and its execution parameters, to be conditionally evaluated later. * * @summary * The `executeIf` function is a decorator factory designed to wrap a handler function * and associate it with a specific metadata key. When invoked, it stores both the * parameters passed and the handler reference inside the metadata system for deferred * or conditional evaluation. This is particularly useful for dynamically applying logic * or decorators only when certain conditions are met. * * @template P - Represents a tuple of any parameter types that the handler function accepts. * * @param {string} key - The metadata key used to store and later retrieve the handler and its parameters. * @param {function(...P):boolean} handler - A predicate or handler function that receives the same parameters as the decorator * and determines whether the associated logic should execute. * * @return {function(...P):function(...Partial<P>):void} * Returns a function that, when invoked with the given parameters, stores a metadata object containing * both the parameters and the handler reference under the provided key. * * @function storeHandlerMetadata * * @mermaid * sequenceDiagram * participant Dev as Developer * participant executeIf as executeIf() * participant ReturnedFn as Returned Function * participant Metadata as metadata() * * Dev->>executeIf: Calls executeIf(key, handler) * executeIf->>ReturnedFn: Returns function(...params) * Dev->>ReturnedFn: Invokes returned function with (...params) * ReturnedFn->>Metadata: Calls metadata(key, { args: params, handler }) * Metadata-->>ReturnedFn: Returns stored metadata reference * ReturnedFn-->>Dev: Returns metadata response * */ export declare function storeHandlerMetadata<P extends any[]>(key: string, handler: (...params: P) => boolean): (...params: Partial<P>) => (model: any, prop?: any, descriptor?: PropertyDescriptor | number) => void; /** * @description * Decorator factory that conditionally blocks specific CRUD operations * from being executed on a model or controller. * * @summary * The `BlockOperations` decorator integrates with the `executeIf` mechanism to * associate metadata that defines which CRUD operations should be restricted. * When applied, it registers a conditional handler that evaluates whether a given * operation is included in the list of blocked operations. This enables dynamic, * metadata-driven control over allowed operations in CRUD-based systems. * * @template CrudOperations - Enum or type representing valid CRUD operations. * * @param {CrudOperations[]} operations - An array of CRUD operations that should be blocked. * The handler will later check if the requested operation is part of this list. * * Returns a decorator that stores metadata indicating which operations are blocked. * The metadata can be inspected or enforced later within the application's lifecycle. * * @function BlockOperations * @category decorators */ export declare const BlockOperations: (operations: CrudOperations[]) => (model: any, prop?: any, descriptor?: PropertyDescriptor | number) => void; /** * @description * Decorator factory that conditionally blocks specific CRUD operations * from being executed on a model or controller. * * @summary * The `BlockOperations` decorator integrates with the `executeIf` mechanism to * associate metadata that defines which CRUD operations should be restricted. * When applied, it registers a conditional handler that evaluates whether a given * operation is included in the list of blocked operations. This enables dynamic, * metadata-driven control over allowed operations in CRUD-based systems. * * @template CrudOperations - Enum or type representing valid CRUD operations. * * @param {function(any[]): boolean} handler - An array of CRUD operations that should be blocked. * The handler will later check if the requested operation is part of this list. * * Returns a decorator that stores metadata indicating which operations are blocked. * The metadata can be inspected or enforced later within the application's lifecycle. * * @function BlockOperationIf * @category decorators */ export declare const BlockOperationIf: (handler: <P extends any[]>(...params: P) => boolean) => (model: any, prop?: any, descriptor?: PropertyDescriptor | number) => void;