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