@wabot-dev/framework 0.5.0 → 0.5.2

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 (53) hide show
  1. package/dist/src/addon/auth/api-key/@apiKeyGuard.js +1 -0
  2. package/dist/src/addon/auth/api-key/@apiKeyHandshakeGuard.js +2 -0
  3. package/dist/src/addon/auth/api-key/ApiKey.js +1 -0
  4. package/dist/src/addon/auth/api-key/ApiKeyGuardMiddleware.js +1 -0
  5. package/dist/src/addon/auth/api-key/ApiKeyHandshakeGuardMiddleware.js +10 -2
  6. package/dist/src/addon/auth/api-key/PgApiKeyRepository.js +1 -0
  7. package/dist/src/addon/auth/api-key/RemoteApiKeyRepository.js +1 -0
  8. package/dist/src/addon/auth/jwt/@jwtGuard.js +1 -0
  9. package/dist/src/addon/auth/jwt/@jwtHandshakeGuard.js +2 -0
  10. package/dist/src/addon/auth/jwt/JwtGuardMiddleware.js +7 -2
  11. package/dist/src/addon/auth/jwt/JwtHandshakeGuardMiddleware.js +1 -0
  12. package/dist/src/addon/auth/jwt/JwtRefreshToken.js +1 -0
  13. package/dist/src/addon/auth/jwt/PgJwtRefreshTokenRepository.js +1 -0
  14. package/dist/src/addon/chat-bot/anthropic/AnthropicChatAdapter.js +6 -2
  15. package/dist/src/addon/chat-bot/google/GoogleChatAdapter.js +5 -1
  16. package/dist/src/addon/chat-bot/pg/PgChatMemory.js +1 -0
  17. package/dist/src/addon/chat-bot/pg/PgChatRepository.js +1 -0
  18. package/dist/src/addon/chat-bot/wabot/WabotChatAdapter.js +1 -0
  19. package/dist/src/addon/chat-controller/cmd/@cmd.js +1 -6
  20. package/dist/src/addon/chat-controller/cmd/CmdChannel.js +8 -0
  21. package/dist/src/addon/chat-controller/socket/@socket.js +1 -6
  22. package/dist/src/addon/chat-controller/socket/SocketChannel.js +3 -0
  23. package/dist/src/addon/chat-controller/telegram/@telegram.js +1 -6
  24. package/dist/src/addon/chat-controller/telegram/TelegramChannel.js +3 -0
  25. package/dist/src/addon/chat-controller/whatsapp/@whatsApp.js +1 -6
  26. package/dist/src/addon/chat-controller/whatsapp/WhatsAppChannel.js +3 -0
  27. package/dist/src/addon/chat-controller/whatsapp/WhatsAppReceiver.js +3 -0
  28. package/dist/src/addon/chat-controller/whatsapp/WhatsAppSender.js +1 -0
  29. package/dist/src/addon/chat-controller/whatsapp/cloud-api/WhatsAppSenderByCloudApi.js +2 -3
  30. package/dist/src/addon/chat-controller/whatsapp/proxy/WhatsAppSenderByWabotProxy.js +2 -3
  31. package/dist/src/core/auth/Auth.js +1 -0
  32. package/dist/src/core/entity/Entity.js +3 -0
  33. package/dist/src/core/error/setupErrorHandlers.js +33 -0
  34. package/dist/src/core/logger/Logger.js +66 -9
  35. package/dist/src/core/mapper/Mapper.js +1 -0
  36. package/dist/src/feature/async/Async.js +28 -4
  37. package/dist/src/feature/async/Job.js +1 -0
  38. package/dist/src/feature/async/JobExecutor.js +8 -1
  39. package/dist/src/feature/async/JobRunner.js +10 -6
  40. package/dist/src/feature/chat-bot/safeJsonParse.js +19 -0
  41. package/dist/src/feature/chat-controller/ChatResolver.js +36 -10
  42. package/dist/src/feature/chat-controller/runChatControllers.js +9 -1
  43. package/dist/src/feature/mindset/MindsetOperator.js +6 -1
  44. package/dist/src/feature/pg/PgCrudRepository.js +1 -0
  45. package/dist/src/feature/pg/PgLocker.js +1 -1
  46. package/dist/src/feature/pg/PgRepositoryBase.js +2 -2
  47. package/dist/src/feature/rest-controller/runRestControllers.js +1 -0
  48. package/dist/src/feature/socket/SocketServerConfig.js +25 -0
  49. package/dist/src/feature/socket/SocketServerProvider.js +15 -3
  50. package/dist/src/feature/socket-controller/runSocketControllers.js +2 -0
  51. package/dist/src/index.d.ts +90 -31
  52. package/dist/src/index.js +3 -0
  53. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  import '../../../core/injection/index.js';
2
2
  import '../../../feature/rest-controller/metadata/RestControllerMetadataStore.js';
3
3
  import { middleware } from '../../../feature/rest-controller/metadata/@middleware.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import 'debug';
5
6
  import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
7
  import '../../../feature/express/ExpressProvider.js';
@@ -1,9 +1,11 @@
1
1
  import { handshakeMiddlewares } from '../../../feature/socket-controller/metadata/@handshakeMiddlewares.js';
2
2
  import '../../../feature/socket-controller/metadata/SocketControllerMetadataStore.js';
3
3
  import '../../../core/injection/index.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import 'debug';
5
6
  import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
7
  import 'socket.io';
8
+ import '../../../feature/socket/SocketServerConfig.js';
7
9
  import '../../../feature/socket/SocketServerProvider.js';
8
10
  import { ApiKeyHandshakeGuardMiddleware } from './ApiKeyHandshakeGuardMiddleware.js';
9
11
 
@@ -1,5 +1,6 @@
1
1
  import { Entity } from '../../../core/entity/Entity.js';
2
2
  import { CustomError } from '../../../core/error/CustomError.js';
3
+ import '../../../core/error/setupErrorHandlers.js';
3
4
  import crypto from 'node:crypto';
4
5
 
5
6
  class ApiKey extends Entity {
@@ -2,6 +2,7 @@ import { __decorate, __metadata } from 'tslib';
2
2
  import { injectable } from '../../../core/injection/index.js';
3
3
  import { Auth } from '../../../core/auth/Auth.js';
4
4
  import { CustomError } from '../../../core/error/CustomError.js';
5
+ import '../../../core/error/setupErrorHandlers.js';
5
6
  import { ApiKeyRepository } from './ApiKeyRepository.js';
6
7
 
7
8
  let ApiKeyGuardMiddleware = class ApiKeyGuardMiddleware {
@@ -1,6 +1,7 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { Auth } from '../../../core/auth/Auth.js';
3
3
  import { CustomError } from '../../../core/error/CustomError.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import { injectable } from '../../../core/injection/index.js';
5
6
  import { ApiKeyRepository } from './ApiKeyRepository.js';
6
7
 
@@ -18,8 +19,15 @@ let ApiKeyHandshakeGuardMiddleware = class ApiKeyHandshakeGuardMiddleware {
18
19
  authorization = authorization[0];
19
20
  }
20
21
  if (authorization) {
21
- const [prefix, token] = authorization.split(' ');
22
- if (prefix.toLowerCase() !== 'api-key' || !token) {
22
+ const parts = authorization.split(' ');
23
+ if (parts.length !== 2) {
24
+ throw new CustomError({
25
+ httpCode: 401,
26
+ message: 'Authorization header must be: Api-Key <token>',
27
+ });
28
+ }
29
+ const [prefix, token] = parts;
30
+ if (prefix.toLowerCase() !== 'api-key') {
23
31
  throw new CustomError({
24
32
  httpCode: 401,
25
33
  message: 'Authorization should be an Api-Key',
@@ -8,6 +8,7 @@ import '../../../feature/pg/pgStorage.js';
8
8
  import { Pool } from 'pg';
9
9
  import { ApiKey } from './ApiKey.js';
10
10
  import { CustomError } from '../../../core/error/CustomError.js';
11
+ import '../../../core/error/setupErrorHandlers.js';
11
12
  import { singleton } from '../../../core/injection/index.js';
12
13
 
13
14
  let PgApiKeyRepository = class PgApiKeyRepository extends PgCrudRepository {
@@ -1,4 +1,5 @@
1
1
  import { CustomError } from '../../../core/error/CustomError.js';
2
+ import '../../../core/error/setupErrorHandlers.js';
2
3
 
3
4
  class RemoteApiKeyRepository {
4
5
  fetcher;
@@ -1,6 +1,7 @@
1
1
  import '../../../core/injection/index.js';
2
2
  import '../../../feature/rest-controller/metadata/RestControllerMetadataStore.js';
3
3
  import { middleware } from '../../../feature/rest-controller/metadata/@middleware.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import 'debug';
5
6
  import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
7
  import '../../../feature/express/ExpressProvider.js';
@@ -1,9 +1,11 @@
1
1
  import { handshakeMiddlewares } from '../../../feature/socket-controller/metadata/@handshakeMiddlewares.js';
2
2
  import '../../../feature/socket-controller/metadata/SocketControllerMetadataStore.js';
3
3
  import '../../../core/injection/index.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import 'debug';
5
6
  import '../../../core/validation/metadata/ValidationMetadataStore.js';
6
7
  import 'socket.io';
8
+ import '../../../feature/socket/SocketServerConfig.js';
7
9
  import '../../../feature/socket/SocketServerProvider.js';
8
10
  import { JwtHandshakeGuardMiddleware } from './JwtHandshakeGuardMiddleware.js';
9
11
 
@@ -1,5 +1,6 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { CustomError } from '../../../core/error/CustomError.js';
3
+ import '../../../core/error/setupErrorHandlers.js';
3
4
  import { injectable } from '../../../core/injection/index.js';
4
5
  import jwt from 'jsonwebtoken';
5
6
  import { Auth } from '../../../core/auth/Auth.js';
@@ -17,8 +18,12 @@ let JwtGuardMiddleware = class JwtGuardMiddleware {
17
18
  if (!authorization) {
18
19
  throw new CustomError({ httpCode: 401, message: 'Authorization header not available' });
19
20
  }
20
- const [bearer, token] = authorization.split(' ');
21
- if (bearer.toLowerCase() !== 'bearer' || !token) {
21
+ const parts = authorization.split(' ');
22
+ if (parts.length !== 2) {
23
+ throw new CustomError({ httpCode: 401, message: 'Authorization header must be: Bearer <token>' });
24
+ }
25
+ const [bearer, token] = parts;
26
+ if (bearer.toLowerCase() !== 'bearer') {
22
27
  throw new CustomError({ httpCode: 401, message: 'Authorization should be a bearer token' });
23
28
  }
24
29
  try {
@@ -3,6 +3,7 @@ import jwt from 'jsonwebtoken';
3
3
  import { injectable } from '../../../core/injection/index.js';
4
4
  import { Auth } from '../../../core/auth/Auth.js';
5
5
  import { CustomError } from '../../../core/error/CustomError.js';
6
+ import '../../../core/error/setupErrorHandlers.js';
6
7
  import { JwtConfig } from './JwtConfig.js';
7
8
 
8
9
  let JwtHandshakeGuardMiddleware = class JwtHandshakeGuardMiddleware {
@@ -1,5 +1,6 @@
1
1
  import { Entity } from '../../../core/entity/Entity.js';
2
2
  import { CustomError } from '../../../core/error/CustomError.js';
3
+ import '../../../core/error/setupErrorHandlers.js';
3
4
  import crypto from 'node:crypto';
4
5
 
5
6
  class JwtRefreshToken extends Entity {
@@ -1,6 +1,7 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { singleton } from '../../../core/injection/index.js';
3
3
  import { CustomError } from '../../../core/error/CustomError.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
5
6
  import '../../../feature/pg/PgLocker.js';
6
7
  import 'debug';
@@ -2,6 +2,10 @@ import { __decorate, __metadata } from 'tslib';
2
2
  import { Env } from '../../../core/env/Env.js';
3
3
  import { singleton } from '../../../core/injection/index.js';
4
4
  import { Logger } from '../../../core/logger/Logger.js';
5
+ import '../../../feature/chat-bot/ChatBot.js';
6
+ import 'uuid';
7
+ import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
8
+ import { safeJsonParse } from '../../../feature/chat-bot/safeJsonParse.js';
5
9
  import { Anthropic } from '@anthropic-ai/sdk';
6
10
 
7
11
  let AnthropicChatAdapter = class AnthropicChatAdapter {
@@ -23,7 +27,7 @@ let AnthropicChatAdapter = class AnthropicChatAdapter {
23
27
  messages,
24
28
  tools: tools.length > 0 ? tools : undefined,
25
29
  };
26
- this.logger.debug(`Call Claude API with Request: ${JSON.stringify(request)}`);
30
+ this.logger.debug(`Call Claude API with model: ${request.model}, messages: ${request.messages.length}, tools: ${request.tools?.length ?? 0}`);
27
31
  const response = await this.anthropic.messages.create(request);
28
32
  return this.mapResponse(response);
29
33
  }
@@ -65,7 +69,7 @@ let AnthropicChatAdapter = class AnthropicChatAdapter {
65
69
  type: 'tool_use',
66
70
  id: item.id,
67
71
  name: item.name,
68
- input: JSON.parse(item.arguments || '{}'),
72
+ input: safeJsonParse(item.arguments, 'function call arguments'),
69
73
  },
70
74
  ],
71
75
  },
@@ -3,6 +3,10 @@ import { Env } from '../../../core/env/Env.js';
3
3
  import { singleton } from '../../../core/injection/index.js';
4
4
  import { Logger } from '../../../core/logger/Logger.js';
5
5
  import { Random } from '../../../core/random/Random.js';
6
+ import '../../../feature/chat-bot/ChatBot.js';
7
+ import 'uuid';
8
+ import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
9
+ import { safeJsonParse } from '../../../feature/chat-bot/safeJsonParse.js';
6
10
  import { GoogleGenAI } from '@google/genai';
7
11
 
8
12
  let GoogleChatAdapter = class GoogleChatAdapter {
@@ -61,7 +65,7 @@ let GoogleChatAdapter = class GoogleChatAdapter {
61
65
  functionCall: {
62
66
  id: item.id,
63
67
  name: item.name,
64
- args: JSON.parse(item.arguments ?? '{}'),
68
+ args: safeJsonParse(item.arguments, 'function call arguments'),
65
69
  },
66
70
  },
67
71
  ],
@@ -9,6 +9,7 @@ import { ChatItem } from '../../../feature/chat-bot/ChatItem.js';
9
9
  import '../../../core/injection/index.js';
10
10
  import 'uuid';
11
11
  import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
12
+ import '../../../core/error/setupErrorHandlers.js';
12
13
 
13
14
  class PgChatMemory extends PgCrudRepository {
14
15
  chatId;
@@ -12,6 +12,7 @@ import { Chat } from '../../../feature/chat-bot/Chat.js';
12
12
  import '../../../feature/chat-bot/ChatBot.js';
13
13
  import 'uuid';
14
14
  import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
15
+ import '../../../core/error/setupErrorHandlers.js';
15
16
 
16
17
  let PgChatRepository = class PgChatRepository extends PgCrudRepository {
17
18
  constructor(pool) {
@@ -1,6 +1,7 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { Env } from '../../../core/env/Env.js';
3
3
  import { CustomError } from '../../../core/error/CustomError.js';
4
+ import '../../../core/error/setupErrorHandlers.js';
4
5
  import { singleton } from '../../../core/injection/index.js';
5
6
  import { Logger } from '../../../core/logger/Logger.js';
6
7
 
@@ -1,12 +1,7 @@
1
1
  import { container } from '../../../core/injection/index.js';
2
2
  import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
3
3
  import '../../../feature/chat-controller/ChatResolver.js';
4
- import '../../../core/auth/Auth.js';
5
- import '../../../feature/chat-bot/ChatBot.js';
6
- import 'uuid';
7
- import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
8
- import '../../../feature/mindset/metadata/MindsetMetadataStore.js';
9
- import '../../../feature/mindset/MindsetOperator.js';
4
+ import '../../../feature/chat-controller/runChatControllers.js';
10
5
  import { CmdChannel } from './CmdChannel.js';
11
6
 
12
7
  function cmd() {
@@ -1,5 +1,6 @@
1
1
  import { __decorate, __metadata } from 'tslib';
2
2
  import { injectable } from '../../../core/injection/index.js';
3
+ import { Logger } from '../../../core/logger/Logger.js';
3
4
  import * as readline from 'readline';
4
5
  import * as fs from 'fs';
5
6
  import * as path from 'path';
@@ -23,6 +24,11 @@ let CmdChannel = CmdChannel_1 = class CmdChannel {
23
24
  listen(callback) {
24
25
  this.callBack = callback;
25
26
  }
27
+ disconnect() {
28
+ this.rl.removeAllListeners('line');
29
+ this.rl.close();
30
+ this.callBack = null;
31
+ }
26
32
  connect() {
27
33
  this.rl.on('line', async (input) => {
28
34
  const trimmedInput = input.trim();
@@ -81,6 +87,7 @@ function writeJsonToFile(filename, data) {
81
87
  fs.mkdirSync(dir, { recursive: true });
82
88
  fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
83
89
  }
90
+ const fileLogger = new Logger('wabot:cmd-channel');
84
91
  function readJsonFromFile(filename) {
85
92
  const filePath = path.resolve(process.cwd(), filename);
86
93
  if (!fs.existsSync(filePath)) {
@@ -91,6 +98,7 @@ function readJsonFromFile(filename) {
91
98
  return JSON.parse(jsonData);
92
99
  }
93
100
  catch (err) {
101
+ fileLogger.warn(`Failed to parse JSON from ${filename}:`, err);
94
102
  return null;
95
103
  }
96
104
  }
@@ -1,12 +1,7 @@
1
1
  import { container } from '../../../core/injection/index.js';
2
2
  import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
3
3
  import '../../../feature/chat-controller/ChatResolver.js';
4
- import '../../../core/auth/Auth.js';
5
- import '../../../feature/chat-bot/ChatBot.js';
6
- import 'uuid';
7
- import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
8
- import '../../../feature/mindset/metadata/MindsetMetadataStore.js';
9
- import '../../../feature/mindset/MindsetOperator.js';
4
+ import '../../../feature/chat-controller/runChatControllers.js';
10
5
  import { SocketChannel } from './SocketChannel.js';
11
6
  import { SocketChannelConfig } from './SocketChannelConfig.js';
12
7
 
@@ -97,6 +97,9 @@ let SocketChannel = SocketChannel_1 = class SocketChannel {
97
97
  return;
98
98
  runSocketControllers([this.controller]);
99
99
  }
100
+ disconnect() {
101
+ this.callBack = null;
102
+ }
100
103
  };
101
104
  SocketChannel = SocketChannel_1 = __decorate([
102
105
  injectable(),
@@ -1,12 +1,7 @@
1
1
  import { container } from '../../../core/injection/index.js';
2
2
  import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
3
3
  import '../../../feature/chat-controller/ChatResolver.js';
4
- import '../../../core/auth/Auth.js';
5
- import '../../../feature/chat-bot/ChatBot.js';
6
- import 'uuid';
7
- import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
8
- import '../../../feature/mindset/metadata/MindsetMetadataStore.js';
9
- import '../../../feature/mindset/MindsetOperator.js';
4
+ import '../../../feature/chat-controller/runChatControllers.js';
10
5
  import { TelegramChannel } from './TelegramChannel.js';
11
6
  import { TelegramChannelConfig } from './TelegramChannelConfig.js';
12
7
 
@@ -38,6 +38,9 @@ let TelegramChannel = TelegramChannel_1 = class TelegramChannel {
38
38
  connect() {
39
39
  this.bot.start();
40
40
  }
41
+ disconnect() {
42
+ this.bot.stop();
43
+ }
41
44
  };
42
45
  TelegramChannel = TelegramChannel_1 = __decorate([
43
46
  injectable(),
@@ -2,12 +2,7 @@ import { container } from '../../../core/injection/index.js';
2
2
  import { WhatsappChannelConfig } from './WhatsAppChannelConfig.js';
3
3
  import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
4
4
  import '../../../feature/chat-controller/ChatResolver.js';
5
- import '../../../core/auth/Auth.js';
6
- import '../../../feature/chat-bot/ChatBot.js';
7
- import 'uuid';
8
- import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
9
- import '../../../feature/mindset/metadata/MindsetMetadataStore.js';
10
- import '../../../feature/mindset/MindsetOperator.js';
5
+ import '../../../feature/chat-controller/runChatControllers.js';
11
6
  import { WhatsAppChannel } from './WhatsAppChannel.js';
12
7
 
13
8
  function whatsApp(config) {
@@ -41,6 +41,9 @@ let WhatsAppChannel = class WhatsAppChannel {
41
41
  connect() {
42
42
  this.receiver.connect();
43
43
  }
44
+ disconnect() {
45
+ this.receiver.disconnect();
46
+ }
44
47
  };
45
48
  WhatsAppChannel = __decorate([
46
49
  injectable(),
@@ -2,6 +2,9 @@ class WhatsAppReceiver {
2
2
  connect() {
3
3
  throw new Error('Not Implemented');
4
4
  }
5
+ disconnect() {
6
+ throw new Error('Not Implemented');
7
+ }
5
8
  listenMessage(request) {
6
9
  throw new Error('Not Implemented');
7
10
  }
@@ -3,6 +3,7 @@ import { ChatItem } from '../../../feature/chat-bot/ChatItem.js';
3
3
  import '../../../core/injection/index.js';
4
4
  import 'uuid';
5
5
  import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
6
+ import '../../../core/error/setupErrorHandlers.js';
6
7
 
7
8
  class WhatsAppSender {
8
9
  chatRepository;
@@ -4,13 +4,12 @@ import { WhatsAppSender } from '../WhatsAppSender.js';
4
4
  import { singleton } from '../../../../core/injection/index.js';
5
5
  import '../../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
6
6
  import { ChatResolver } from '../../../../feature/chat-controller/ChatResolver.js';
7
- import '../../../../core/auth/Auth.js';
7
+ import '../../../../feature/chat-controller/runChatControllers.js';
8
8
  import '../../../../feature/chat-bot/ChatBot.js';
9
9
  import { ChatRepository } from '../../../../feature/chat-bot/ChatRepository.js';
10
10
  import 'uuid';
11
11
  import '../../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
12
- import '../../../../feature/mindset/metadata/MindsetMetadataStore.js';
13
- import '../../../../feature/mindset/MindsetOperator.js';
12
+ import '../../../../core/error/setupErrorHandlers.js';
14
13
  import { WhatsAppRepository } from '../WhatsAppRepository.js';
15
14
 
16
15
  let WhatsAppSenderByCloudApi = class WhatsAppSenderByCloudApi extends WhatsAppSender {
@@ -6,11 +6,10 @@ import '../../../../feature/chat-bot/ChatBot.js';
6
6
  import { ChatRepository } from '../../../../feature/chat-bot/ChatRepository.js';
7
7
  import 'uuid';
8
8
  import '../../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
9
+ import '../../../../core/error/setupErrorHandlers.js';
9
10
  import '../../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
10
11
  import { ChatResolver } from '../../../../feature/chat-controller/ChatResolver.js';
11
- import '../../../../core/auth/Auth.js';
12
- import '../../../../feature/mindset/metadata/MindsetMetadataStore.js';
13
- import '../../../../feature/mindset/MindsetOperator.js';
12
+ import '../../../../feature/chat-controller/runChatControllers.js';
14
13
  import { WhatsAppRepository } from '../WhatsAppRepository.js';
15
14
  import { WhatsAppWabotProxyConnection } from './WhatsAppWabotProxyConnection.js';
16
15
 
@@ -1,5 +1,6 @@
1
1
  import { __decorate } from 'tslib';
2
2
  import { CustomError } from '../error/CustomError.js';
3
+ import '../error/setupErrorHandlers.js';
3
4
  import { scoped, Lifecycle } from '../injection/index.js';
4
5
 
5
6
  let Auth = class Auth {
@@ -46,6 +46,9 @@ class Entity extends Storable {
46
46
  throw new Error('createdAt is required');
47
47
  }
48
48
  }
49
+ lockerKey() {
50
+ return this.id;
51
+ }
49
52
  }
50
53
  /**
51
54
  * @deprecated Should use Entity
@@ -0,0 +1,33 @@
1
+ import { Logger } from '../logger/Logger.js';
2
+
3
+ const defaultConfig = {
4
+ exitOnUncaughtException: true,
5
+ exitOnUnhandledRejection: true,
6
+ logger: new Logger('wabot:error'),
7
+ };
8
+ function setupErrorHandlers(config) {
9
+ const { exitOnUncaughtException, exitOnUnhandledRejection, logger } = {
10
+ ...defaultConfig,
11
+ ...config,
12
+ };
13
+ process.on('uncaughtException', (error, origin) => {
14
+ logger.fatal(`Uncaught Exception [${origin}]:`, error);
15
+ if (exitOnUncaughtException) {
16
+ process.exit(1);
17
+ }
18
+ });
19
+ process.on('unhandledRejection', (reason, promise) => {
20
+ if (reason instanceof Error) {
21
+ logger.error('Unhandled Rejection:', reason);
22
+ }
23
+ else {
24
+ logger.error('Unhandled Rejection at:', promise, 'reason:', reason);
25
+ }
26
+ if (exitOnUnhandledRejection) {
27
+ process.exit(1);
28
+ }
29
+ });
30
+ logger.info('Global error handlers configured');
31
+ }
32
+
33
+ export { setupErrorHandlers };
@@ -8,9 +8,17 @@ const levelColors = {
8
8
  error: 1,
9
9
  fatal: 1,
10
10
  };
11
+ const levelToSeverity = {
12
+ warn: 'warning',
13
+ error: 'error',
14
+ fatal: 'fatal',
15
+ };
11
16
  class Logger {
17
+ static monitor = null;
12
18
  debuggers;
19
+ name;
13
20
  constructor(name) {
21
+ this.name = name;
14
22
  this.debuggers = {};
15
23
  for (const level of Object.keys(levelColors)) {
16
24
  const dbg = debug(`${name}:${level}`);
@@ -18,26 +26,76 @@ class Logger {
18
26
  this.debuggers[level] = dbg;
19
27
  }
20
28
  }
29
+ static setMonitor(monitor) {
30
+ Logger.monitor = monitor;
31
+ }
32
+ static getMonitor() {
33
+ return Logger.monitor;
34
+ }
21
35
  trace(...args) {
22
- this.log(this.debuggers['trace'], args);
36
+ this.log('trace', args);
23
37
  }
24
38
  debug(...args) {
25
- this.log(this.debuggers['debug'], args);
39
+ this.log('debug', args);
26
40
  }
27
41
  info(...args) {
28
- this.log(this.debuggers['info'], args);
42
+ this.log('info', args);
29
43
  }
30
44
  warn(...args) {
31
- this.log(this.debuggers['warn'], args);
45
+ this.log('warn', args);
32
46
  }
33
47
  error(...args) {
34
- this.log(this.debuggers['error'], args);
48
+ this.log('error', args);
35
49
  }
36
50
  fatal(...args) {
37
- this.log(this.debuggers['fatal'], args);
51
+ this.log('fatal', args);
52
+ }
53
+ log(level, args) {
54
+ const debugg = this.debuggers[level];
55
+ const formattedArgs = this.formatArgs(args);
56
+ debugg(...formattedArgs);
57
+ this.sendToMonitor(level, args);
58
+ }
59
+ sendToMonitor(level, args) {
60
+ const severity = levelToSeverity[level];
61
+ if (!severity || !Logger.monitor)
62
+ return;
63
+ const context = {
64
+ logger: this.name,
65
+ level: severity,
66
+ timestamp: new Date(),
67
+ extra: this.extractExtra(args),
68
+ };
69
+ const error = args.find((arg) => arg instanceof Error);
70
+ if (error) {
71
+ Logger.monitor.captureError(error, context);
72
+ }
73
+ else {
74
+ const message = args
75
+ .filter((arg) => !(arg instanceof Error))
76
+ .map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg)))
77
+ .join(' ');
78
+ Logger.monitor.captureMessage(message, context);
79
+ }
80
+ }
81
+ extractExtra(args) {
82
+ const extra = {};
83
+ let index = 0;
84
+ for (const arg of args) {
85
+ if (arg instanceof Error)
86
+ continue;
87
+ if (typeof arg === 'object' && arg !== null) {
88
+ Object.assign(extra, arg);
89
+ }
90
+ else if (typeof arg !== 'string') {
91
+ extra[`arg${index}`] = arg;
92
+ }
93
+ index++;
94
+ }
95
+ return Object.keys(extra).length > 0 ? extra : {};
38
96
  }
39
- log(debugg, args) {
40
- const _args = args.map((arg) => {
97
+ formatArgs(args) {
98
+ return args.map((arg) => {
41
99
  if (arg instanceof Error) {
42
100
  return JSON.stringify({
43
101
  name: arg.name,
@@ -58,7 +116,6 @@ class Logger {
58
116
  }
59
117
  return arg;
60
118
  });
61
- debugg(..._args);
62
119
  }
63
120
  }
64
121
 
@@ -1,5 +1,6 @@
1
1
  import { Storable } from '../storable/Storable.js';
2
2
  import { CustomError } from '../error/CustomError.js';
3
+ import '../error/setupErrorHandlers.js';
3
4
  import '../injection/index.js';
4
5
  import '../validation/metadata/ValidationMetadataStore.js';
5
6
  import { validateAndTransform } from '../validation/validateAndTransform.js';
@@ -17,23 +17,47 @@ let Async = class Async {
17
17
  this.jobScheduler = jobScheduler;
18
18
  }
19
19
  async runCommand(ctor, data) {
20
+ const job = await this.scheduleCommand(ctor, data, new Date());
21
+ this.jobScheduler.tryExecuteNow(job);
22
+ return job;
23
+ }
24
+ async scheduleCommand(ctor, data, scheduledAt) {
20
25
  const commandName = this.metadataStore.getCommandName(ctor);
21
26
  if (!commandName) {
22
27
  throw new Error(`${ctor.name} is not registered as command`);
23
28
  }
24
29
  const { error, value: commandData } = validateAndTransform(data, ctor);
25
- if (!commandData) {
26
- throw new Error('Invalid command data');
30
+ if (error) {
31
+ throw new Error(`Validation failed: ${error.description}`);
27
32
  }
33
+ const scheduledDate = this.resolveScheduledDate(scheduledAt);
28
34
  const job = new Job({
29
35
  commandName,
30
36
  commandData,
31
- scheduledAt: new Date().getTime(),
37
+ scheduledAt: scheduledDate.getTime(),
32
38
  });
33
39
  await this.jobRepository.create(job);
34
- this.jobScheduler.tryExecuteNow(job);
35
40
  return job;
36
41
  }
42
+ resolveScheduledDate(scheduledAt) {
43
+ if (scheduledAt instanceof Date) {
44
+ return scheduledAt;
45
+ }
46
+ const now = new Date();
47
+ if ('seconds' in scheduledAt) {
48
+ return new Date(now.getTime() + scheduledAt.seconds * 1000);
49
+ }
50
+ if ('minutes' in scheduledAt) {
51
+ return new Date(now.getTime() + scheduledAt.minutes * 60 * 1000);
52
+ }
53
+ if ('hours' in scheduledAt) {
54
+ return new Date(now.getTime() + scheduledAt.hours * 60 * 60 * 1000);
55
+ }
56
+ if ('days' in scheduledAt) {
57
+ return new Date(now.getTime() + scheduledAt.days * 24 * 60 * 60 * 1000);
58
+ }
59
+ throw new Error('Invalid schedule delay format');
60
+ }
37
61
  };
38
62
  Async = __decorate([
39
63
  singleton(),