import {Application} from './Application' import {Container, Injectable, TypedDependencyKey} from '../di' /** * Base type for a class that supports binding methods by string. */ export interface Bindable { getBoundMethod(methodName: string): (...args: any[]) => any } /** * Returns true if the given object is bindable. * @param what * @return boolean */ export function isBindable(what: unknown): what is Bindable { return ( Boolean(what) && typeof (what as any).getBoundMethod === 'function' && (what as any).getBoundMethod.length === 1 && typeof (what as any).getBoundMethod('getBoundMethod') === 'function' ) } /** * Base for classes that gives access to the global application and container. */ @Injectable() export class AppClass { /** The global application instance. */ private get appClassApplication(): Application { return Application.getApplication() } /** Get the global Application. */ protected app(): Application { return this.appClassApplication } /** Get the global Container. */ protected container(): Container { return this.appClassApplication } /** Call the `make()` method on the global container. */ protected make(target: TypedDependencyKey, ...parameters: any[]): T { return this.container().make(target, ...parameters) } /** * Get the method with the given name from this class, bound to this class. * @param {string} methodName * @return function */ public getBoundMethod(methodName: string): (...args: any[]) => any { if ( typeof (this as any)[methodName] !== 'function' ) { throw new TypeError(`Attempt to get bound method for non-function type: ${methodName}`) } return (...args: any[]): any => { return (this as any)[methodName](...args) } } }