import { getSingleton } from "../helpers/singletonMethod"; // Symbols for the Property Registery: const _registeredDispatcherMethods_ = Symbol('_registeredDispatcherMethods_'); const _registeredDispatcherParams_ = Symbol('_registeredDispatcherParams_'); // Interfaces for the Class export interface IExportToDispatcherParameters { uri?: string, } export interface IExportMethodToDispatcherParameters { uri: string, } export interface IExportFunctionToDispatcherParameters { uri?: string, } export interface IExportPropertyToDispatcherParameters { uri?: string, readonly?: boolean } const container = getSingleton('nopeBackendDispatcher.methodContainer', () => { return { methods: new Map Promise, options: IExportMethodToDispatcherParameters }>(), parameters: new Map Promise, options: IExportPropertyToDispatcherParameters }>() } }); /** * Decorator used to export a Class API over openAPI * @param options */ export function exportsElementsToDispatcher(options: IExportToDispatcherParameters) { return function (Base: T) { return class extends Base { constructor(...args: any[]) { super(...args); const _this = this as any; // extract the Registered Methods of the Class. const registeredMethods = Base.prototype[_registeredDispatcherMethods_] as Map; const registeredParams = Base.prototype[_registeredDispatcherParams_] as Map; // Online if they are present, iterate over them if (registeredMethods) { registeredMethods.forEach((options, methodName) => { // Register the Methods const uri = (options.uri || Base.prototype.name) + (options.uri || methodName); container.instance.methods.set(uri, { callback: async (...args) => _this[methodName](...args), uri, options }); }); } // Online if they are present, iterate over them if (registeredParams) { registeredParams.forEach((options, parameterName) => { // Register the Methods const uri = (options.uri || Base.prototype.name) + (options.uri || parameterName); container.instance.parameters.set(uri, { callback: async (...args) => _this[parameterName](...args), uri, options }); }); } } }; } } /** * Decorator, used to export the Method. * @param options */ export function exportMethodToDispatcher(options: IExportMethodToDispatcherParameters) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { target[_registeredDispatcherMethods_] = target[_registeredDispatcherMethods_] || new Map(); // Here we just add some information that class decorator will use target[_registeredDispatcherMethods_].set(propertyKey, options); }; } /** * Decorator, will create a POST and GET api for the Parameter. * @param options */ export function exportPropertyToDispatcher(options: IExportPropertyToDispatcherParameters) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { target[_registeredDispatcherParams_] = target[_registeredDispatcherParams_] || new Map(); // Here we just add some information that class decorator will use target[_registeredDispatcherParams_].set(propertyKey, options); }; } /** * Defintion of a Functon. */ export type callable = { (...args): T } /** * Decorator, that will export the Function to a Dispatcher * @param func The Function * @param options The Options. */ export function exportFunctionToDispatcher(func: callable, options: IExportMethodToDispatcherParameters) { container.instance.methods.set(options.uri, { callback: async (...args) => await func(...args), options, uri: options.uri || func.name }); return func; }