diff --git a/express/src/decorators/params.ts b/express/src/decorators/params.ts index 0c3ec5c..bca1e7d 100644 --- a/express/src/decorators/params.ts +++ b/express/src/decorators/params.ts @@ -1,4 +1,4 @@ -import { ParameterType, ExpressClass } from '../interface'; +import { ParameterType, ExpressClass, ParameterConfiguration } from '../interface'; import { getMeta } from '../meta'; /** diff --git a/express/src/express.ts b/express/src/express.ts index ed2fad6..8efc639 100644 --- a/express/src/express.ts +++ b/express/src/express.ts @@ -1,6 +1,6 @@ import { Router, Express, RequestHandler } from 'express'; -import { ParameterType, Routes, Middleware, Injectable, ExpressClass } from './interface'; +import { ParameterType, Routes, Middleware, Injectable, ExpressClass, Params } from './interface'; function getParam(source: any, paramType: string, name: string) { let param = source[paramType] || source; diff --git a/playground/socket/index.ts b/playground/socket/index.ts index 53d14e8..46069a6 100644 --- a/playground/socket/index.ts +++ b/playground/socket/index.ts @@ -35,6 +35,10 @@ class SocketWrapper { @Namespace('/messaging') class FirstController { + constructor(...args) { + console.log(args); + } + @Event('message', (io, socket, packet, next) => { console.log('Message middleware'); next(); @@ -46,4 +50,6 @@ class FirstController { } -bootstrapSocketIO(server, [ FirstController ]); +bootstrapSocketIO(server, [ + { provide: FirstController, deps: [1, 2, 3]} +]); diff --git a/socket/CHANGELOG.md b/socket/CHANGELOG.md index faf6514..7596a01 100644 --- a/socket/CHANGELOG.md +++ b/socket/CHANGELOG.md @@ -1,3 +1,10 @@ +# Socket#1.4.0 +* Controller DI +```typescript +{ provide: UserController, deps: [UserService] } +``` +* Renamed methods **bootstrapSocketIO** and **attachControllerToSocket** (see README for details) + # Socket#1.3.3 * Added possibility to pass array of middleware funcs into: * **@ServerMiddleware** diff --git a/socket/README.md b/socket/README.md index 581f5cf..e010eaf 100644 --- a/socket/README.md +++ b/socket/README.md @@ -9,8 +9,15 @@ npm install @decorators/socket --save ``` ### API #### Functions -* **bootstrapSocketIO(io: SocketIO.Server, Controllers)** - Attaches controllers to IO server -* **attachControllerToSocket(io: SocketIO.Server, socket: SocketIO.Socket, Controllers)** - Attaches controllers to Socket +* **attachControllers(io: SocketIO.Server, Controller[] || Injectable[])** - Attaches controllers to IO server +* **attachControllersToSocket(io: SocketIO.Server, socket: SocketIO.Socket, Controller[] || Injectable[])** - Attaches controllers to Socket +where Injectable: +```typescript +{ provide: UserController, deps: [UserService] } +``` + +* **bootstrapSocketIO(io: SocketIO.Server, Controllers)** - Attaches controllers to IO server - **_[deprecated, use attachControllers - will be removed in v2.0.0 of this library]_** +* **attachControllerToSocket(io: SocketIO.Server, socket: SocketIO.Socket, Controllers)** - Attaches controllers to Socket - **_[deprecated, use attachControllersToSocket - will be removed in v2.0.0 of this library]_** #### Decorators ##### Class diff --git a/socket/index.ts b/socket/index.ts index 8420b10..befc343 100644 --- a/socket/index.ts +++ b/socket/index.ts @@ -1 +1,19 @@ -export * from './src'; +export { + Namespace, + ServerMiddleware, + GlobalMiddleware, + Middleware, + Connection, + Disconnect, + GlobalEvent, + Event, + IO, + Socket, + Args, + Callback, + attachControllers, + attachControllersToSocket +} from './src'; + +/** @deprecated */ +export { bootstrapSocketIO, attachControllerToSocket } from './src'; diff --git a/socket/package.json b/socket/package.json index bbb9093..00bf29b 100644 --- a/socket/package.json +++ b/socket/package.json @@ -1,6 +1,6 @@ { "name": "@decorators/socket", - "version": "1.3.3", + "version": "1.4.0", "description": "node decorators", "main": "index.js", "dependencies": { diff --git a/socket/src/decorators/class.ts b/socket/src/decorators/class.ts index 2cf8b3c..5383773 100644 --- a/socket/src/decorators/class.ts +++ b/socket/src/decorators/class.ts @@ -1,3 +1,4 @@ +import { SocketIOMeta } from '../interface'; import { getMeta } from '../meta'; /** diff --git a/socket/src/decorators/index.ts b/socket/src/decorators/index.ts index aa7d639..2ec076c 100644 --- a/socket/src/decorators/index.ts +++ b/socket/src/decorators/index.ts @@ -1,3 +1,3 @@ -export * from './class'; -export * from './property'; -export * from './param'; +export { Namespace, ServerMiddleware, GlobalMiddleware, Middleware } from './class'; +export { Connection, Disconnect, GlobalEvent, Event } from './property'; +export { IO, Socket, Args, Callback } from './param'; diff --git a/socket/src/decorators/param.ts b/socket/src/decorators/param.ts index ffa813a..9c04cdb 100644 --- a/socket/src/decorators/param.ts +++ b/socket/src/decorators/param.ts @@ -1,5 +1,5 @@ +import { ParameterType, SocketIOClass, ParameterConfiguration } from '../interface'; import { getMeta } from '../meta'; -import { ParameterType } from '../interface'; /** * Add parameter to metadata @@ -22,7 +22,7 @@ function addParameterMeta(target: SocketIOClass, propertyKey: string | symbol, c */ function parameterDecoratorFactory(parameterType: ParameterType): () => ParameterDecorator { return function(): ParameterDecorator { - return function (target: SocketIOClass, propertyKey: string | symbol, index: number) { + return function(target: SocketIOClass, propertyKey: string | symbol, index: number) { addParameterMeta(target, propertyKey, {index, type: parameterType}); }; }; @@ -40,7 +40,7 @@ export const IO = parameterDecoratorFactory(ParameterType.IO); * @type { (WrapperClass?: any) => ParameterDecorator } */ export const Socket = function(WrapperClass?: any): ParameterDecorator { - return function (target: SocketIOClass, propertyKey: string | symbol, index: number) { + return function(target: SocketIOClass, propertyKey: string | symbol, index: number) { addParameterMeta(target, propertyKey, { index, type: ParameterType.Socket, data: WrapperClass }); diff --git a/socket/src/decorators/property.ts b/socket/src/decorators/property.ts index 7457884..e512549 100644 --- a/socket/src/decorators/property.ts +++ b/socket/src/decorators/property.ts @@ -1,3 +1,4 @@ +import { SocketIOClass, SocketIOMeta } from '../interface'; import { getMeta } from '../meta'; /** diff --git a/socket/src/index.ts b/socket/src/index.ts index b5165eb..116ec7c 100644 --- a/socket/src/index.ts +++ b/socket/src/index.ts @@ -1,2 +1,18 @@ -export * from './decorators'; +export { + Namespace, + ServerMiddleware, + GlobalMiddleware, + Middleware, + Connection, + Disconnect, + GlobalEvent, + Event, + IO, + Socket, + Args, + Callback +} from './decorators'; +export { attachControllers, attachControllersToSocket } from './socket'; + +/** @deprecated */ export { bootstrapSocketIO, attachControllerToSocket } from './socket'; diff --git a/socket/src/interface.ts b/socket/src/interface.ts index 471452a..112e3e8 100644 --- a/socket/src/interface.ts +++ b/socket/src/interface.ts @@ -1,3 +1,14 @@ +export interface ParameterConfiguration { + index: number; + type: any; + name?: string; + data?: any; +} + +export interface Params { + [key: string]: ParameterConfiguration[]; +} + /** * Parameter types enum */ @@ -7,3 +18,40 @@ export enum ParameterType { Args, Callback } + +export interface Listener { + [key: string]: { + event: string; + middleware: Function[]; + }; +} + +export interface SocketIOMeta { + serverOrPort: any; + options: any; + namespace: string; + + middleware: { + io: Function[]; + socket: Function[]; + controller: Function[]; + } + + listeners: { + all: string[], + io: Listener; + socket: Listener; + }; + + params: Params; +} + +export interface Injectable { + provide: Function; + deps: any[]; +} +export interface SocketIOClass extends Object { + __meta__: SocketIOMeta; + + new (...deps: any[]); +} diff --git a/socket/src/meta.ts b/socket/src/meta.ts index 3f71b69..c616de1 100644 --- a/socket/src/meta.ts +++ b/socket/src/meta.ts @@ -1,3 +1,5 @@ +import { SocketIOClass, SocketIOMeta } from './interface'; + /** * Get or initiate metadata on target * @param target diff --git a/socket/src/socket.ts b/socket/src/socket.ts index 0387e6d..b804787 100644 --- a/socket/src/socket.ts +++ b/socket/src/socket.ts @@ -1,4 +1,12 @@ -import { ParameterType } from './interface'; +import { + ParameterType, + Listener, + SocketIOMeta, + Injectable, + SocketIOClass, + ParameterConfiguration, + Params +} from './interface'; /** * Dummy function to ensure, that callback exists @@ -53,9 +61,9 @@ function extractParameters( * loop through all params and put them into correct order */ for (let item of params) { - switch(item.type) { + switch (item.type) { + default: args[item.index] = getSocket(item, socket); break; // socket case ParameterType.IO: args[item.index] = io; break; - case ParameterType.Socket: args[item.index] = getSocket(item, socket); break; case ParameterType.Args: args[item.index] = eventArgs.pop(); break; case ParameterType.Callback: args[item.index] = callback || noop; break; } @@ -93,7 +101,7 @@ function applyListeners( (socket || io).on(listeners[listener].event, (...args) => { let handlerArgs = extractParameters(io, (socket || args[0]), params[listener], args); - return controller[listener].apply(controller, handlerArgs) + return controller[listener].apply(controller, handlerArgs); }); } } @@ -101,14 +109,16 @@ function applyListeners( /** * Get artifacts, instantiates controller and extract meta data * @param Controller + * @param deps * @returns { {controller, meta: SocketIOMeta, listeners: {io: Listener, socket: Listener}, params: Params} } */ -function getArtifacts(Controller) { - const controller = new Controller(), - meta: SocketIOMeta = controller.__meta__, - namespace: string = meta.namespace, - listeners = meta.listeners, - params = meta.params; +function getArtifacts(Controller, deps) { + const controller = new Controller(...deps); + const meta: SocketIOMeta = controller.__meta__; + const namespace: string = meta.namespace; + const listeners = meta.listeners; + const params = meta.params; + return { controller, meta, listeners, params, namespace }; } @@ -123,7 +133,7 @@ function _attachControllerToSocket(io, socket, artifacts) { * Apply all registered middleware to socket */ artifacts.meta.middleware.socket.forEach(middleware => { - (socket).use((...args) =>middleware.apply(middleware, [io, socket, ...args])); + (socket).use((...args) => middleware.apply(middleware, [io, socket, ...args])); }); /** @@ -132,7 +142,7 @@ function _attachControllerToSocket(io, socket, artifacts) { artifacts.meta.middleware.controller.forEach(middleware => { (socket).use((packet, next) => { if (artifacts.meta.listeners.all.indexOf(packet[0]) !== -1) { - return middleware.apply(middleware, [io, socket, packet, next]) + return middleware.apply(middleware, [io, socket, packet, next]); } next(); }); @@ -155,9 +165,9 @@ function _attachControllerToSocket(io, socket, artifacts) { * @param io * @param Controller */ -function attachController(io: SocketIO.Server, Controller) { - const artifacts = getArtifacts(Controller), - _io: SocketIO.Namespace = io.of(artifacts.namespace); +function attachController(io: SocketIO.Server, Controller, deps) { + const artifacts = getArtifacts(Controller, deps); + const _io: SocketIO.Namespace = io.of(artifacts.namespace); /** * Apply all registered global middleware to io @@ -180,12 +190,16 @@ function attachController(io: SocketIO.Server, Controller) { /** * Attaches controllers to IO server * @param {SocketIO.Server} io - * @param {Object[]} Controllers + * @param {Array} injectables */ -export function bootstrapSocketIO(io: SocketIO.Server, Controllers: any[]) { - Controllers.forEach(Controller => { - attachController(io, Controller); - }); +export function attachControllers(io: SocketIO.Server, injectables: Array) { + injectables + .forEach((injectable: Injectable | SocketIOClass) => { + const controller = (injectable).provide || injectable; + const deps = (injectable).deps || []; + + attachController(io, controller, deps); + }); } /** @@ -193,14 +207,32 @@ export function bootstrapSocketIO(io: SocketIO.Server, Controllers: any[]) { * With this approach you can't define global middleware, it's up to you. * @param {SocketIO.Server} io * @param {SocketIO.Socket} socket - * @param Controllers + * @param {Array} injectables */ -export function attachControllerToSocket( +export function attachControllersToSocket( io: SocketIO.Server, socket: SocketIO.Socket, - Controllers + injectables: Array ) { - Controllers.forEach(Controller => { - _attachControllerToSocket(io, socket, getArtifacts(Controller)); - }); + injectables + .forEach((injectable: Injectable | SocketIOClass) => { + const controller = (injectable).provide || injectable; + const deps = (injectable).deps || []; + + _attachControllerToSocket(io, socket, getArtifacts(controller, deps)); + }); } + +/** + * @alias + * @see attachControllers + * @deprecated + */ +export let bootstrapSocketIO = attachControllers; + +/** + * @alias + * @see attachControllersToSocket + * @deprecated + */ +export let attachControllerToSocket = attachControllersToSocket; diff --git a/types/base.d.ts b/types/base.d.ts deleted file mode 100644 index b4cea45..0000000 --- a/types/base.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -interface ParameterConfiguration { - index: number; - type: any; - name?: string; - data?: any; -} - -interface Params { - [key: string]: ParameterConfiguration[]; -} diff --git a/types/socket.d.ts b/types/socket.d.ts deleted file mode 100644 index 83650e4..0000000 --- a/types/socket.d.ts +++ /dev/null @@ -1,30 +0,0 @@ -interface Listener { - [key: string]: { - event: string; - middleware: Function[]; - }; -} - -interface SocketIOMeta { - serverOrPort: any; - options: any; - namespace: string; - - middleware: { - io: Function[]; - socket: Function[]; - controller: Function[]; - } - - listeners: { - all: string[], - io: Listener; - socket: Listener; - }; - - params: Params; -} - -interface SocketIOClass extends Object { - __meta__: SocketIOMeta; -}