@wabot-dev/framework 0.2.0-beta.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/src/addon/auth/api-key/@apiKeyHandshakeGuard.js +16 -0
  2. package/dist/src/addon/auth/api-key/{ApiKeyConnectionGuardMiddleware.js → ApiKeyHandshakeGuardMiddleware.js} +4 -4
  3. package/dist/src/addon/auth/jwt/@jwtHandshakeGuard.js +16 -0
  4. package/dist/src/addon/auth/jwt/{JwtConnectionGuardMiddleware.js → JwtHandshakeGuardMiddleware.js} +4 -4
  5. package/dist/src/addon/chat-bot/anthropic/AnthropicChatAdapter.js +18 -20
  6. package/dist/src/addon/chat-bot/deepseek/DeepSeekChatAdapter.js +2 -2
  7. package/dist/src/addon/chat-bot/google/GoogleChatAdapter.js +81 -70
  8. package/dist/src/addon/chat-bot/openia/OpenaiChatAdapter.js +43 -19
  9. package/dist/src/addon/chat-bot/wabot/WabotChatAdapter.js +1 -1
  10. package/dist/src/addon/chat-controller/cmd/CmdChannel.js +17 -10
  11. package/dist/src/addon/chat-controller/socket/@socket.js +1 -1
  12. package/dist/src/addon/chat-controller/socket/SocketChannel.js +74 -33
  13. package/dist/src/addon/chat-controller/socket/SocketChannelConfig.js +6 -4
  14. package/dist/src/core/auth/Auth.js +6 -0
  15. package/dist/src/feature/chat-bot/ChatAdapter.js +1 -1
  16. package/dist/src/feature/chat-bot/ChatBot.js +14 -10
  17. package/dist/src/feature/chat-controller/runChatControllers.js +6 -7
  18. package/dist/src/feature/rest-controller/runRestControllers.js +1 -1
  19. package/dist/src/feature/socket-controller/metadata/@handshakeMiddlewares.js +16 -0
  20. package/dist/src/feature/socket-controller/metadata/{@socketEvent.js → @onSocketEvent.js} +2 -2
  21. package/dist/src/feature/socket-controller/metadata/SocketControllerMetadataStore.js +12 -34
  22. package/dist/src/feature/socket-controller/runSocketControllers.js +96 -77
  23. package/dist/src/index.d.ts +50 -61
  24. package/dist/src/index.js +7 -8
  25. package/package.json +5 -6
  26. package/dist/src/addon/auth/api-key/@apiKeyConnectionGuard.js +0 -16
  27. package/dist/src/addon/auth/jwt/@jwtConnectionGuard.js +0 -16
  28. package/dist/src/feature/socket-controller/metadata/@connectionMiddleware.js +0 -16
  29. package/dist/src/feature/socket-controller/metadata/@socketConnection.js +0 -18
@@ -1,65 +1,106 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { injectable } from '../../../core/injection/index.js';
3
- import { SocketServerProvider } from '../../../feature/socket/SocketServerProvider.js';
3
+ import { handshakeMiddlewares } from '../../../feature/socket-controller/metadata/@handshakeMiddlewares.js';
4
+ import { socketController } from '../../../feature/socket-controller/metadata/@socketController.js';
5
+ import { onSocketEvent } from '../../../feature/socket-controller/metadata/@onSocketEvent.js';
6
+ import '../../../feature/socket-controller/metadata/SocketControllerMetadataStore.js';
7
+ import { runSocketControllers } from '../../../feature/socket-controller/runSocketControllers.js';
8
+ import { Socket } from 'socket.io';
4
9
  import { SocketChannelConfig } from './SocketChannelConfig.js';
10
+ import '../../../core/validation/metadata/ValidationMetadataStore.js';
11
+ import { isNotEmpty } from '../../../core/validation/validators/is-not-empty/@isNotEmpty.js';
12
+ import { isString } from '../../../core/validation/validators/is-string/@isString.js';
13
+ import { Auth } from '../../../core/auth/Auth.js';
5
14
 
6
15
  var SocketChannel_1;
16
+ class SocketChannelReceivedMessage {
17
+ chatId;
18
+ senderName;
19
+ text;
20
+ }
21
+ __decorate([
22
+ isString(),
23
+ isNotEmpty(),
24
+ __metadata("design:type", String)
25
+ ], SocketChannelReceivedMessage.prototype, "chatId", void 0);
26
+ __decorate([
27
+ isString(),
28
+ isNotEmpty(),
29
+ __metadata("design:type", String)
30
+ ], SocketChannelReceivedMessage.prototype, "senderName", void 0);
31
+ __decorate([
32
+ isString(),
33
+ isNotEmpty(),
34
+ __metadata("design:type", String)
35
+ ], SocketChannelReceivedMessage.prototype, "text", void 0);
7
36
  let SocketChannel = SocketChannel_1 = class SocketChannel {
8
37
  config;
9
- socketServerProvider;
10
38
  callBack = null;
11
- server;
12
- constructor(config, socketServerProvider) {
39
+ controller = null;
40
+ constructor(config) {
13
41
  this.config = config;
14
- this.socketServerProvider = socketServerProvider;
15
- this.server = this.socketServerProvider.getSocketServer();
42
+ this.configController();
16
43
  }
17
- listen(callback) {
18
- this.callBack = callback;
19
- }
20
- connect() {
21
- this.server.on('connection', (socket) => {
22
- socket.on(this.config.channel, async (message) => {
44
+ configController() {
45
+ const channel = this;
46
+ let SocketChannelController = class SocketChannelController {
47
+ auth;
48
+ constructor(auth) {
49
+ this.auth = auth;
50
+ }
51
+ onMessage(message, socket) {
52
+ if (!channel.callBack)
53
+ return;
23
54
  const trimmedInput = message.text.trim();
24
55
  if (!trimmedInput) {
25
56
  return;
26
57
  }
27
- if (!message.chatId || !message.userId || !message.senderName) {
28
- socket.emit(this.config.channel, {
29
- error: 'Invalid message format. chatId, userId, and senderName are required.',
30
- });
31
- return;
32
- }
33
58
  const chatConnection = {
34
59
  id: message.chatId,
35
60
  chatType: 'PRIVATE',
36
61
  channelName: SocketChannel_1.name,
37
62
  };
38
- if (!this.callBack)
39
- return;
40
- this.callBack({
63
+ channel.callBack({
41
64
  chatConnection,
42
65
  message: {
43
- text: trimmedInput,
66
+ text: message.text,
44
67
  senderName: message.senderName,
45
68
  },
46
69
  reply: (message) => {
47
- socket.emit(this.config.channel, message);
48
- },
49
- authInfo: socket.data.authInfo,
50
- setAuthInfo: (authInfo) => {
51
- socket.data.authInfo = authInfo;
70
+ socket.emit('message', message);
52
71
  },
72
+ injectInstances: [
73
+ [Socket, socket],
74
+ [Auth, this.auth],
75
+ ],
53
76
  });
54
- });
55
- });
56
- this.socketServerProvider.listen();
77
+ }
78
+ };
79
+ __decorate([
80
+ onSocketEvent('message'),
81
+ __metadata("design:type", Function),
82
+ __metadata("design:paramtypes", [SocketChannelReceivedMessage, Socket]),
83
+ __metadata("design:returntype", void 0)
84
+ ], SocketChannelController.prototype, "onMessage", null);
85
+ SocketChannelController = __decorate([
86
+ socketController(channel.config.namespace),
87
+ handshakeMiddlewares(channel.config.handshakeMidlewares ?? []),
88
+ __metadata("design:paramtypes", [Auth])
89
+ ], SocketChannelController);
90
+ this.controller = SocketChannelController;
91
+ }
92
+ listen(callback) {
93
+ this.callBack = callback;
94
+ }
95
+ connect() {
96
+ if (!this.controller)
97
+ return;
98
+ runSocketControllers([this.controller]);
57
99
  }
58
100
  };
59
101
  SocketChannel = SocketChannel_1 = __decorate([
60
102
  injectable(),
61
- __metadata("design:paramtypes", [SocketChannelConfig,
62
- SocketServerProvider])
103
+ __metadata("design:paramtypes", [SocketChannelConfig])
63
104
  ], SocketChannel);
64
105
 
65
- export { SocketChannel };
106
+ export { SocketChannel, SocketChannelReceivedMessage };
@@ -2,14 +2,16 @@ import { __decorate, __metadata } from 'tslib';
2
2
  import { injectable } from '../../../core/injection/index.js';
3
3
 
4
4
  let SocketChannelConfig = class SocketChannelConfig {
5
- channel;
6
- constructor(channel) {
7
- this.channel = channel;
5
+ namespace;
6
+ handshakeMidlewares;
7
+ constructor(namespace, handshakeMidlewares) {
8
+ this.namespace = namespace;
9
+ this.handshakeMidlewares = handshakeMidlewares;
8
10
  }
9
11
  };
10
12
  SocketChannelConfig = __decorate([
11
13
  injectable(),
12
- __metadata("design:paramtypes", [String])
14
+ __metadata("design:paramtypes", [String, Array])
13
15
  ], SocketChannelConfig);
14
16
 
15
17
  export { SocketChannelConfig };
@@ -4,6 +4,7 @@ import { scoped, Lifecycle } from '../injection/index.js';
4
4
 
5
5
  let Auth = class Auth {
6
6
  authInfo = null;
7
+ overrided = false;
7
8
  require() {
8
9
  if (!this.authInfo) {
9
10
  throw new CustomError({ message: 'Unauthorized', httpCode: 401 });
@@ -18,13 +19,18 @@ let Auth = class Auth {
18
19
  }
19
20
  override(authInfo) {
20
21
  this.authInfo = authInfo;
22
+ this.overrided = true;
21
23
  }
22
24
  clear() {
23
25
  this.authInfo = null;
26
+ this.overrided = true;
24
27
  }
25
28
  isAssigned() {
26
29
  return this.authInfo !== null;
27
30
  }
31
+ wasOverrided() {
32
+ return this.overrided;
33
+ }
28
34
  };
29
35
  Auth = __decorate([
30
36
  scoped(Lifecycle.ContainerScoped)
@@ -1,5 +1,5 @@
1
1
  class ChatAdapter {
2
- nextItem(req) {
2
+ nextItems(req) {
3
3
  throw new Error('Method not implemented.');
4
4
  }
5
5
  }
@@ -41,23 +41,27 @@ let ChatBot = class ChatBot {
41
41
  throw new Error(`Invalid ${this.mindset.constructor.name} - llms not found`);
42
42
  }
43
43
  const llm = llms[0];
44
- const { chatItem: newItemData } = await this.adapter.nextItem({
44
+ const { nextItems: newItemsData } = await this.adapter.nextItems({
45
45
  model: llm.model,
46
46
  provider: llm.provider,
47
47
  systemPrompt,
48
48
  tools,
49
49
  prevItems: prevItems.map((x) => x.getData()),
50
50
  });
51
- if (newItemData.type === 'functionCall') {
52
- newItemData.functionCall.result = await this.mindset.callFunction(newItemData.functionCall.name, newItemData.functionCall.arguments ?? '{}');
51
+ for (const newItemData of newItemsData) {
52
+ if (newItemData.type === 'functionCall') {
53
+ newItemData.functionCall.result = await this.mindset.callFunction(newItemData.functionCall.name, newItemData.functionCall.arguments ?? '{}');
54
+ }
55
+ else if (newItemData.type === 'botMessage') {
56
+ newItemData.botMessage.senderName = identity.name;
57
+ }
58
+ const newChatItem = new ChatItem(newItemData);
59
+ await this.memory.create(newChatItem);
60
+ if (newItemData.type === 'botMessage') {
61
+ callback(newChatItem.botMessage);
62
+ }
53
63
  }
54
- else if (newItemData.type === 'botMessage') {
55
- newItemData.botMessage.senderName = identity.name;
56
- }
57
- const newChatItem = new ChatItem(newItemData);
58
- await this.memory.create(newChatItem);
59
- if (newChatItem.type === 'botMessage') {
60
- callback(newChatItem.botMessage);
64
+ if (newItemsData.length == 0 || newItemsData[newItemsData.length - 1].type === 'botMessage') {
61
65
  return;
62
66
  }
63
67
  this.processLoop(callback);
@@ -62,16 +62,15 @@ function runChatControllers(controllers) {
62
62
  chat,
63
63
  ...channelMessage,
64
64
  });
65
+ if (channelMessage.injectInstances) {
66
+ for (const [token, instance] of channelMessage.injectInstances) {
67
+ chatContainer.registerInstance(token, instance);
68
+ }
69
+ }
65
70
  const chatController = chatContainer.resolve(channelMetadata.controllerConstructor);
66
71
  const receivedMessage = {
67
72
  message: channelMessage.message,
68
- reply: (message) => {
69
- channelMessage.reply(message);
70
- if (channelMessage.setAuthInfo) {
71
- const auth = chatContainer.resolve(Auth);
72
- channelMessage.setAuthInfo(auth['authInfo'] || undefined);
73
- }
74
- },
73
+ reply: channelMessage.reply,
75
74
  };
76
75
  chatController[channelMetadata.functionName](receivedMessage);
77
76
  });
@@ -59,7 +59,7 @@ function runRestControllers(controllers) {
59
59
  }
60
60
  }
61
61
  const response = await controllerInstance[endPoint.functionName].apply(controllerInstance, endPointArgs);
62
- res.status(200).json(response);
62
+ res.status(200).json(response ?? null);
63
63
  }
64
64
  catch (err) {
65
65
  logger.error(err);
@@ -0,0 +1,16 @@
1
+ import { SocketControllerMetadataStore } from './SocketControllerMetadataStore.js';
2
+ import { container } from '../../../core/injection/index.js';
3
+
4
+ function handshakeMiddlewares(middlewares) {
5
+ return function (target) {
6
+ const store = container.resolve(SocketControllerMetadataStore);
7
+ for (const mw of middlewares) {
8
+ store.saveHandshakeMiddlewareMetadata({
9
+ controllerConstructor: target,
10
+ middlewareConstructor: mw,
11
+ });
12
+ }
13
+ };
14
+ }
15
+
16
+ export { handshakeMiddlewares };
@@ -1,7 +1,7 @@
1
1
  import { container } from '../../../core/injection/index.js';
2
2
  import { SocketControllerMetadataStore } from './SocketControllerMetadataStore.js';
3
3
 
4
- function socketEvent(config) {
4
+ function onSocketEvent(config) {
5
5
  return function (target, propertyKey) {
6
6
  const functionName = propertyKey.toString();
7
7
  const paramsTypes = Reflect.getMetadata('design:paramtypes', target, functionName);
@@ -15,4 +15,4 @@ function socketEvent(config) {
15
15
  };
16
16
  }
17
17
 
18
- export { socketEvent };
18
+ export { onSocketEvent };
@@ -3,19 +3,11 @@ import { singleton } from '../../../core/injection/index.js';
3
3
 
4
4
  let SocketControllerMetadataStore = class SocketControllerMetadataStore {
5
5
  socketControllers = new Map();
6
- socketConnections = new Map();
7
6
  socketEvents = new Map();
8
- connectionMiddlewares = new Map();
7
+ handshakeMiddlewares = new Map();
9
8
  saveControllerMetadata(controllerMetadata) {
10
9
  this.socketControllers.set(controllerMetadata.controllerConstructor, controllerMetadata);
11
10
  }
12
- saveSocketConnectionMetadata(socketConnectionMetadata) {
13
- let controllerConnections = this.socketConnections.get(socketConnectionMetadata.controllerConstructor);
14
- if (!controllerConnections) {
15
- this.socketConnections.set(socketConnectionMetadata.controllerConstructor, (controllerConnections = new Map()));
16
- }
17
- controllerConnections.set(socketConnectionMetadata.functionName, socketConnectionMetadata);
18
- }
19
11
  saveSocketEventMetadata(socketEventMetadata) {
20
12
  let controllerEvents = this.socketEvents.get(socketEventMetadata.controllerConstructor);
21
13
  if (!controllerEvents) {
@@ -23,39 +15,25 @@ let SocketControllerMetadataStore = class SocketControllerMetadataStore {
23
15
  }
24
16
  controllerEvents.set(socketEventMetadata.functionName, socketEventMetadata);
25
17
  }
26
- saveConnectionMiddlewareMetadata(middlewareMetadata) {
27
- let controllerMiddlewares = this.connectionMiddlewares.get(middlewareMetadata.controllerConstructor);
18
+ saveHandshakeMiddlewareMetadata(handshakeMetadata) {
19
+ let controllerMiddlewares = this.handshakeMiddlewares.get(handshakeMetadata.controllerConstructor);
28
20
  if (!controllerMiddlewares) {
29
- this.connectionMiddlewares.set(middlewareMetadata.controllerConstructor, (controllerMiddlewares = new Map()));
21
+ this.handshakeMiddlewares.set(handshakeMetadata.controllerConstructor, (controllerMiddlewares = []));
30
22
  }
31
- let methodMiddlewares = controllerMiddlewares.get(middlewareMetadata.functionName);
32
- if (!methodMiddlewares) {
33
- controllerMiddlewares.set(middlewareMetadata.functionName, (methodMiddlewares = []));
34
- }
35
- methodMiddlewares.unshift(middlewareMetadata);
23
+ controllerMiddlewares.unshift(handshakeMetadata);
36
24
  }
37
- getControllerSockerConnectionsInfo(controllerConstructor) {
25
+ getSocketControllerInfo(controllerConstructor) {
38
26
  const controller = this.socketControllers.get(controllerConstructor);
39
27
  if (!controller) {
40
28
  throw new Error(`${controllerConstructor.name} should be decorated with @socketController`);
41
29
  }
42
- const connections = this.socketConnections.get(controllerConstructor);
30
+ const handShakeMiddlewares = this.handshakeMiddlewares.get(controllerConstructor);
43
31
  const events = this.socketEvents.get(controllerConstructor) ?? new Map();
44
- if (!connections?.size) {
45
- // TODO: Warning
46
- return [];
47
- }
48
- return [...connections.values()].map((connection) => ({
49
- ...connection,
50
- events: (() => {
51
- const connectionNamespace = connection.config?.namespace;
52
- return [...events.values()].filter((x) => x.config?.namespace === connectionNamespace);
53
- })(),
54
- connectionMiddlewares: this.connectionMiddlewares
55
- .get(connection.controllerConstructor)
56
- ?.get(connection.functionName) ?? [],
57
- controller: this.socketControllers.get(connection.controllerConstructor),
58
- }));
32
+ return {
33
+ controller,
34
+ events,
35
+ handShakeMiddlewares,
36
+ };
59
37
  }
60
38
  };
61
39
  SocketControllerMetadataStore = __decorate([
@@ -1,11 +1,11 @@
1
- import { SocketControllerMetadataStore } from './metadata/SocketControllerMetadataStore.js';
1
+ import { CustomError } from '../../core/error/CustomError.js';
2
2
  import { container } from '../../core/injection/index.js';
3
- import path__default from 'path';
4
3
  import { Logger } from '../../core/logger/Logger.js';
5
- import { SocketServerProvider } from '../socket/SocketServerProvider.js';
6
- import { CustomError } from '../../core/error/CustomError.js';
7
4
  import '../../core/validation/metadata/ValidationMetadataStore.js';
8
5
  import { validateAndTransform } from '../../core/validation/validateAndTransform.js';
6
+ import { Socket } from 'socket.io';
7
+ import { SocketServerProvider } from '../socket/SocketServerProvider.js';
8
+ import { SocketControllerMetadataStore } from './metadata/SocketControllerMetadataStore.js';
9
9
 
10
10
  function runSocketControllers(controllers) {
11
11
  const logger = new Logger('wabot:socket');
@@ -13,84 +13,103 @@ function runSocketControllers(controllers) {
13
13
  const socketServerProvider = container.resolve(SocketServerProvider);
14
14
  const socketServer = socketServerProvider.getSocketServer();
15
15
  controllers.forEach((controller) => {
16
- const connections = metadataStore.getControllerSockerConnectionsInfo(controller);
17
- connections.forEach((connection) => {
18
- const namespace = path__default
19
- .join(connection.controller.config?.namespace ?? '/', connection.config?.namespace ?? '')
20
- .replaceAll('\\', '/');
21
- logger.info(`config connection to ${namespace}`);
22
- const namespaceServer = socketServer.of(namespace);
23
- namespaceServer.use(async (socket, next) => {
24
- const connectionContainer = container.createChildContainer();
25
- try {
26
- const middlewares = connection.connectionMiddlewares.map((x) => connectionContainer.resolve(x.middlewareConstructor));
27
- for (const middleware of middlewares) {
28
- await middleware.handle(socket, connectionContainer);
29
- }
30
- socket.data.connectionContainer = connectionContainer;
31
- next();
16
+ const controllerInfo = metadataStore.getSocketControllerInfo(controller);
17
+ const namespace = `/${controllerInfo.controller.config?.namespace ?? ''}`;
18
+ logger.info(`config connection to ${namespace}`);
19
+ const namespaceServer = socketServer.of(namespace);
20
+ namespaceServer.use(async (socket, next) => {
21
+ const connectionContainer = container.createChildContainer();
22
+ try {
23
+ const middlewares = controllerInfo.handShakeMiddlewares?.map((x) => connectionContainer.resolve(x.middlewareConstructor)) ?? [];
24
+ for (const middleware of middlewares) {
25
+ await middleware.handle(socket, connectionContainer);
32
26
  }
33
- catch (err) {
34
- next(err);
35
- connectionContainer.dispose();
27
+ socket.data.connectionContainer = connectionContainer;
28
+ connectionContainer.registerInstance(Socket, socket);
29
+ next();
30
+ }
31
+ catch (err) {
32
+ next(err);
33
+ connectionContainer.dispose();
34
+ }
35
+ });
36
+ const eventListener = async (controllerInstance, socket, event, req, callback) => {
37
+ logger.trace(`received '${event.config.event}' event on '${namespace}'`);
38
+ const paramsValues = [];
39
+ try {
40
+ if (event.paramsTypes.length > 2) {
41
+ throw new CustomError({
42
+ httpCode: 400,
43
+ message: 'the socket event handler should have max 2 parameters: (req, socket)',
44
+ });
36
45
  }
37
- });
38
- namespaceServer.on('connection', async (socket) => {
39
- logger.trace(`connection on '${namespace}'`);
40
- const connectionContainer = socket.data.connectionContainer;
41
- try {
42
- const controllerInstance = connectionContainer.resolve(connection.controllerConstructor);
43
- connection.events.forEach((event) => {
44
- logger.trace(`config listener to '${event.config.event}' event on '${namespace}'`);
45
- socket.on(event.config.event, async (req, callback) => {
46
- logger.trace(`received '${event.config.event}' event on '${namespace}'`);
47
- try {
48
- const reqType = event.paramsTypes[0];
49
- if (typeof reqType !== 'function') {
50
- throw new CustomError({
51
- httpCode: 400,
52
- message: 'Unable to validate request',
53
- });
54
- }
55
- const { value, error } = validateAndTransform(req, reqType);
56
- if (error) {
57
- throw new CustomError({
58
- httpCode: 400,
59
- message: error.description,
60
- info: error,
61
- });
62
- }
63
- const out = await controllerInstance[event.functionName].apply(controllerInstance, [value, socket]);
64
- callback(out);
65
- }
66
- catch (err) {
67
- logger.error(err);
68
- if (err instanceof Error) {
69
- const keys = Object.keys(err).filter((key) => !['message', 'stack'].includes(key));
70
- const { httpCode, ...info } = keys.reduce((acc, key) => {
71
- acc[key] = err[key];
72
- return acc;
73
- }, {});
74
- if (typeof callback === 'function') {
75
- callback({ error: { ...info, message: err.message, stack: err.stack } });
76
- }
77
- }
78
- else {
79
- if (typeof callback === 'function') {
80
- callback({ error: { message: 'Unspected error' } });
81
- }
82
- }
83
- }
46
+ if (event.paramsTypes[0] !== Socket) {
47
+ const reqType = event.paramsTypes[0];
48
+ if (typeof reqType !== 'function') {
49
+ throw new CustomError({
50
+ httpCode: 400,
51
+ message: 'Unable to validate request',
84
52
  });
85
- });
86
- await controllerInstance[connection.functionName].apply(controllerInstance, [socket]);
53
+ }
54
+ const { value, error } = validateAndTransform(req, reqType);
55
+ if (error) {
56
+ throw new CustomError({
57
+ httpCode: 400,
58
+ message: error.description,
59
+ info: error,
60
+ });
61
+ }
62
+ paramsValues.push(value);
63
+ }
64
+ paramsValues.push(socket);
65
+ const out = await controllerInstance[event.functionName].apply(controllerInstance, paramsValues);
66
+ if (typeof callback === 'function') {
67
+ callback(out);
68
+ }
69
+ }
70
+ catch (err) {
71
+ logger.error(err);
72
+ if (err instanceof Error) {
73
+ const keys = Object.keys(err).filter((key) => !['message', 'stack'].includes(key));
74
+ const { httpCode, ...info } = keys.reduce((acc, key) => {
75
+ acc[key] = err[key];
76
+ return acc;
77
+ }, {});
78
+ if (typeof callback === 'function') {
79
+ callback({ error: { ...info, message: err.message, stack: err.stack } });
80
+ }
81
+ }
82
+ else {
83
+ if (typeof callback === 'function') {
84
+ callback({ error: { message: 'Unspected error' } });
85
+ }
87
86
  }
88
- catch (err) {
89
- logger.error(err);
90
- socket.disconnect();
91
- connectionContainer.dispose();
87
+ }
88
+ };
89
+ namespaceServer.on('connection', async (socket) => {
90
+ logger.trace(`connection on '${namespace}'`);
91
+ const connectionContainer = socket.data.connectionContainer;
92
+ try {
93
+ const controllerInstance = connectionContainer.resolve(controllerInfo.controller.controllerConstructor);
94
+ controllerInfo.events.forEach((event) => {
95
+ logger.trace(`config listener to '${event.config.event}' event on '${namespace}'`);
96
+ if (event.config.event === 'connection') {
97
+ return;
98
+ }
99
+ socket.on(event.config.event, async (req, callback) => {
100
+ await eventListener(controllerInstance, socket, event, req, callback);
101
+ });
102
+ });
103
+ const connectionEvent = controllerInfo.events.get('connection');
104
+ if (connectionEvent) {
105
+ await eventListener(controllerInstance, socket, connectionEvent, null, null);
92
106
  }
93
- });
107
+ }
108
+ catch (err) {
109
+ logger.error(err);
110
+ socket.disconnect();
111
+ connectionContainer.dispose();
112
+ }
94
113
  });
95
114
  });
96
115
  socketServerProvider.listen();