type SurrogateContexts = 'instance' | 'surrogate'; type MethodWrappers = 'sync' | 'async'; type Contexts = SurrogateContexts | typeof Object | typeof Function | Object; /** * @description Function run when an Error occurs and will determine if Surrogate should silence any error output */ type ShouldSilence = (error: Error) => boolean; interface RecoverableProvider = any, Result = any> extends ProviderParameters { shouldRecover: boolean; } export interface RunOnErrorParameters = any, Result = any> extends RecoverableProvider { error: Error; recoverFromError(recover: boolean): void; } export interface RunOnBailParameters = any, Result = any> extends RecoverableProvider { bailWith(value: any): void; recoverFromBail(recover: boolean): void; } export type RunOnBail = = any, Result = any>(bailParameters: RunOnBailParameters) => any; export type RunOnError = = any, Result = any>(errorParameters: RunOnErrorParameters) => any; /** * Surrogate Options * * @export * @interface SurrogateOptions */ export interface SurrogateOptions extends SurrogateGlobalOptions { /** * @description Instructs Surrogate to operate as a Singleton * @default true * @type {boolean} * @memberof SurrogateOptions */ useSingleton?: boolean; /** * @description Will force Surrogate to run specified methods with or without hooks. * @default false * @Type {boolean|string|string[]} * @memberof SurrogateOptions */ maintainContext?: boolean | string | string[]; } interface SurrogateGlobalOptions { /** * @description Pass Next object to the Surrogate Handler * * @default true */ useNext?: boolean; /** * @description Specify that nothing should be passed to handler * * @default false */ noArgs?: boolean; /** * @description Should errors be thrown or ignored when passed via next()? * * @default false */ ignoreErrors?: boolean; /** * @description Specifies the context in which to call a handler. Method defined contexts take precedence. * * @options * - instance * - surrogate * - user supplied context object * * @default instance * @type {Contexts} * @memberof SurrogateGlobalOptions */ useContext?: Contexts; /** * @description Function to be called when an error is thrown. Will run even if errors are ignored. * @type {RunOnError|RunOnError[]} * @memberof SurrogateGlobalOptions */ runOnError?: RunOnError | RunOnError[]; /** * @description Function to be called when bailing out of a handler. * @type {RunOnBail|RunOnBail[]} * @memberof SurrogateGlobalOptions */ runOnBail?: RunOnBail | RunOnBail[]; /** * @description Provide content for Surrogate to pass to handlers and conditionals. * @type {any} * @memberof SurrogateGlobalOptions */ provide?: any; /** * @description Ignore error output * @note If supplying a function a result of true will silence errors and false will allow output * @default false * @type {(boolean | ShouldSilence)} * @memberof SurrogateGlobalOptions */ silenceErrors?: boolean | ShouldSilence; } interface GlobalHandlerOptions { handler?: SurrogateHandlerOptions; global?: SurrogateOptions; } type CombinedOptions = Required> & Required>; export enum SurrogateContext { Instance = "instance", Surrogate = "surrogate" } export enum MethodWrapper { Sync = "sync", Async = "async" } interface OptionsHandler extends CombinedOptions { } declare class OptionsHandler { protected readonly combinedOptions: GlobalHandlerOptions; constructor(combinedOptions?: GlobalHandlerOptions); } declare const METHOD = "method"; declare const EMPTY = "empty"; export const BOTH = "both"; export const POST = "post"; export const PRE = "pre"; type WhichMethod = Which | typeof METHOD | typeof EMPTY; type Which = typeof PRE | typeof POST; type Whichever = Which | typeof BOTH; export enum HookType { PRE = "pre", POST = "post", BOTH = "both" } declare class EventManager implements SurrogateEventManager { readonly globalOptions: SurrogateOptions; constructor(globalOptions?: SurrogateOptions); getEventMap(): EventMap; getEventHandlers(event: string): WhichContainers; getPreEventHandlers(event: string): SurrogateHandlerContainer[]; getPostEventHandlers(event: string): SurrogateHandlerContainer[]; eventIsHandled(event: string): boolean; registerHook(event: string, type: Which, handler: SurrogateHandlers, options: SurrogateHandlerOptions): EventManager; registerPreHook(event: string, handler: SurrogateHandlers, options?: SurrogateHandlerOptions): EventManager; registerPostHook(event: string, handler: SurrogateHandlers, options?: SurrogateHandlerOptions): EventManager; deregisterHooks(): EventManager; deregisterHooksFor(event: string): EventManager; deregisterPreHook(event: string, handler: SurrogateHandlers): EventManager; deregisterPostHook(event: string, handler: SurrogateHandlers): EventManager; deregisterPostHooks(event: string): EventManager; deregisterPreHooks(event: string): EventManager; } declare class Context { readonly target: T; readonly receiver: Surrogate; readonly event: string; readonly original: Function; readonly originalArguments: any[]; constructor(target: T, receiver: Surrogate, event: string, original: Function, originalArguments: any[]); determineContext(options: RequiredHandlerOptions): Contexts; useInstance(context: Contexts): boolean; useSurrogate(context: Contexts): boolean; } declare class SurrogateProxy implements ProxyHandler { constructor(target: T, { useSingleton, ...globalOptions }?: SurrogateOptions); get(target: T, event: string, receiver: Surrogate): T[K] | EventManager; getEventManager(target: T): EventManager; static wrap(object: T, options?: SurrogateOptions): Surrogate; static hasTarget(target: T): target is Surrogate; bindHandler(event: string, target: T, receiver: Surrogate): Function; surrogateHandler(context: Context): any; dispose(target: T): T; } interface TimeTracking extends TimeTracker { setHookStart(): void; setHookEnd(): void; } interface TimeTracker { getDurationSinceLastRun(): number; getLastRunDuration(): number; getHookStartTime(): number; getTotalDuration(): number; getStartTime(): number; } interface SurrogateHandlerRunner { run(args: any[], error?: Error): void; } export interface HandlerContainer { type: WhichMethod; options: OptionsHandler; getHandlerRunner(node: NextNode): SurrogateHandlerRunner; getHandler(context: Context): SurrogateHandler | Function; } declare abstract class BaseContainer implements HandlerContainer { protected readonly handler: SurrogateHandlerTypes | Function; readonly type: WhichMethod; readonly options: OptionsHandler; constructor(handler: SurrogateHandlerTypes | Function, type: WhichMethod, options?: OptionsHandler); getHandler(context: Context): Function | SurrogateHandler; getHandlerRunner(node: NextNode): SurrogateHandlerRunner; } declare class SurrogateHandlerContainer extends BaseContainer { readonly handler: SurrogateHandlerTypes; readonly type: Which; constructor(handler: SurrogateHandlerTypes, type: Which, options: OptionsHandler); } /** * @description Object containing PRE and POST handlers for a method * * @export * @interface WhichContainers * @template T */ interface WhichContainers { [HookType.PRE]: SurrogateHandlerContainer[]; [HookType.POST]: SurrogateHandlerContainer[]; } export interface NextOptions extends BailOptions { bail?: boolean; } interface BailOptions { error?: Error | false | null | undefined; bailWith?: any; replace?: any; using?: any[]; } interface ContextController { start(): any; complete(): void; returnValue: any; currentArgs: any[]; context: Context; correlationId: string; bail(bailWith: any): any; timeTracker: TimeTracking; addNext(next: NextNode): void; setNext(next: NextNode): void; runOriginal(node: NextNode): void; updateLatestArgs(updatedArgs: any): void; handleError(node: NextNode, error?: Error): never | void; setupPipeline(proxy: SurrogateProxy, typeContainers: WhichContainers): ContextController; } export interface INext { skip(skipAmount?: number): void; bail(bailOptions?: BailOptions): void; next(nextOptions?: NextOptions): void; skipWith(skipAmount?: number, ...args: any[]): void; } interface NextNode extends INext { handleNext(options?: NextOptions): void; shouldRun(using: any[]): boolean; addNext(next: NextNode): void; controller: ContextController; instance: SurrogateUnwrapped; container: HandlerContainer; proxy: SurrogateProxy; nextNode: NextNode; prevNode: NextNode; useContext: Contexts; context: Context; hookType: string; didError: Error; } /** * * @deprecated Use NextParameters * @export * @interface NextHandler * @extends {ProviderParameters} * @template T */ export interface NextHandler extends NextParameters { } /** * * @export * @interface NextParameters * @extends {ProviderParameters} * @template T */ export interface NextParameters = any, Result = any> extends ProviderParameters { surrogate: Surrogate; next: INext; } type RequiredHandlerOptions = any, Result = any> = Required>; export interface SurrogateHandlerOptions = any, Result = any> extends SurrogateGlobalOptions { /** * @description Specifies the method context wrapper to utilize * * @options * - sync * - async * * @default sync */ wrapper?: MethodWrappers; /** * @description Conditions to determine if a handler should be executed */ runConditions?: RunCondition | RunCondition[]; /** * @description - Specify the priority of the handler. Higher priority handlers are run first. * * @default 0 */ priority?: number; } interface EventMap { [event: string]: WhichContainers; } /** * @description Class that manages PRE and POST method handlers for Surrogate wrapped instances. * * @export * @interface SurrogateEventManager * @template T */ export interface SurrogateEventManager { /** * @description Removes all handlers for all methods * * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ deregisterHooks(): SurrogateEventManager; /** * @description Removes all PRE handlers for the provided method * * @param {keyof T | string} event * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ deregisterPreHooks(event: keyof T | string): SurrogateEventManager; /** * @description Removes all POST handlers for the provided method * * @param {keyof T | string} event * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ deregisterPostHooks(event: keyof T | string): SurrogateEventManager; /** * @description Removes a specific PRE handler for the provided method * * @param {keyof T | string} event * @param {SurrogateHandlers} handler * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ deregisterPreHook(event: keyof T | string, handler: SurrogateHandlers): SurrogateEventManager; /** * @description Removes a specific POST handler for the provided method * * @param {keyof T | string} event * @param {SurrogateHandlers} handler * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ deregisterPostHook(event: keyof T | string, handler: SurrogateHandlers): SurrogateEventManager; /** * @description Retrieves all handlers in an event map * * @returns {EventMap} * @memberof SurrogateEventManager */ getEventMap(): EventMap; /** * @description Retrieves all handlers for the provided method * * @param {keyof T | string} event * @returns {WhichContainers} * @memberof SurrogateEventManager */ getEventHandlers(event: keyof T | string): WhichContainers; /** * @description Retrieves all PRE handlers for the provided method * * @param {keyof T | string} event * @returns {SurrogateHandlerContainer} * @memberof SurrogateEventManager */ getPreEventHandlers(event: keyof T | string): SurrogateHandlerContainer[]; /** * @description Retrieves all POST handlers for the provided method * * @param {keyof T | string} event * @returns {SurrogateHandlerContainer} * @memberof SurrogateEventManager */ getPostEventHandlers(event: keyof T | string): SurrogateHandlerContainer[]; /** * @description Registers a PRE handler or array of handlers for the provided method * * @param {keyof T | string} event * @param {(SurrogateHandlers)} handler * @param {SurrogateHandlerOptions} [options] * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ registerPreHook(event: keyof T | string, handler: SurrogateHandlers, options?: SurrogateHandlerOptions): SurrogateEventManager; /** * @description Registers a POST handler or array of handlers for the provided method * * @param {keyof T | string} event * @param {(SurrogateHandlers)} handler * @param {SurrogateHandlerOptions} [options] * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ registerPostHook(event: keyof T | string, handler: SurrogateHandlers, options?: SurrogateHandlerOptions): SurrogateEventManager; /** * @description Registers a PRE or POST handler for the provided method * * @param {keyof T | string} event * @param {Which} type * @param {(SurrogateHandlers)} handler * @param {SurrogateHandlerOptions} options * @returns {SurrogateEventManager} * @memberof SurrogateEventManager */ registerHook(event: keyof T | string, type: Which, handler: SurrogateHandlers, options: SurrogateHandlerOptions): SurrogateEventManager; } export interface SurrogateMethods { disposeSurrogate(): T; getSurrogate(): SurrogateEventManager; bypassSurrogate(): SurrogateUnwrapped; } export type Surrogate = SurrogateMethods & T; export type SurrogateUnwrapped = Omit, keyof SurrogateMethods>; /** * @description Surrogate handler types */ export type SurrogateHandler = any, Result = any> = (nextParameters: NextParameters) => unknown; export type SurrogateHandlerTypes = any, Result = any> = SurrogateHandler | keyof T | string; export type SurrogateHandlers = any, Result = any> = SurrogateHandlerTypes | SurrogateHandlerTypes[]; interface ProviderParameters { /** * @description The current, unwrapped instance * * @note Being unwrapped it does not have access to Surrogate methods and no hooks will run * * @type {SurrogateUnwrapped} * @memberof ProviderParameters */ instance: SurrogateUnwrapped; /** * @description The current hook pipeline time tracker * * @type {TimeTracker} * @memberof ProviderParameters */ timeTracker: TimeTracker; /** * @description Arguments passed to called method * * @type {Arguments} * @memberof ProviderParameters */ originalArgs: Arguments; /** * @description Hook pipeline correlation id * * @note Sub hook pipelines receive a new correlation id * * @type {string} * @memberof ProviderParameters */ correlationId: string; /** * @description The method name of the current hook pipeline * * @type {string} * @memberof ProviderParameters */ action: string; receivedArgs: any[]; currentArgs: any[]; /** * @description The hook type of the pipeline (pre|post) * * @type {string} * @memberof ProviderParameters */ hookType: string; /** * @description The error thrown by the hook pipeline method invocation * * @type {Error} * @memberof ProviderParameters */ error?: Error | undefined; /** * @description Any additional provided values to the hook pipeline * * @type {*} * @memberof ProviderParameters */ provide: any; /** * @description The result of the current hook pipeline method invocation * * @type {T[keyof T]} * @memberof ProviderParameters */ result: Result; } export interface RunConditionParameters = any, Result = any> extends ProviderParameters { didError: boolean; valueFromCondition: any; didReceiveFromLastCondition: boolean; passToNextCondition(value: any): void; } export type RunCondition = any, Result = any> = (parameters: RunConditionParameters) => boolean; /** * Helper function to create Surrogate wrapped objects * * @export * @template T * @param {T} object * @param {SurrogateOptions} [options={}] * @returns {Surrogate} */ export const wrapSurrogate: (object: T, options?: SurrogateOptions) => Surrogate; type Constructor = { new (...args: any[]): T; }; export interface SurrogateDecorateOptions extends SurrogateOptions { locateWith?: Constructor; } export interface SurrogateDecoratorOptions = any, Result = any> { options?: SurrogateHandlerOptions; handler: SurrogateHandlers; } export type SurrogateDelegateOptions = any, Result = any> = SurrogateHandlers | SurrogateDecoratorOptions | SurrogateDecoratorOptions[]; export interface SurrogateForOptions = any, Result = any> { options: SurrogateDelegateOptions; type: Whichever; } type Action = keyof SurrogateUnwrapped | (keyof SurrogateUnwrapped)[] | string | string[]; export interface NextDecoratorOptions { options?: SurrogateHandlerOptions; action: Action; } export interface NextForOptions extends NextDecoratorOptions { type: Whichever; } type PropertyDecorator = (target: T, property: Action) => void; /** * @description Register class for automatic surrogate wrapping * * @export * @decorator * @template T * @param {SurrogateDecorateOptions} [delegateOptions={}] */ export const SurrogateDelegate: (delegateOptions?: SurrogateDecorateOptions) => (klass: K) => K; /** * @description Registers hooks for decorated methods. Handler type must be assigned. * * @export * @decorator * @template T * @param {(SurrogateForOptions | SurrogateForOptions[])} forOptions * @returns {PropertyDecorator} */ export const SurrogateFor: (forOptions: SurrogateForOptions | SurrogateForOptions[]) => PropertyDecorator; /** * @description Registers pre and post hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogatePreAndPost: (decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; /** * @description Registers pre hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogatePre: (decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; /** * @description Registers post hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogatePost: (decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; /** * @description Registers async pre and post hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogateAsyncPreAndPost: (decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; /** * @description Registers async post hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogateAsyncPost: = any, Result = any>(decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; /** * @description Registers async pre hooks for decorated methods * * @export * @decorator * @template T * @param {(SurrogateDelegateOptions | SurrogateDelegateOptions[])} decoratorOptions * @returns {PropertyDecorator} */ export const SurrogateAsyncPre: (decoratorOptions: SurrogateDelegateOptions | SurrogateDelegateOptions[]) => PropertyDecorator; type _PropertyDecorator1 = (target: T, property: string, descriptor: PropertyDescriptor) => void; /** * @description Designate decorated methods as next handler. Handler type must be assigned * * @export * @decorator * @template T * @param {(NextForOptions | NextForOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextFor: (nextOptions: NextForOptions | NextForOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as async pre hooks. * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextAsyncPre: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as async post hooks. * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextAsyncPost: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as async pre and post hooks. * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextAsyncPreAndPost: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as pre hooks. * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextPre: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as post hook * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextPost: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; /** * Designate decorated methods as pre and post hooks. * * @export * @decorator * @template T * @param {(NextDecoratorOptions | NextDecoratorOptions[])} nextOptions * @returns {PropertyDecorator} */ export const NextPreAndPost: (nextOptions: NextDecoratorOptions | NextDecoratorOptions[]) => _PropertyDecorator1; //# sourceMappingURL=types.d.ts.map