@wabot-dev/framework 0.9.5 → 0.9.7

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.
@@ -36,20 +36,23 @@ import { RepositoryAdapterRegistry } from '../repository/RepositoryAdapterRegist
36
36
 
37
37
  const logger = new Logger('wabot:project-runner');
38
38
  const TEST_FILE_PATTERNS = /\.(test|spec|unit|integration|e2e|multiprocess)\.(ts|js)$/;
39
+ const DEFAULT_EXCLUDE = ['run.ts', 'cmd.ts'];
39
40
  const DEFAULT_CHAT_ADAPTERS = [
40
- ['../../addon/chat-bot/openia', 'OpenaiChatAdapter'],
41
- ['../../addon/chat-bot/openrouter', 'OpenRouterChatAdapter'],
42
- ['../../addon/chat-bot/anthropic', 'AnthropicChatAdapter'],
43
- ['../../addon/chat-bot/google', 'GoogleChatAdapter'],
41
+ ['../../addon/chat-bot/openia/OpenaiChatAdapter', 'OpenaiChatAdapter'],
42
+ ['../../addon/chat-bot/openrouter/OpenRouterChatAdapter', 'OpenRouterChatAdapter'],
43
+ ['../../addon/chat-bot/anthropic/AnthropicChatAdapter', 'AnthropicChatAdapter'],
44
+ ['../../addon/chat-bot/google/GoogleChatAdapter', 'GoogleChatAdapter'],
44
45
  ];
45
46
  class ProjectRunner {
46
47
  directories;
48
+ exclude;
47
49
  chatAdapters;
48
50
  connectionString;
49
51
  isPg;
50
52
  pool = null;
51
53
  constructor(config = {}) {
52
54
  this.directories = config.directories ?? ['src'];
55
+ this.exclude = [...DEFAULT_EXCLUDE, ...(config.exclude ?? [])];
53
56
  this.chatAdapters = config.chatAdapters;
54
57
  this.connectionString = this.resolveConnectionString(config.connectionString);
55
58
  this.isPg = this.connectionString != null && isPostgresUrl(this.connectionString);
@@ -86,10 +89,30 @@ class ProjectRunner {
86
89
  seen.add(d);
87
90
  return true;
88
91
  });
89
- const results = await Promise.all(roots.map((dir) => scanDir(dir).catch((err) => {
90
- logger.warn(`Could not read directory ${dir}: ${err.message}`);
91
- return [];
92
- })));
92
+ const excludedNames = new Set();
93
+ const excludedPathsByRoot = new Map();
94
+ for (const entry of this.exclude) {
95
+ if (entry.includes('/') || entry.includes('\\')) {
96
+ for (const root of roots) {
97
+ let paths = excludedPathsByRoot.get(root);
98
+ if (!paths) {
99
+ paths = new Set();
100
+ excludedPathsByRoot.set(root, paths);
101
+ }
102
+ paths.add(resolve(root, entry));
103
+ }
104
+ }
105
+ else {
106
+ excludedNames.add(entry);
107
+ }
108
+ }
109
+ const results = await Promise.all(roots.map((dir) => {
110
+ const excludedPaths = excludedPathsByRoot.get(dir) ?? new Set();
111
+ return scanDir(dir, excludedNames, excludedPaths).catch((err) => {
112
+ logger.warn(`Could not read directory ${dir}: ${err.message}`);
113
+ return [];
114
+ });
115
+ }));
93
116
  return results.flat();
94
117
  }
95
118
  async importFiles(files) {
@@ -153,23 +176,28 @@ class ProjectRunner {
153
176
  }
154
177
  async registerMemoryAdapters(components) {
155
178
  const needsJobs = components.commandHandlers.length > 0 || components.cronHandlers.length > 0;
156
- const [chatBotMod, lockMod, asyncMod] = await Promise.all([
157
- import('../../addon/chat-bot/in-memory/index.js'),
158
- import('../../addon/lock/index.js'),
159
- needsJobs ? import('../../addon/async/in-memory/index.js') : Promise.resolve(null),
179
+ const [chatBotMod, lockMod, jobMod, cronJobMod] = await Promise.all([
180
+ import('../../addon/chat-bot/in-memory/InMemoryChatRepository.js'),
181
+ import('../../addon/lock/InMemoryLocker.js'),
182
+ needsJobs
183
+ ? import('../../addon/async/in-memory/InMemoryJobRepository.js')
184
+ : Promise.resolve(null),
185
+ components.cronHandlers.length > 0
186
+ ? import('../../addon/async/in-memory/InMemoryCronJobRepository.js')
187
+ : Promise.resolve(null),
160
188
  ]);
161
189
  container.register(ChatRepository, { useToken: chatBotMod.InMemoryChatRepository });
162
190
  container.register(Locker, { useToken: lockMod.InMemoryLocker });
163
191
  const memoryAdapter = new MemoryRepositoryAdapter();
164
192
  container.resolve(RepositoryAdapterRegistry).setDefault(memoryAdapter);
165
193
  container.resolve(RepositoryMetadataStore).validateExtensionsRegistered(memoryAdapter.id);
166
- if (asyncMod) {
167
- container.register(JobRepository, { useToken: asyncMod.InMemoryJobRepository });
168
- if (components.cronHandlers.length > 0) {
169
- container.register(CronJobRepository, {
170
- useToken: asyncMod.InMemoryCronJobRepository,
171
- });
172
- }
194
+ if (jobMod) {
195
+ container.register(JobRepository, { useToken: jobMod.InMemoryJobRepository });
196
+ }
197
+ if (cronJobMod) {
198
+ container.register(CronJobRepository, {
199
+ useToken: cronJobMod.InMemoryCronJobRepository,
200
+ });
173
201
  }
174
202
  logger.info('Configured with in-memory adapters');
175
203
  }
@@ -177,25 +205,32 @@ class ProjectRunner {
177
205
  if (!this.pool) {
178
206
  throw new Error('Postgres pool was not initialized');
179
207
  }
180
- const [chatBotMod, pgMod, asyncMod] = await Promise.all([
181
- import('../../addon/chat-bot/pg/index.js'),
182
- import('../pg/index.js'),
183
- import('../../addon/async/pg/index.js'),
208
+ const hasCommandHandlers = components.commandHandlers.length > 0;
209
+ const hasCronHandlers = components.cronHandlers.length > 0;
210
+ const [chatBotMod, lockerMod, repoAdapterMod, txMod, jobMod, cronJobMod] = await Promise.all([
211
+ import('../../addon/chat-bot/pg/PgChatRepository.js'),
212
+ import('../pg/PgLocker.js'),
213
+ import('../pg/PgJsonRepositoryAdapter.js'),
214
+ import('../../addon/async/pg/PgTransactionAdapter.js'),
215
+ hasCommandHandlers || hasCronHandlers
216
+ ? import('../../addon/async/pg/PgJobRepository.js')
217
+ : Promise.resolve(null),
218
+ hasCronHandlers
219
+ ? import('../../addon/async/pg/PgCronJobRepository.js')
220
+ : Promise.resolve(null),
184
221
  ]);
185
222
  container.register(ChatRepository, { useToken: chatBotMod.PgChatRepository });
186
- container.register(Locker, { useToken: pgMod.PgLocker });
187
- const pgAdapter = new pgMod.PgJsonRepositoryAdapter(this.pool);
223
+ container.register(Locker, { useToken: lockerMod.PgLocker });
224
+ const pgAdapter = new repoAdapterMod.PgJsonRepositoryAdapter(this.pool);
188
225
  container.resolve(RepositoryAdapterRegistry).setDefault(pgAdapter);
189
226
  container.resolve(RepositoryMetadataStore).validateExtensionsRegistered(pgAdapter.id);
190
227
  const transactionStore = container.resolve(TransactionMetadataStore);
191
- transactionStore.registerAdapter('default', new asyncMod.PgTransactionAdapter(this.pool));
192
- const hasCommandHandlers = components.commandHandlers.length > 0;
193
- const hasCronHandlers = components.cronHandlers.length > 0;
194
- if (hasCommandHandlers || hasCronHandlers) {
195
- container.register(JobRepository, { useToken: asyncMod.PgJobRepository });
228
+ transactionStore.registerAdapter('default', new txMod.PgTransactionAdapter(this.pool));
229
+ if (jobMod) {
230
+ container.register(JobRepository, { useToken: jobMod.PgJobRepository });
196
231
  }
197
- if (hasCronHandlers) {
198
- container.register(CronJobRepository, { useToken: asyncMod.PgCronJobRepository });
232
+ if (cronJobMod) {
233
+ container.register(CronJobRepository, { useToken: cronJobMod.PgCronJobRepository });
199
234
  }
200
235
  logger.info('Configured with PostgreSQL adapters');
201
236
  }
@@ -250,14 +285,19 @@ function run(config) {
250
285
  function isPostgresUrl(cs) {
251
286
  return cs.startsWith('postgres://') || cs.startsWith('postgresql://');
252
287
  }
253
- async function scanDir(dir) {
288
+ async function scanDir(dir, excludedNames, excludedPaths) {
254
289
  const entries = await readdir(dir, { withFileTypes: true });
255
290
  const subResults = await Promise.all(entries.map(async (entry) => {
256
291
  const name = entry.name;
292
+ const fullPath = join(dir, name);
293
+ if (excludedNames.has(name))
294
+ return [];
295
+ if (excludedPaths.has(fullPath))
296
+ return [];
257
297
  if (entry.isDirectory()) {
258
298
  if (name.startsWith('__'))
259
299
  return [];
260
- return scanDir(join(dir, name));
300
+ return scanDir(fullPath, excludedNames, excludedPaths);
261
301
  }
262
302
  if (!entry.isFile())
263
303
  return [];
@@ -265,7 +305,6 @@ async function scanDir(dir) {
265
305
  return [];
266
306
  if (name.endsWith('.d.ts'))
267
307
  return [];
268
- const fullPath = join(dir, name);
269
308
  if (TEST_FILE_PATTERNS.test(fullPath))
270
309
  return [];
271
310
  return [fullPath];
@@ -1125,11 +1125,13 @@ declare function safeJsonParse<T = unknown>(json: string | undefined | null, con
1125
1125
 
1126
1126
  interface IProjectRunnerConfig {
1127
1127
  directories?: string[];
1128
+ exclude?: string[];
1128
1129
  connectionString?: string;
1129
1130
  chatAdapters?: IConstructor<IChatAdapter>[];
1130
1131
  }
1131
1132
  declare class ProjectRunner {
1132
1133
  private directories;
1134
+ private exclude;
1133
1135
  private chatAdapters;
1134
1136
  private connectionString;
1135
1137
  private isPg;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wabot-dev/framework",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "Framework for IA Chat Bots",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -1,2 +0,0 @@
1
- export { InMemoryJobRepository } from './InMemoryJobRepository.js';
2
- export { InMemoryCronJobRepository } from './InMemoryCronJobRepository.js';
@@ -1,3 +0,0 @@
1
- export { PgCronJobRepository } from './PgCronJobRepository.js';
2
- export { PgJobRepository } from './PgJobRepository.js';
3
- export { PgTransactionAdapter } from './PgTransactionAdapter.js';
@@ -1,2 +0,0 @@
1
- export { InMemoryChatMemory } from './InMemoryChatMemory.js';
2
- export { InMemoryChatRepository } from './InMemoryChatRepository.js';
@@ -1,2 +0,0 @@
1
- export { PgChatRepository } from './PgChatRepository.js';
2
- export { PgChatMemory } from './PgChatMemory.js';
@@ -1,2 +0,0 @@
1
- export { InMemoryLockKey } from './InMemoryLockKey.js';
2
- export { InMemoryLocker } from './InMemoryLocker.js';
@@ -1,10 +0,0 @@
1
- export { PG_ADAPTER_ID, pgExtension } from './@pgExtension.js';
2
- export { PgCrudRepository } from './PgCrudRepository.js';
3
- export { PgJsonRepositoryAdapter } from './PgJsonRepositoryAdapter.js';
4
- export { PgLocker } from './PgLocker.js';
5
- export { PgLockKey } from './PgLockKey.js';
6
- export { PgRepositoryBase, PgRepositoryBase as PgRepositoryExtension } from './PgRepositoryBase.js';
7
- export { getClientMap, pgStorage } from './pgStorage.js';
8
- export { buildQuerySql } from './buildQuerySql.js';
9
- export { getPgClient, withPgClient } from './withPgClient.js';
10
- export { withPgTransaction } from './withPgTransaction.js';