@decaf-ts/db-decorators
Version:
Agnostic database decorators and repository
370 lines (367 loc) • 20.3 kB
TypeScript
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;