@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.
- package/dist/src/feature/project-runner/ProjectRunner.js +74 -35
- package/dist/src/index.d.ts +2 -0
- package/package.json +1 -1
- package/dist/src/addon/async/in-memory/index.js +0 -2
- package/dist/src/addon/async/pg/index.js +0 -3
- package/dist/src/addon/chat-bot/in-memory/index.js +0 -2
- package/dist/src/addon/chat-bot/pg/index.js +0 -2
- package/dist/src/addon/lock/index.js +0 -2
- package/dist/src/feature/pg/index.js +0 -10
|
@@ -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
|
|
90
|
-
|
|
91
|
-
|
|
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,
|
|
157
|
-
import('../../addon/chat-bot/in-memory/
|
|
158
|
-
import('../../addon/lock/
|
|
159
|
-
needsJobs
|
|
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 (
|
|
167
|
-
container.register(JobRepository, { useToken:
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
import('../../addon/
|
|
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:
|
|
187
|
-
const pgAdapter = new
|
|
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
|
|
192
|
-
|
|
193
|
-
|
|
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 (
|
|
198
|
-
container.register(CronJobRepository, { useToken:
|
|
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(
|
|
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];
|
package/dist/src/index.d.ts
CHANGED
|
@@ -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,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';
|