@seedcord/plugins 0.3.2 → 0.4.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.
package/dist/index.d.ts CHANGED
@@ -1,58 +1,45 @@
1
- import { Plugin, Core, Logger } from 'seedcord';
2
- import { TypedConstructor, ConstructorFunction } from '@seedcord/types';
3
- import mongoose from 'mongoose';
1
+ import { Plugin, Core, Logger, TypedConstructor as TypedConstructor$1 } from 'seedcord';
2
+ import mongoose, { Mongoose } from 'mongoose';
3
+ import { TypedConstructor } from '@seedcord/types';
4
+ import { Constructor } from 'type-fest';
5
+ import { PoolConfig, Pool } from 'pg';
6
+ import { Kysely, NO_MIGRATIONS, Migration, MigrationInfo } from 'kysely';
7
+
8
+ /**
9
+ * Configuration options for MongoDB connection and service loading.
10
+ */
11
+ interface MongoOptions {
12
+ /** Directory path containing database service classes */
13
+ dir: string;
14
+ /** MongoDB connection URI */
15
+ uri: string;
16
+ /** Database name to use */
17
+ name: string;
18
+ }
4
19
 
5
20
  /**
6
21
  * Registry of available database services.
7
22
  *
8
23
  * This interface can be augmented via declaration merging to add
9
- * type-safe service definitions when using the \@DatabaseService and \@DatabaseModel decorator.
24
+ * type-safe service definitions when using the \@RegisterMongoService and \@RegisterMongoModel decorator.
10
25
  *
11
26
  * @example
12
27
  * ```typescript
13
- * declare module 'seedcord' {
14
- * interface Services {
15
- * 'user': UserService;
16
- * 'guild': GuildService;
28
+ * declare module '@seedcord/plugins' {
29
+ * interface MongoServices {
30
+ * 'user': Users;
31
+ * 'guild': Guilds;
17
32
  * }
18
33
  * }
19
34
  * ```
20
35
  */
21
- interface Services {
36
+ interface MongoServices {
22
37
  }
23
38
  /**
24
39
  * Helper type to extract service keys from the Services interface.
25
40
  */
26
- type ServiceKeys = keyof Services;
41
+ type MongoServiceKeys = keyof MongoServices;
27
42
 
28
- /**
29
- * Basic document interface with MongoDB ObjectId field.
30
- *
31
- * Represents the minimal structure of a MongoDB document
32
- * with the required `_id` field.
33
- */
34
- interface IDocument {
35
- /** MongoDB document identifier */
36
- _id: string;
37
- }
38
- /**
39
- * Helper type to extract the type of a document that extends IDocument.
40
- *
41
- * @typeParam Doc - The document type extending IDocument
42
- */
43
- type TypeOfIDocument<Doc extends IDocument = IDocument> = Doc;
44
-
45
- /**
46
- * Configuration options for MongoDB connection and service loading.
47
- */
48
- interface MongoOptions {
49
- /** Directory path containing database service classes */
50
- dir: string;
51
- /** MongoDB connection URI */
52
- uri: string;
53
- /** Database name to use */
54
- name: string;
55
- }
56
43
  /**
57
44
  * MongoDB integration plugin for Seedcord.
58
45
  *
@@ -67,9 +54,11 @@ declare class Mongo extends Plugin {
67
54
  private readonly uri;
68
55
  /**
69
56
  * Map of all loaded services.
70
- * Keys come from `@DatabaseService('key')`
57
+ * Keys come from `@RegisterMongoService('key')`
71
58
  */
72
- readonly services: Services;
59
+ readonly services: MongoServices;
60
+ /** Exposed Mongoose instance once `init` completes. */
61
+ connection: Mongoose;
73
62
  constructor(core: Core, options: MongoOptions);
74
63
  init(): Promise<void>;
75
64
  stop(): Promise<void>;
@@ -77,9 +66,31 @@ declare class Mongo extends Plugin {
77
66
  private disconnect;
78
67
  private loadServices;
79
68
  private isServiceClass;
80
- _register<SKey extends keyof Services>(key: SKey, instance: Services[SKey]): void;
69
+ /**
70
+ * Register hook used by decorated services.
71
+ *
72
+ * @internal
73
+ */
74
+ _register<SKey extends keyof MongoServices>(key: SKey, instance: MongoServices[SKey]): void;
81
75
  }
82
76
 
77
+ /**
78
+ * Basic document interface with MongoDB ObjectId field.
79
+ *
80
+ * Represents the minimal structure of a MongoDB document
81
+ * with the required `_id` field.
82
+ */
83
+ interface MongoDocument {
84
+ /** MongoDB document identifier */
85
+ _id: string;
86
+ }
87
+ /**
88
+ * Helper type to extract the type of a document that extends MongoDocument.
89
+ *
90
+ * @typeParam Doc - The document type extending MongoDocument
91
+ */
92
+ type MongoDocumentType<Doc extends MongoDocument = MongoDocument> = Doc;
93
+
83
94
  /**
84
95
  * Base class for MongoDB service layers
85
96
  *
@@ -89,9 +100,9 @@ declare class Mongo extends Plugin {
89
100
  * @typeParam Doc - The document type this service manages
90
101
  * @example
91
102
  * ```typescript
92
- * \@DatabaseService('users')
93
- * export class Users extends BaseService<IUser> {
94
- * \@DatabaseModel('users')
103
+ * \@RegisterMongoService('users')
104
+ * export class Users extends MongoService<IUser> {
105
+ * \@RegisterMongoModel('users')
95
106
  * public static schema = new mongoose.Schema<IUser>({
96
107
  * username: { type: String, required: true, unique: true }
97
108
  * });
@@ -103,34 +114,14 @@ declare class Mongo extends Plugin {
103
114
  * }
104
115
  * ```
105
116
  */
106
- declare abstract class BaseService<Doc extends IDocument = IDocument> {
117
+ declare abstract class MongoService<Doc extends MongoDocument = MongoDocument> {
107
118
  protected readonly db: Mongo;
108
119
  protected readonly core: Core;
109
120
  readonly model: mongoose.Model<Doc>;
110
121
  constructor(db: Mongo, core: Core);
111
122
  }
112
- /** Constructor type for BaseService classes */
113
- type BaseServiceConstructor = TypedConstructor<typeof BaseService>;
114
-
115
- /**
116
- * Catches and wraps database operation errors.
117
- *
118
- * Automatically wraps non-CustomError exceptions in DatabaseError instances
119
- * with UUID tracking. Should be applied to database service methods.
120
- *
121
- * @param errorMessage - Message to include when wrapping errors
122
- * @decorator
123
- * @example
124
- * ```typescript
125
- * class UserService extends BaseService {
126
- * \@DBCatchable('Failed to find user')
127
- * async findById(id: string) {
128
- * return this.model.findById(id);
129
- * }
130
- * }
131
- * ```
132
- */
133
- declare function DBCatchable<TypeReturn>(errorMessage: string): (_target: unknown, _propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>) => void;
123
+ /** Constructor type for {@link MongoService} classes */
124
+ type MongoServiceConstructor = TypedConstructor<typeof MongoService>;
134
125
 
135
126
  declare const ModelMetadataKey: unique symbol;
136
127
  /**
@@ -140,20 +131,21 @@ declare const ModelMetadataKey: unique symbol;
140
131
  * for service registration. The model becomes available as `this.model` in the service.
141
132
  * Must be applied to a `public static schema` property in the service class.
142
133
  *
134
+ * @typeParam TService - The service key type
143
135
  * @param collection - Collection name for the Mongoose model
144
136
  * @decorator
145
137
  * @example
146
138
  * ```typescript
147
- * \@DatabaseService('users')
148
- * export class Users extends BaseService<IUser> {
149
- * \@DatabaseModel('users')
139
+ * \@RegisterMongoService('users')
140
+ * export class Users extends MongoService<IUser> {
141
+ * \@RegisterMongoModel('users')
150
142
  * public static schema = new mongoose.Schema<IUser>({
151
143
  * username: { type: String, required: true, unique: true }
152
144
  * });
153
145
  * }
154
146
  * ```
155
147
  */
156
- declare function DatabaseModel<TService extends ServiceKeys>(collection: TService): <SchemaObj extends Record<KeyOfSchema, mongoose.Schema>, KeyOfSchema extends keyof SchemaObj & (string | symbol)>(target: SchemaObj, propertyKey: KeyOfSchema) => void;
148
+ declare function RegisterMongoModel<TService extends MongoServiceKeys>(collection: TService): <SchemaObj extends Record<KeyOfSchema, mongoose.Schema>, KeyOfSchema extends keyof SchemaObj & (string | symbol)>(target: SchemaObj, propertyKey: KeyOfSchema) => void;
157
149
 
158
150
  declare const ServiceMetadataKey: unique symbol;
159
151
  /**
@@ -162,18 +154,377 @@ declare const ServiceMetadataKey: unique symbol;
162
154
  * Associates a service class with a key for dependency injection.
163
155
  * The service becomes available via `core.db.services[key]`.
164
156
  *
157
+ * @typeParam TService - The service key type
165
158
  * @param key - Service key for registration and type-safe access
166
159
  * @decorator
167
160
  * @example
168
161
  * ```typescript
169
- * \@DatabaseService('users')
170
- * export class Users<Doc extends IUser = IUser> extends BaseService<Doc> {
162
+ * \@RegisterMongoService('users')
163
+ * export class Users<Doc extends IUser = IUser> extends MongoService<Doc> {
171
164
  * // Some code
172
165
  * }
173
166
  * ```
174
167
  */
175
- declare function DatabaseService<TService extends ServiceKeys>(key: TService): <DatabaseCtor extends ConstructorFunction & {
176
- prototype: BaseService;
168
+ declare function RegisterMongoService<TService extends MongoServiceKeys>(key: TService): <DatabaseCtor extends Constructor<unknown> & {
169
+ prototype: MongoService;
177
170
  }>(ctor: DatabaseCtor) => void;
178
171
 
179
- export { BaseService, type BaseServiceConstructor, DBCatchable, DatabaseModel, DatabaseService, type IDocument, ModelMetadataKey, Mongo, type ServiceKeys, ServiceMetadataKey, type Services, type TypeOfIDocument };
172
+ /**
173
+ * Handles ensuring the target Postgres database exists, creating it if necessary.
174
+ */
175
+ declare class KpgDatabaseBootstrapper {
176
+ private readonly logger;
177
+ private static readonly ADMIN_DB;
178
+ private static readonly DATABASE_EXISTS_SQL;
179
+ constructor(logger: Logger);
180
+ resolveDatabaseName(config: PoolConfig): string | null;
181
+ resolveDatabaseFromPool(pool: Pool): string | null;
182
+ ensure(baseConfig: PoolConfig): Promise<void>;
183
+ private buildAdminConfig;
184
+ private databaseExists;
185
+ private createDatabase;
186
+ private static parseDatabaseName;
187
+ private static applyDatabaseToConnectionString;
188
+ private static escapeIdentifier;
189
+ }
190
+
191
+ /**
192
+ * Options that describe where migrations live and how the migrator should
193
+ * behave.
194
+ */
195
+ interface KpgMigrationsOptions {
196
+ /** Directory path, single file path, or array of migration files */
197
+ readonly path: string | string[];
198
+ /** Allow running migrations even if new ones are inserted out of order */
199
+ readonly allowUnorderedMigrations?: boolean;
200
+ /** Custom table name used to track executed migrations */
201
+ readonly migrationTableName?: string;
202
+ /** Custom lock table name used by the migrator */
203
+ readonly migrationLockTableName?: string;
204
+ /** Schema that contains the migration bookkeeping tables */
205
+ readonly migrationTableSchema?: string;
206
+ /** Comparator that determines execution order for migrations */
207
+ readonly nameComparator?: (nameA: string, nameB: string) => number;
208
+ /** Behavior when the plugin connects. `true`/`undefined` runs to latest. */
209
+ readonly onStartup?: boolean | MigrationOptions;
210
+ }
211
+ /**
212
+ * Configuration options for Postgres connection and service discovery.
213
+ */
214
+ interface KpgOptions {
215
+ /** Directory containing service classes. Make sure file(s)/folder(s) are built to `.js` in dist and aren't merged into a single file. */
216
+ readonly dir: string;
217
+ /** Migration settings */
218
+ readonly migrations: KpgMigrationsOptions;
219
+ /** Optional existing Pool instance or configuration overrides */
220
+ readonly pool?: Pool | PoolConfig;
221
+ /** Optional connection string used when a pool config is provided */
222
+ readonly connectionString?: string;
223
+ /** Optional SQL statements executed for each new connection */
224
+ readonly onConnectSQL?: string[];
225
+ /** Force using insecure SSL*/
226
+ readonly forceInsecureSSL?: boolean;
227
+ }
228
+
229
+ /**
230
+ * Type representing a migration function (either `up` or `down`).
231
+ *
232
+ * @internal
233
+ */
234
+ type MigrationFn<TKey extends keyof Migration> = NonNullable<Migration[TKey]>;
235
+ /**
236
+ * Module exporting both `up` and `down` migration functions.
237
+ *
238
+ * @internal
239
+ */
240
+ interface MigrationModule {
241
+ up: MigrationFn<'up'>;
242
+ down: MigrationFn<'down'>;
243
+ }
244
+ /**
245
+ * Target migration identifier used to indicate no migrations should be run. Uses Kysely's built-in `NO_MIGRATIONS` constant.
246
+ *
247
+ * @internal
248
+ */
249
+ type MigrationTarget = string | typeof NO_MIGRATIONS;
250
+ /**
251
+ * Behavior configuration for migrations that should run automatically when a
252
+ * database connection is established.
253
+ */
254
+ interface MigrationOptions {
255
+ /** Optional target migration to reach. Defaults to latest if omitted. */
256
+ readonly target?: MigrationTarget;
257
+ /** Direction to move along the migration timeline. Defaults to `latest`. */
258
+ readonly direction?: 'latest' | 'up' | 'down';
259
+ /** Number of steps to apply when direction is `up` or `down`. */
260
+ readonly steps?: number;
261
+ }
262
+ /**
263
+ * Behavior configuration for step-based migrations.
264
+ */
265
+ interface StepMigrationOptions {
266
+ /** Number of steps to apply when direction is `up` or `down`. */
267
+ readonly steps?: number | undefined;
268
+ }
269
+ /**
270
+ * Context provided to the migration manager for performing migrations.
271
+ *
272
+ * @internal
273
+ */
274
+ interface MigrationManagerContext<Database extends object> {
275
+ readonly db: Kysely<Database>;
276
+ readonly logger: Logger;
277
+ readonly config: KpgMigrationsOptions;
278
+ readonly baseDir: string;
279
+ }
280
+
281
+ /**
282
+ * Migration tooling for KyselyPg.
283
+ */
284
+ declare class KpgMigrationManager<Database extends object> {
285
+ private readonly ctx;
286
+ constructor(ctx: MigrationManagerContext<Database>);
287
+ migrate(options?: MigrationOptions): Promise<void>;
288
+ migrateUp(options?: StepMigrationOptions): Promise<void>;
289
+ migrateDown(options?: StepMigrationOptions): Promise<void>;
290
+ listMigrations(): Promise<readonly MigrationInfo[]>;
291
+ private runMigration;
292
+ private runStepwise;
293
+ private createMigrator;
294
+ private getMigrationProvider;
295
+ private createModuleProvider;
296
+ private logMigrationFiles;
297
+ private logPreparedMigrations;
298
+ private logMigrationResults;
299
+ private relativePath;
300
+ private resolvePath;
301
+ private handleMigrationError;
302
+ private isMigrationModule;
303
+ }
304
+
305
+ /**
306
+ * Namespace interface that gets augmented by individual service packages.
307
+ *
308
+ * This interface can be augmented via declaration merging to add
309
+ * type-safe service definitions when using the `@RegisterKpgService` decorator.
310
+ *
311
+ * @example
312
+ * ```typescript
313
+ * declare module '@seedcord/plugins' {
314
+ * interface KpgServices {
315
+ * 'users': Users;
316
+ * }
317
+ * }
318
+ * ```
319
+ */
320
+ interface KpgServices {
321
+ }
322
+ /**
323
+ * Union of all registered service keys.
324
+ */
325
+ type KpgServiceKeys = keyof KpgServices;
326
+ /**
327
+ * Fallback database shape used when no services have extended the base interface.
328
+ *
329
+ * @internal
330
+ */
331
+ type DefaultKpgDatabase = Record<string, unknown>;
332
+ /**
333
+ * Fallback service type used while no concrete services are registered.
334
+ *
335
+ * @internal
336
+ */
337
+ type DefaultKpgService = KpgService<DefaultKpgDatabase, string>;
338
+ /**
339
+ * Either a real service from `KpgServices` or the default service placeholder.
340
+ *
341
+ * @internal
342
+ */
343
+ type AnyKpgService = [KpgServiceKeys] extends [never] ? DefaultKpgService : KpgServices[KpgServiceKeys];
344
+
345
+ /**
346
+ * Postgres plugin using Kysely.
347
+ *
348
+ * Handles setting up the connection pool, applying migrations, and
349
+ * registering decorated services so they can be resolved from the core.
350
+ */
351
+ declare class KyselyPg<Database extends object> extends Plugin {
352
+ readonly core: Core;
353
+ private readonly options;
354
+ readonly logger: Logger;
355
+ private isInitialised;
356
+ /** Exposed Kysely instance once `init` completes. */
357
+ connection: Kysely<Database>;
358
+ private pool;
359
+ private migrationManager;
360
+ private readonly serviceRegistry;
361
+ private readonly databaseBootstrapper;
362
+ private databaseName;
363
+ /**
364
+ * Map of all services registered with the plugin, keyed by their decorator name.
365
+ */
366
+ get services(): KpgServices;
367
+ constructor(core: Core, options: KpgOptions);
368
+ /**
369
+ * Connects to Postgres, runs any startup migrations, and loads decorated services.
370
+ *
371
+ * Safe to call multiple times; subsequent calls exit early.
372
+ */
373
+ init(): Promise<void>;
374
+ /**
375
+ * Tears down the connection pool and clears the migration manager reference.
376
+ */
377
+ stop(): Promise<void>;
378
+ private connect;
379
+ private disconnect;
380
+ /**
381
+ * Runs migrations using the supplied options or defaults to `latest`.
382
+ *
383
+ * @param options - Target migration or direction overrides
384
+ */
385
+ migrate(options?: MigrationOptions): Promise<void>;
386
+ /**
387
+ * Runs a single upwards migration step unless a custom count is provided.
388
+ *
389
+ * @param options - Optional configuration for step-based execution
390
+ */
391
+ migrateUp(options?: StepMigrationOptions): Promise<void>;
392
+ /**
393
+ * Runs a single downwards migration step unless a custom count is provided.
394
+ *
395
+ * @param options - Optional configuration for step-based execution
396
+ */
397
+ migrateDown(options?: StepMigrationOptions): Promise<void>;
398
+ /**
399
+ * Lists every migration the manager knows about along with its execution state.
400
+ */
401
+ listMigrations(): Promise<readonly MigrationInfo[]>;
402
+ /**
403
+ * Lists unapplied migrations.
404
+ */
405
+ listPendingMigrations(): Promise<MigrationInfo[]>;
406
+ private getMigrationManager;
407
+ /**
408
+ * Register hook used by decorated services.
409
+ *
410
+ * @internal
411
+ */
412
+ _register(key: KpgServiceKeys, instance: AnyKpgService): void;
413
+ private resolvePool;
414
+ private createPoolConfig;
415
+ private registerOnConnectStatements;
416
+ private testPoolConnection;
417
+ }
418
+
419
+ /**
420
+ * Base class for KyselyPg services.
421
+ *
422
+ * Provides a small, typed shim around the shared Kysely instance and ensures
423
+ * that subclasses have been decorated with `@RegisterKpgService`.
424
+ *
425
+ * @typeParam Database - The database shape used by Kysely (tables as keys).
426
+ * @typeParam TTable - The specific table key from `Database` this service works with.
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * \@RegisterKpgService('users')
431
+ * export class UsersService extends KpgService<ImportedDatabaseInterface, 'users'> {
432
+ * public async findById(id: string) {
433
+ * return this.entity
434
+ * .selectFrom(this.table)
435
+ * .selectAll().where('id', '=', id)
436
+ * .executeTakeFirst();
437
+ * }
438
+ * }
439
+ *
440
+ * // Usage inside handlers:
441
+ * const user = await this.core.db.services.users.findById('abc');
442
+ * ```
443
+ */
444
+ declare abstract class KpgService<Database extends object, TTable extends keyof Database & string> {
445
+ protected readonly kysely: KyselyPg<Database>;
446
+ protected readonly core: Core;
447
+ readonly table: TTable;
448
+ constructor(kysely: KyselyPg<Database>, core: Core);
449
+ /**
450
+ * Shared Kysely instance used to interact with the Postgres database.
451
+ */
452
+ get db(): Kysely<Database>;
453
+ }
454
+ /** Constructor type for {@link KpgService} classes */
455
+ type KyselyServiceConstructor<Database extends object = object> = TypedConstructor$1<typeof KpgService<Database, keyof Database & string>>;
456
+
457
+ /**
458
+ * Discovers and registers Postgres services for the plugin.
459
+ */
460
+ declare class KpgServiceRegistry<Database extends object> {
461
+ private readonly plugin;
462
+ private readonly core;
463
+ private readonly logger;
464
+ private readonly services;
465
+ constructor(plugin: KyselyPg<Database>, core: Core, logger: Logger);
466
+ get map(): KpgServices;
467
+ register(key: KpgServiceKeys, instance: AnyKpgService): void;
468
+ loadFromDirectory(dir: string): Promise<void>;
469
+ private isServiceClass;
470
+ }
471
+
472
+ /**
473
+ * Extra configuration supplied to `@RegisterKpgService`.
474
+ */
475
+ interface KpgServiceRegistrationOptions {
476
+ /** Optional override for the table name exposed via the service. Defaults to the provided key. */
477
+ table?: string;
478
+ }
479
+
480
+ declare const PgServiceMetadataKey: unique symbol;
481
+ declare const PgTableMetadataKey: unique symbol;
482
+ /**
483
+ *
484
+ * Registers a Kysely PG service with the specified key and options.
485
+ *
486
+ * Associates a service class with a key for dependency injection.
487
+ * The service becomes available via `core.db.services[key]`.
488
+ *
489
+ * @typeParam TKey - The service key type
490
+ * @param key - Service key for registration and type-safe access
491
+ * @param options - Additional registration options
492
+ * @decorator
493
+ * @example
494
+ * ```typescript
495
+ * \@RegisterKpgService('users', { table: 'app_users' })
496
+ * export class UsersService extends KpgService<{ users: IUser }, 'users'> {
497
+ * // Some code
498
+ * }
499
+ * ```
500
+ *
501
+ * @see {@link KpgService}
502
+ */
503
+ declare function RegisterKpgService<TKey extends KpgServiceKeys>(key: TKey, options?: KpgServiceRegistrationOptions): <Ctor extends Constructor<KpgServices[TKey]>>(ctor: Ctor) => void;
504
+
505
+ /**
506
+ * Catches and wraps database operation errors.
507
+ *
508
+ * Wraps non-CustomError exceptions in DatabaseError instances
509
+ * with UUID tracking. Should be applied to database service methods.
510
+ *
511
+ * @typeParam TypeReturn - The return type of the decorated method
512
+ * @param errorMessage - Message to include when wrapping errors
513
+ * @decorator
514
+ * @example
515
+ * ```typescript
516
+ * class UserService extends MongoService<IUser> {
517
+ * \@WrapDatabaseError('Failed to find user')
518
+ * async findById(id: string) {
519
+ * return this.model.findById(id);
520
+ * }
521
+ * }
522
+ * ```
523
+ *
524
+ * @see {@link DatabaseError}
525
+ * @see {@link CustomError}
526
+ * @see {@link MongoService}
527
+ */
528
+ declare function WrapDatabaseError<TypeReturn>(errorMessage: string): (_target: unknown, _propertyKey: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>) => void;
529
+
530
+ export { type AnyKpgService, type DefaultKpgDatabase, type DefaultKpgService, KpgDatabaseBootstrapper, KpgMigrationManager, type KpgMigrationsOptions, type KpgOptions, KpgService, type KpgServiceKeys, type KpgServiceRegistrationOptions, KpgServiceRegistry, type KpgServices, KyselyPg, type KyselyServiceConstructor, type MigrationFn, type MigrationManagerContext, type MigrationModule, type MigrationOptions, type MigrationTarget, ModelMetadataKey, Mongo, type MongoDocument, type MongoDocumentType, MongoService, type MongoServiceConstructor, type MongoServiceKeys, type MongoServices, PgServiceMetadataKey, PgTableMetadataKey, RegisterKpgService, RegisterMongoModel, RegisterMongoService, ServiceMetadataKey, type StepMigrationOptions, WrapDatabaseError };