@seedcord/plugins 0.4.2 → 0.4.4

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.cjs CHANGED
@@ -54,9 +54,17 @@ var MongoService = class {
54
54
  this.core = core;
55
55
  const ctor = this.constructor;
56
56
  const key = Reflect.getMetadata(ServiceMetadataKey, ctor);
57
- if (!key) throw new Error(`Missing @RegisterMongoService on ${ctor.name}`);
57
+ if (!key) {
58
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginMongoServiceDecoratorMissing, [
59
+ ctor.name
60
+ ]);
61
+ }
58
62
  const model = Reflect.getMetadata(ModelMetadataKey, ctor);
59
- if (!model) throw new Error(`Missing @RegisterMongoModel on ${ctor.name}`);
63
+ if (!model) {
64
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginMongoModelDecoratorMissing, [
65
+ ctor.name
66
+ ]);
67
+ }
60
68
  this.model = model;
61
69
  db._register(key, this);
62
70
  }
@@ -69,7 +77,7 @@ var Mongo = class extends seedcord.Plugin {
69
77
  }
70
78
  core;
71
79
  options;
72
- logger = new seedcord.Logger("MongoDB");
80
+ logger = new seedcord.Logger("Mongo");
73
81
  isInitialised = false;
74
82
  uri;
75
83
  /**
@@ -80,7 +88,7 @@ var Mongo = class extends seedcord.Plugin {
80
88
  constructor(core, options) {
81
89
  super(core), this.core = core, this.options = options;
82
90
  this.uri = options.uri;
83
- this.core.shutdown.addTask(seedcord.ShutdownPhase.ExternalResources, "stop-database", async () => await this.stop());
91
+ this.core.shutdown.addTask(seedcord.ShutdownPhase.ExternalResources, "stop-database", async () => await this.stop(), this.options.timeout);
84
92
  }
85
93
  async init() {
86
94
  if (this.isInitialised) return;
@@ -97,12 +105,17 @@ var Mongo = class extends seedcord.Plugin {
97
105
  ...envapt.Envapter.isProduction && {
98
106
  tls: true,
99
107
  ssl: true
100
- }
108
+ },
109
+ ...seedcord.keepDefined(this.options.connectionOptions ?? {})
101
110
  }).then((conn) => {
102
111
  this.logger.info(chalk3__default.default.green.bold(`Connected to MongoDB: ${chalk3__default.default.magenta.bold(conn.connection.name)}`));
103
112
  return conn;
104
113
  }).catch((err) => {
105
- throw new Error(`Could not connect to MongoDB`, err);
114
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginMongoConnectionFailed, [
115
+ this.options.name
116
+ ], {
117
+ cause: err
118
+ });
106
119
  });
107
120
  }
108
121
  async disconnect() {
@@ -275,7 +288,7 @@ var KpgMigrationManager = class {
275
288
  case "down": {
276
289
  const stepCount = steps ?? 1;
277
290
  if (!Number.isInteger(stepCount) || stepCount < 0) {
278
- throw new Error("Migration step count must be a non-negative integer");
291
+ throw new seedcord.SeedcordRangeError(seedcord.SeedcordErrorCode.PluginKpgInvalidStepCount);
279
292
  }
280
293
  if (stepCount === 0) {
281
294
  this.logMigrationResults([]);
@@ -286,7 +299,9 @@ var KpgMigrationManager = class {
286
299
  return;
287
300
  }
288
301
  default:
289
- throw new Error(`Unknown migration direction: ${String(direction)}`);
302
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgUnknownDirection, [
303
+ direction
304
+ ]);
290
305
  }
291
306
  }
292
307
  async migrateUp(options) {
@@ -394,18 +409,22 @@ var KpgMigrationManager = class {
394
409
  ]);
395
410
  }
396
411
  const label = Array.isArray(target) ? target.join(", ") : target;
397
- throw new Error(`Unable to resolve migrations at path: ${label}`);
412
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgUnresolvedMigrationsPath, [
413
+ label
414
+ ]);
398
415
  }
399
416
  async createModuleProvider(files) {
400
417
  if (files.length === 0) {
401
- throw new Error("No migration files provided");
418
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgNoMigrationFiles);
402
419
  }
403
420
  const comparator = this.ctx.config.nameComparator ?? ((nameA, nameB) => nameA.localeCompare(nameB));
404
421
  const entries = await Promise.all(files.map(async (filePath) => {
405
422
  const moduleUrl = url.pathToFileURL(filePath).href;
406
423
  const mod = await import(moduleUrl);
407
424
  if (!this.isMigrationModule(mod)) {
408
- throw new Error(`Migration file ${filePath} must export async functions up and down`);
425
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgInvalidMigrationModule, [
426
+ filePath
427
+ ]);
409
428
  }
410
429
  const { up, down } = mod;
411
430
  const name = path__default.default.basename(filePath);
@@ -450,14 +469,14 @@ var KpgMigrationManager = class {
450
469
  this.ctx.logger.info("Migration results:");
451
470
  for (const result of results) {
452
471
  if (result.status === "Success") {
453
- this.ctx.logger.info(` ${chalk3__default.default.green("\u2713")} ${chalk3__default.default.bold(result.migrationName)}`);
472
+ this.ctx.logger.info(`${chalk3__default.default.green("\u2713")} ${chalk3__default.default.bold(result.migrationName)}`);
454
473
  continue;
455
474
  }
456
475
  if (result.status === "Error") {
457
- this.ctx.logger.error(` ${chalk3__default.default.red("\u2717")} ${chalk3__default.default.bold(result.migrationName)}`);
476
+ this.ctx.logger.error(`${chalk3__default.default.red("\u2717")} ${chalk3__default.default.bold(result.migrationName)}`);
458
477
  continue;
459
478
  }
460
- this.ctx.logger.info(` ${chalk3__default.default.yellow("\u2022")} ${chalk3__default.default.bold(result.migrationName)} ${chalk3__default.default.gray("(skipped)")}`);
479
+ this.ctx.logger.info(`${chalk3__default.default.yellow("\u2022")} ${chalk3__default.default.bold(result.migrationName)} ${chalk3__default.default.gray("(skipped)")}`);
461
480
  }
462
481
  }
463
482
  relativePath(filePath) {
@@ -474,7 +493,9 @@ var KpgMigrationManager = class {
474
493
  if (error instanceof Error) {
475
494
  throw error;
476
495
  }
477
- throw new Error(message);
496
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgNonErrorFailure, [
497
+ message
498
+ ]);
478
499
  }
479
500
  isMigrationModule(value) {
480
501
  if (!value || typeof value !== "object") return false;
@@ -509,10 +530,16 @@ var KpgService = class {
509
530
  this.core = core;
510
531
  const ctor = this.constructor;
511
532
  const key = Reflect.getMetadata(PgServiceMetadataKey, ctor);
512
- if (!key) throw new Error(`Missing @RegisterKpgService on ${ctor.name}`);
533
+ if (!key) {
534
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgServiceDecoratorMissing, [
535
+ ctor.name
536
+ ]);
537
+ }
513
538
  const table = Reflect.getMetadata(PgTableMetadataKey, ctor);
514
539
  if (!table) {
515
- throw new Error(`Missing table metadata for ${ctor.name}. Provide a table via @RegisterKpgService().`);
540
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.PluginKpgServiceTableMissing, [
541
+ ctor.name
542
+ ]);
516
543
  }
517
544
  this.table = table;
518
545
  this.kysely._register(key, this);
@@ -582,7 +609,7 @@ var KyselyPg = class extends seedcord.Plugin {
582
609
  super(core), this.core = core, this.options = options;
583
610
  this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);
584
611
  this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);
585
- this.core.shutdown.addTask(seedcord.ShutdownPhase.ExternalResources, "stop-kyselypg", async () => await this.stop());
612
+ this.core.shutdown.addTask(seedcord.ShutdownPhase.ExternalResources, "stop-kyselypg", async () => await this.stop(), this.options.timeout);
586
613
  }
587
614
  /**
588
615
  * Connects to Postgres, runs any startup migrations, and loads decorated services.
@@ -752,7 +779,7 @@ function WrapDatabaseError(errorMessage) {
752
779
  const originalMethod = descriptor.value;
753
780
  descriptor.value = async function(...args) {
754
781
  if (!originalMethod) {
755
- throw new Error("Method not found");
782
+ throw new seedcord.SeedcordError(seedcord.SeedcordErrorCode.DecoratorMethodNotFound);
756
783
  }
757
784
  try {
758
785
  return await originalMethod.apply(this, args);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/shared/WrapDatabaseError.ts"],"names":["ServiceMetadataKey","Symbol","RegisterMongoService","key","ctor","Reflect","defineMetadata","ModelMetadataKey","RegisterMongoModel","collection","target","propertyKey","schema","name","String","model","mongoose","MongoService","db","core","getMetadata","Error","_register","Mongo","Plugin","logger","Logger","isInitialised","uri","services","options","shutdown","addTask","ShutdownPhase","ExternalResources","stop","init","connect","loadServices","disconnect","connection","dbName","Envapter","isProduction","tls","ssl","then","conn","info","chalk","green","bold","magenta","catch","err","red","error","message","servicesDir","dir","traverseDirectory","_full","rel","mod","Service","Object","values","isServiceClass","instance","italic","yellow","gray","keys","length","obj","prototype","hasMetadata","KpgDatabaseBootstrapper","ADMIN_DB","DATABASE_EXISTS_SQL","resolveDatabaseName","config","parseDatabaseName","resolveDatabaseFromPool","pool","database","connectionString","ensure","baseConfig","targetDb","adminConfig","buildAdminConfig","warn","adminPool","Pool","exists","databaseExists","createDatabase","end","applyDatabaseToConnectionString","client","rows","query","Boolean","release","createSql","escapeIdentifier","trim","url","URL","pathname","replace","candidate","split","decodeURIComponent","encodeURIComponent","toString","identifier","KpgMigrationManager","ctx","migrate","direction","steps","label","NO_MIGRATIONS","runMigration","migrator","migrateTo","migrateToLatest","stepCount","Number","isInteger","logMigrationResults","runner","migrateUp","migrateDown","runStepwise","listMigrations","createMigrator","getMigrations","runningMessage","results","handleMigrationError","directionLabel","countLabel","aggregated","encounteredError","index","push","provider","getMigrationProvider","Migrator","allowUnorderedMigrations","keepDefined","path","resolvedTarget","Array","isArray","map","entry","resolvePath","logMigrationFiles","createModuleProvider","migrationStat","fs","stat","undefined","isDirectory","directory","relativePath","FileMigrationProvider","migrationFolder","isFile","join","files","comparator","nameComparator","nameA","nameB","localeCompare","entries","Promise","all","filePath","moduleUrl","pathToFileURL","href","isMigrationModule","up","down","basename","migration","sorted","sort","a","b","logPreparedMigrations","resolve","fromEntries","file","result","status","migrationName","relative","baseDir","startsWith","isAbsolute","inspect","value","PgServiceMetadataKey","PgTableMetadataKey","RegisterKpgService","tableName","table","KpgService","kysely","KpgServiceRegistry","create","plugin","register","loadFromDirectory","KyselyPg","migrationManager","serviceRegistry","databaseBootstrapper","databaseName","startupConfig","migrations","onStartup","resolvePool","registerOnConnectStatements","onConnectSQL","testPoolConnection","Kysely","dialect","PostgresDialect","process","cwd","dbLabel","getMigrationManager","listPendingMigrations","filter","m","executedAt","manager","providedPool","createPoolConfig","poolConfig","forceInsecureSSL","rejectUnauthorized","statements","queuedStatements","on","sql","WrapDatabaseError","errorMessage","_target","_propertyKey","descriptor","originalMethod","args","apply","CustomError","throwCustomError","DatabaseError"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { MongoService } from '../MongoService';\nimport type { MongoServiceKeys } from '../types/MongoServices';\nimport type { Constructor } from 'type-fest';\n\nexport const ServiceMetadataKey = Symbol('db:serviceKey');\n\n/**\n * Registers a database service with a typed key\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TService - The service key type\n * @param key - Service key for registration and type-safe access\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users<Doc extends IUser = IUser> extends MongoService<Doc> {\n * // Some code\n * }\n * ```\n */\nexport function RegisterMongoService<TService extends MongoServiceKeys>(key: TService) {\n return <DatabaseCtor extends Constructor<unknown> & { prototype: MongoService }>(ctor: DatabaseCtor): void => {\n Reflect.defineMetadata(ServiceMetadataKey, key, ctor);\n };\n}\n","import mongoose from 'mongoose';\n\nimport type { MongoServiceKeys } from '../types/MongoServices';\n\nexport const ModelMetadataKey = Symbol('db:model');\n\n/**\n * Associates a Mongoose model with a database service\n *\n * Creates a Mongoose model from the decorated static schema property and stores it\n * for service registration. The model becomes available as `this.model` in the service.\n * Must be applied to a `public static schema` property in the service class.\n *\n * @typeParam TService - The service key type\n * @param collection - Collection name for the Mongoose model\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n * }\n * ```\n */\nexport function RegisterMongoModel<TService extends MongoServiceKeys>(collection: TService) {\n return <\n SchemaObj extends Record<KeyOfSchema, mongoose.Schema>,\n KeyOfSchema extends keyof SchemaObj & (string | symbol)\n >(\n target: SchemaObj,\n propertyKey: KeyOfSchema\n ): void => {\n const schema = target[propertyKey];\n const name = String(collection);\n const model = mongoose.model(name, schema);\n Reflect.defineMetadata(ModelMetadataKey, model, target);\n };\n}\n","import { ModelMetadataKey } from './decorators/RegisterMongoModel';\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\n\nimport type { Mongo } from './Mongo';\nimport type { MongoDocument } from './types/MongoDocument';\nimport type { MongoServices } from './types/MongoServices';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type mongoose from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * Base class for MongoDB service layers\n *\n * Provides typed access to MongoDB collections through Mongoose models.\n * Services are automatically registered with the Mongo plugin when instantiated.\n *\n * @typeParam Doc - The document type this service manages\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n *\n * // Custom methods here\n * public async findByUsername(username: string) {\n * return this.model.findOne({ username });\n * }\n * }\n * ```\n */\nexport abstract class MongoService<Doc extends MongoDocument = MongoDocument> {\n public readonly model: mongoose.Model<Doc>;\n\n public constructor(\n protected readonly db: Mongo,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n if (!key) throw new Error(`Missing @RegisterMongoService on ${ctor.name}`);\n\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<Doc> | undefined;\n if (!model) throw new Error(`Missing @RegisterMongoModel on ${ctor.name}`);\n\n this.model = model;\n\n db._register(key as keyof MongoServices, this as unknown as MongoServices[keyof MongoServices]);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { Logger, Plugin, ShutdownPhase, traverseDirectory } from 'seedcord';\n\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\nimport { MongoService } from './MongoService';\n\nimport type { MongoServiceConstructor } from './MongoService';\nimport type { MongoOptions } from './types/MongoOptions';\nimport type { MongoServices } from './types/MongoServices';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * MongoDB integration plugin for Seedcord.\n *\n * Manages MongoDB connections, service loading, and provides type-safe\n * access to database services through service registration decorators.\n */\nexport class Mongo extends Plugin {\n public readonly logger = new Logger('MongoDB');\n private isInitialised = false;\n private readonly uri: string;\n\n /**\n * Map of all loaded services.\n * Keys come from `@RegisterMongoService('key')`\n */\n public readonly services: MongoServices = {} as MongoServices;\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n\n constructor(\n public readonly core: Core,\n private readonly options: MongoOptions\n ) {\n super(core);\n this.uri = options.uri;\n\n this.core.shutdown.addTask(ShutdownPhase.ExternalResources, 'stop-database', async () => await this.stop());\n }\n\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n await this.loadServices();\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.connection = await mongoose\n .connect(this.uri, {\n dbName: this.options.name,\n ...(Envapter.isProduction && { tls: true, ssl: true })\n })\n .then((conn) => {\n this.logger.info(chalk.green.bold(`Connected to MongoDB: ${chalk.magenta.bold(conn.connection.name)}`));\n return conn;\n })\n .catch((err) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n throw new Error(`Could not connect to MongoDB`, err);\n });\n }\n\n private async disconnect(): Promise<void> {\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`));\n }\n\n private async loadServices(): Promise<void> {\n const servicesDir = this.options.dir;\n this.logger.info(chalk.bold(servicesDir));\n\n await traverseDirectory(\n servicesDir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is MongoServiceConstructor {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof MongoService &&\n Reflect.hasMetadata(ServiceMetadataKey, obj)\n );\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register<SKey extends keyof MongoServices>(key: SKey, instance: MongoServices[SKey]): void {\n this.services[key] = instance;\n }\n}\n","import chalk from 'chalk';\nimport { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from 'seedcord';\n\n/**\n * Handles ensuring the target Postgres database exists, creating it if necessary.\n */\nexport class KpgDatabaseBootstrapper {\n private static readonly ADMIN_DB = 'postgres';\n private static readonly DATABASE_EXISTS_SQL =\n 'SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname = $1) AS \"exists\"';\n\n constructor(private readonly logger: Logger) {}\n\n public resolveDatabaseName(config: PoolConfig): string | null {\n return KpgDatabaseBootstrapper.parseDatabaseName(config);\n }\n\n public resolveDatabaseFromPool(pool: Pool): string | null {\n const config: PoolConfig = {};\n\n const { options } = pool;\n\n if (typeof options.database === 'string') {\n config.database = options.database;\n }\n\n if (typeof options.connectionString === 'string') {\n config.connectionString = options.connectionString;\n }\n\n return this.resolveDatabaseName(config);\n }\n\n public async ensure(baseConfig: PoolConfig): Promise<void> {\n const targetDb = this.resolveDatabaseName(baseConfig);\n if (!targetDb) {\n this.logger.info(chalk.gray('Skipping database existence check (no database specified).'));\n return;\n }\n\n if (targetDb === KpgDatabaseBootstrapper.ADMIN_DB) {\n this.logger.info(chalk.gray('Target database is postgres; skipping creation.'));\n return;\n }\n\n const adminConfig = this.buildAdminConfig(baseConfig);\n if (!adminConfig) {\n this.logger.warn(`Unable to derive admin connection when ensuring database ${targetDb}`);\n return;\n }\n\n this.logger.info(chalk.gray(`Ensuring database ${chalk.yellow(targetDb)} exists...`));\n\n const adminPool = new Pool(adminConfig);\n\n try {\n const exists = await this.databaseExists(adminPool, targetDb);\n if (exists) {\n this.logger.info(chalk.gray(`Database ${chalk.yellow(targetDb)} already exists.`));\n return;\n }\n\n await this.createDatabase(adminPool, targetDb);\n this.logger.info(chalk.green(`Created database ${chalk.bold(targetDb)}.`));\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to ensure database ${targetDb}: ${err.message}`);\n throw err;\n } finally {\n await adminPool.end();\n }\n }\n\n private buildAdminConfig(baseConfig: PoolConfig): PoolConfig | null {\n const adminConfig: PoolConfig = { ...baseConfig };\n\n const { connectionString } = adminConfig;\n if (connectionString) {\n const connection = KpgDatabaseBootstrapper.applyDatabaseToConnectionString(\n connectionString,\n KpgDatabaseBootstrapper.ADMIN_DB\n );\n if (!connection) return null;\n adminConfig.connectionString = connection;\n }\n\n adminConfig.database = KpgDatabaseBootstrapper.ADMIN_DB;\n return adminConfig;\n }\n\n private async databaseExists(pool: Pool, database: string): Promise<boolean> {\n const client = await pool.connect();\n try {\n const { rows } = await client.query<{ exists: boolean }>(KpgDatabaseBootstrapper.DATABASE_EXISTS_SQL, [\n database\n ]);\n return Boolean(rows[0]?.exists);\n } finally {\n client.release();\n }\n }\n\n private async createDatabase(pool: Pool, database: string): Promise<void> {\n const client = await pool.connect();\n try {\n const createSql = `CREATE DATABASE ${KpgDatabaseBootstrapper.escapeIdentifier(database)}`;\n await client.query(createSql);\n } finally {\n client.release();\n }\n }\n\n private static parseDatabaseName(config: PoolConfig): string | null {\n if (typeof config.database === 'string' && config.database.trim().length > 0) {\n return config.database.trim();\n }\n\n const connectionString = config.connectionString;\n if (!connectionString) return null;\n\n try {\n const url = new URL(connectionString);\n const pathname = url.pathname.replace(/^\\//, '');\n if (!pathname) return null;\n const [candidate] = pathname.split('/');\n return candidate ? decodeURIComponent(candidate) : null;\n } catch {\n return null;\n }\n }\n\n private static applyDatabaseToConnectionString(connectionString: string, database: string): string | null {\n try {\n const url = new URL(connectionString);\n url.pathname = `/${encodeURIComponent(database)}`;\n return url.toString();\n } catch {\n return null;\n }\n }\n\n private static escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { inspect } from 'node:util';\n\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type { Migration, MigrationInfo, MigrationProvider, MigrationResult, MigrationResultSet } from 'kysely';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n */\nexport class KpgMigrationManager<Database extends object> {\n constructor(private readonly ctx: MigrationManagerContext<Database>) {}\n\n public async migrate(options?: MigrationOptions): Promise<void> {\n const { target, direction = 'latest', steps } = options ?? {};\n\n if (typeof target !== 'undefined') {\n const label = target === NO_MIGRATIONS ? 'NO_MIGRATIONS' : target;\n await this.runMigration((migrator) => migrator.migrateTo(target), `Migrating to ${chalk.yellow(label)}...`);\n return;\n }\n\n switch (direction) {\n case 'latest':\n await this.runMigration((migrator) => migrator.migrateToLatest());\n return;\n case 'up':\n case 'down': {\n const stepCount = steps ?? 1;\n if (!Number.isInteger(stepCount) || stepCount < 0) {\n throw new Error('Migration step count must be a non-negative integer');\n }\n\n if (stepCount === 0) {\n this.logMigrationResults([]);\n return;\n }\n\n const runner =\n direction === 'up'\n ? (migrator: Migrator) => migrator.migrateUp()\n : (migrator: Migrator) => migrator.migrateDown();\n await this.runStepwise(stepCount, direction, runner);\n return;\n }\n default:\n throw new Error(`Unknown migration direction: ${String(direction)}`);\n }\n }\n\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'up' });\n return;\n }\n\n await this.migrate({ direction: 'up', steps: options.steps });\n }\n\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'down' });\n return;\n }\n\n await this.migrate({ direction: 'down', steps: options.steps });\n }\n\n public async listMigrations(): Promise<readonly MigrationInfo[]> {\n const migrator = await this.createMigrator();\n return migrator.getMigrations();\n }\n\n private async runMigration(\n runner: (migrator: Migrator) => Promise<MigrationResultSet>,\n runningMessage = 'Running migrations...'\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n this.ctx.logger.info(chalk.gray(runningMessage));\n const { error, results } = await runner(migrator);\n\n this.logMigrationResults(results ?? []);\n\n if (error) {\n this.handleMigrationError(error);\n }\n }\n\n private async runStepwise(\n steps: number,\n direction: 'up' | 'down',\n runner: (migrator: Migrator) => Promise<MigrationResultSet>\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n const directionLabel = direction === 'up' ? 'Running' : 'Reverting';\n const countLabel = steps === 1 ? 'one migration' : `${chalk.yellow(String(steps))} migrations`;\n this.ctx.logger.info(chalk.gray(`${directionLabel} ${countLabel}...`));\n\n const aggregated: MigrationResult[] = [];\n let encounteredError: unknown;\n\n for (let index = 0; index < steps; index += 1) {\n const { error, results } = await runner(migrator);\n\n if (results?.length) {\n aggregated.push(...results);\n }\n\n if (error) {\n encounteredError = error;\n break;\n }\n\n if (!results?.length) {\n break;\n }\n }\n\n this.logMigrationResults(aggregated);\n\n if (encounteredError) {\n this.handleMigrationError(encounteredError);\n }\n }\n\n private async createMigrator(): Promise<Migrator> {\n const provider = await this.getMigrationProvider();\n const { config } = this.ctx;\n\n return new Migrator({\n db: this.ctx.db,\n provider,\n allowUnorderedMigrations: config.allowUnorderedMigrations ?? false,\n ...keepDefined(config, 'migrationTableName', 'migrationLockTableName', 'migrationTableSchema')\n });\n }\n\n private async getMigrationProvider(): Promise<MigrationProvider> {\n const { path: target } = this.ctx.config;\n const resolvedTarget = Array.isArray(target)\n ? target.map((entry) => this.resolvePath(entry))\n : this.resolvePath(target);\n\n if (Array.isArray(resolvedTarget)) {\n this.logMigrationFiles(resolvedTarget);\n return this.createModuleProvider(resolvedTarget);\n }\n\n let migrationStat: Stats | undefined;\n try {\n migrationStat = await fs.stat(resolvedTarget);\n } catch {\n migrationStat = undefined;\n }\n\n if (migrationStat?.isDirectory()) {\n const directory = this.relativePath(resolvedTarget);\n this.ctx.logger.info(chalk.gray(`Loading migrations directory ${chalk.yellow(directory)}`));\n return new FileMigrationProvider({ fs, path, migrationFolder: resolvedTarget });\n }\n\n if (migrationStat?.isFile() ?? true) {\n this.logMigrationFiles([resolvedTarget]);\n return this.createModuleProvider([resolvedTarget]);\n }\n\n const label = Array.isArray(target) ? target.join(', ') : target;\n throw new Error(`Unable to resolve migrations at path: ${label}`);\n }\n\n private async createModuleProvider(files: string[]): Promise<MigrationProvider> {\n if (files.length === 0) {\n throw new Error('No migration files provided');\n }\n\n const comparator =\n this.ctx.config.nameComparator ?? ((nameA: string, nameB: string) => nameA.localeCompare(nameB));\n\n const entries = await Promise.all(\n files.map(async (filePath) => {\n const moduleUrl = pathToFileURL(filePath).href;\n const mod: unknown = await import(moduleUrl);\n\n if (!this.isMigrationModule(mod)) {\n throw new Error(`Migration file ${filePath} must export async functions up and down`);\n }\n\n const { up, down } = mod;\n\n const name = path.basename(filePath);\n\n const migration: Migration = {\n async up(db) {\n await up(db);\n },\n async down(db) {\n await down(db);\n }\n };\n\n return [name, migration] as const;\n })\n );\n\n const sorted = entries.sort(([a], [b]) => comparator(a, b));\n this.logPreparedMigrations(sorted);\n\n return {\n getMigrations: () => Promise.resolve(Object.fromEntries(sorted))\n } satisfies MigrationProvider;\n }\n\n private logMigrationFiles(files: readonly string[]): void {\n if (!files.length) return;\n\n this.ctx.logger.info('Loading migration file(s):');\n for (const file of files) {\n this.ctx.logger.info(`→ ${chalk.yellow(this.relativePath(file))}`);\n }\n }\n\n private logPreparedMigrations(entries: readonly (readonly [string, Migration])[]): void {\n if (!entries.length) return;\n\n this.ctx.logger.info('Prepared migrations:');\n for (const [name] of entries) {\n this.ctx.logger.info(`→ ${chalk.green(name)}`);\n }\n }\n\n private logMigrationResults(results: readonly MigrationResult[]): void {\n if (!results.length) {\n this.ctx.logger.info(chalk.gray('No migrations executed.'));\n return;\n }\n\n this.ctx.logger.info('Migration results:');\n\n for (const result of results) {\n if (result.status === 'Success') {\n this.ctx.logger.info(` ${chalk.green('✓')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n if (result.status === 'Error') {\n this.ctx.logger.error(` ${chalk.red('✗')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n this.ctx.logger.info(\n ` ${chalk.yellow('•')} ${chalk.bold(result.migrationName)} ${chalk.gray('(skipped)')}`\n );\n }\n }\n\n private relativePath(filePath: string): string {\n const relative = path.relative(this.ctx.baseDir, filePath);\n return relative.startsWith('..') ? filePath : relative;\n }\n\n private resolvePath(target: string): string {\n if (path.isAbsolute(target)) return target;\n return path.resolve(this.ctx.baseDir, target);\n }\n\n private handleMigrationError(error: unknown): never {\n const message = error instanceof Error ? error.message : inspect(error);\n this.ctx.logger.error(`Migration failure: ${message}`);\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new Error(message);\n }\n\n private isMigrationModule(value: unknown): value is MigrationModule {\n if (!value || typeof value !== 'object') return false;\n if (!('up' in value) || !('down' in value)) return false;\n\n const { up, down } = value as { up: unknown; down: unknown };\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import type { KpgServiceRegistrationOptions } from '../types/KpgServiceRegistrationOptions';\nimport type { KpgServices, KpgServiceKeys } from '../types/KpgServices';\nimport type { Constructor } from 'type-fest';\n\nexport const PgServiceMetadataKey = Symbol('db:pgServiceKey');\nexport const PgTableMetadataKey = Symbol('db:pgTable');\n\n/**\n *\n * Registers a Kysely PG service with the specified key and options.\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TKey - The service key type\n * @param key - Service key for registration and type-safe access\n * @param options - Additional registration options\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterKpgService('users', { table: 'app_users' })\n * export class UsersService extends KpgService<{ users: IUser }, 'users'> {\n * // Some code\n * }\n * ```\n *\n * @see {@link KpgService}\n */\nexport function RegisterKpgService<TKey extends KpgServiceKeys>(key: TKey, options?: KpgServiceRegistrationOptions) {\n return <Ctor extends Constructor<KpgServices[TKey]>>(ctor: Ctor): void => {\n Reflect.defineMetadata(PgServiceMetadataKey, key, ctor);\n\n const tableName = options?.table ?? String(key);\n Reflect.defineMetadata(PgTableMetadataKey, tableName, ctor);\n };\n}\n","import { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServices } from './types/KpgServices';\nimport type { Kysely } from 'kysely';\nimport type { Core, TypedConstructor } from 'seedcord';\n\n/**\n * Base class for KyselyPg services.\n *\n * Provides a small, typed shim around the shared Kysely instance and ensures\n * that subclasses have been decorated with `@RegisterKpgService`.\n *\n * @typeParam Database - The database shape used by Kysely (tables as keys).\n * @typeParam TTable - The specific table key from `Database` this service works with.\n *\n * @example\n * ```typescript\n * \\@RegisterKpgService('users')\n * export class UsersService extends KpgService<ImportedDatabaseInterface, 'users'> {\n * public async findById(id: string) {\n * return this.entity\n * .selectFrom(this.table)\n * .selectAll().where('id', '=', id)\n * .executeTakeFirst();\n * }\n * }\n *\n * // Usage inside handlers:\n * const user = await this.core.db.services.users.findById('abc');\n * ```\n */\nexport abstract class KpgService<Database extends object, TTable extends keyof Database & string> {\n public readonly table: TTable;\n\n public constructor(\n protected readonly kysely: KyselyPg<Database>,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n if (!key) throw new Error(`Missing @RegisterKpgService on ${ctor.name}`);\n\n const table = Reflect.getMetadata(PgTableMetadataKey, ctor) as TTable | undefined;\n\n // This check should always pass since TTable is derived from the key if a table is not provided explicitly.\n if (!table) {\n throw new Error(`Missing table metadata for ${ctor.name}. Provide a table via @RegisterKpgService().`);\n }\n\n this.table = table;\n this.kysely._register(key as keyof KpgServices, this as unknown as AnyKpgService);\n }\n\n /**\n * Shared Kysely instance used to interact with the Postgres database.\n */\n public get db(): Kysely<Database> {\n return this.kysely.connection;\n }\n}\n\n/** Constructor type for {@link KpgService} classes */\nexport type KyselyServiceConstructor<Database extends object = object> = TypedConstructor<\n typeof KpgService<Database, keyof Database & string>\n>;\n","import chalk from 'chalk';\nimport { traverseDirectory } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { Core, Logger } from 'seedcord';\n\n/**\n * Discovers and registers Postgres services for the plugin.\n */\nexport class KpgServiceRegistry<Database extends object> {\n private readonly services: Record<string, AnyKpgService> = Object.create(null) as Record<string, AnyKpgService>;\n\n constructor(\n private readonly plugin: KyselyPg<Database>,\n private readonly core: Core,\n private readonly logger: Logger\n ) {}\n\n public get map(): KpgServices {\n return this.services as unknown as KpgServices;\n }\n\n public register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.services[key] = instance;\n }\n\n public async loadFromDirectory(dir: string): Promise<void> {\n this.logger.info(chalk.bold(dir));\n\n await traverseDirectory(\n dir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this.plugin, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is KyselyServiceConstructor<Database> {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof KpgService &&\n Reflect.hasMetadata(PgServiceMetadataKey, obj)\n );\n }\n}\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig } from 'pg';\nimport { keepDefined, Logger, Plugin, ShutdownPhase } from 'seedcord';\n\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { MigrationInfo } from 'kysely';\nimport type { Core } from 'seedcord';\n\n/**\n * Postgres plugin using Kysely.\n *\n * Handles setting up the connection pool, applying migrations, and\n * registering decorated services so they can be resolved from the core.\n */\nexport class KyselyPg<Database extends object> extends Plugin {\n public readonly logger = new Logger('KyselyPg');\n private isInitialised = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private migrationManager: KpgMigrationManager<Database> | null = null;\n private readonly serviceRegistry: KpgServiceRegistry<Database>;\n private readonly databaseBootstrapper: KpgDatabaseBootstrapper;\n private databaseName: string | null = null;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n return this.serviceRegistry.map;\n }\n\n constructor(\n public readonly core: Core,\n private readonly options: KpgOptions\n ) {\n super(core);\n this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);\n this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);\n this.core.shutdown.addTask(ShutdownPhase.ExternalResources, 'stop-kyselypg', async () => await this.stop());\n }\n\n /**\n * Connects to Postgres, runs any startup migrations, and loads decorated services.\n *\n * Safe to call multiple times; subsequent calls exit early.\n */\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n\n const startupConfig = this.options.migrations.onStartup;\n if (startupConfig !== false) {\n if (startupConfig && typeof startupConfig !== 'boolean') {\n await this.migrate(startupConfig);\n } else {\n await this.migrate();\n }\n }\n await this.serviceRegistry.loadFromDirectory(this.options.dir);\n }\n\n /**\n * Tears down the connection pool and clears the migration manager reference.\n */\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n const pool = await this.resolvePool();\n this.pool = pool;\n\n this.registerOnConnectStatements(pool, this.options.onConnectSQL);\n\n try {\n await this.testPoolConnection(pool);\n\n this.connection = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n ...keepDefined(this.options.kysely ?? {})\n });\n\n this.migrationManager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n const dbLabel = this.databaseName ?? 'unknown';\n this.logger.info(`Connected to Postgres database ${chalk.bold.magenta(dbLabel)}`);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.logger.error(`Could not connect to Postgres: ${error.message}`);\n throw error;\n }\n }\n\n private async disconnect(): Promise<void> {\n const pool = this.pool;\n if (!pool) return;\n\n this.pool = null;\n this.migrationManager = null;\n\n this.logger.info(chalk.gray('Closing Postgres pool.'));\n await pool.end().catch((err) => {\n this.logger.error(`Could not close pg pool: ${(err as Error).message}`);\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options or defaults to `latest`.\n *\n * @param options - Target migration or direction overrides\n */\n public async migrate(options?: MigrationOptions): Promise<void> {\n await this.getMigrationManager().migrate(options);\n }\n\n /**\n * Runs a single upwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateUp(options);\n }\n\n /**\n * Runs a single downwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateDown(options);\n }\n\n /**\n * Lists every migration the manager knows about along with its execution state.\n */\n public listMigrations(): Promise<readonly MigrationInfo[]> {\n return this.getMigrationManager().listMigrations();\n }\n\n /**\n * Lists unapplied migrations.\n */\n public async listPendingMigrations(): Promise<MigrationInfo[]> {\n const all = await this.listMigrations();\n return all.filter((m) => !m.executedAt);\n }\n\n private getMigrationManager(): KpgMigrationManager<Database> {\n if (this.migrationManager) return this.migrationManager;\n\n const manager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n this.migrationManager = manager;\n return manager;\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.serviceRegistry.register(key, instance);\n }\n\n private async resolvePool(): Promise<Pool> {\n const { pool: providedPool, connectionString } = this.options;\n\n if (providedPool instanceof Pool) {\n this.logger.info(chalk.gray('Reusing provided Postgres pool instance.'));\n this.databaseName = this.databaseBootstrapper.resolveDatabaseFromPool(providedPool);\n return providedPool;\n }\n\n const baseConfig = this.createPoolConfig(providedPool, connectionString);\n await this.databaseBootstrapper.ensure(baseConfig);\n this.databaseName = this.databaseBootstrapper.resolveDatabaseName(baseConfig);\n\n this.logger.info(chalk.gray('Creating new Postgres pool.'));\n return new Pool(baseConfig);\n }\n\n private createPoolConfig(poolConfig?: PoolConfig, connectionString?: string): PoolConfig {\n const config: PoolConfig = poolConfig ? { ...poolConfig } : {};\n\n if (connectionString) {\n config.connectionString = connectionString;\n }\n\n if (this.options.forceInsecureSSL) {\n config.ssl = { rejectUnauthorized: false };\n }\n\n return config;\n }\n\n private registerOnConnectStatements(pool: Pool, statements?: string[]): void {\n if (!statements?.length) return;\n\n const queuedStatements = [...statements];\n pool.on('connect', (client) => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })();\n });\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","import { CustomError, throwCustomError, DatabaseError } from 'seedcord';\n\n/**\n * Catches and wraps database operation errors.\n *\n * Wraps non-CustomError exceptions in DatabaseError instances\n * with UUID tracking. Should be applied to database service methods.\n *\n * @typeParam TypeReturn - The return type of the decorated method\n * @param errorMessage - Message to include when wrapping errors\n * @decorator\n * @example\n * ```typescript\n * class UserService extends MongoService<IUser> {\n * \\@WrapDatabaseError('Failed to find user')\n * async findById(id: string) {\n * return this.model.findById(id);\n * }\n * }\n * ```\n *\n * @see {@link DatabaseError}\n * @see {@link CustomError}\n * @see {@link MongoService}\n */\nexport function WrapDatabaseError<TypeReturn>(errorMessage: string) {\n return function (\n _target: unknown,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>\n ): void {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]): Promise<TypeReturn> {\n if (!originalMethod) {\n throw new Error('Method not found');\n }\n\n try {\n return await originalMethod.apply(this, args);\n } catch (error) {\n if (!(error instanceof CustomError)) {\n throwCustomError(error, errorMessage, DatabaseError);\n } else {\n throw error;\n }\n }\n };\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/shared/WrapDatabaseError.ts"],"names":["ServiceMetadataKey","Symbol","RegisterMongoService","key","ctor","Reflect","defineMetadata","ModelMetadataKey","RegisterMongoModel","collection","target","propertyKey","schema","name","String","model","mongoose","MongoService","db","core","getMetadata","SeedcordError","SeedcordErrorCode","PluginMongoServiceDecoratorMissing","PluginMongoModelDecoratorMissing","_register","Mongo","Plugin","logger","Logger","isInitialised","uri","services","options","shutdown","addTask","ShutdownPhase","ExternalResources","stop","timeout","init","connect","loadServices","disconnect","connection","dbName","Envapter","isProduction","tls","ssl","keepDefined","connectionOptions","then","conn","info","chalk","green","bold","magenta","catch","err","PluginMongoConnectionFailed","cause","red","error","message","servicesDir","dir","traverseDirectory","_full","rel","mod","Service","Object","values","isServiceClass","instance","italic","yellow","gray","keys","length","obj","prototype","hasMetadata","KpgDatabaseBootstrapper","ADMIN_DB","DATABASE_EXISTS_SQL","resolveDatabaseName","config","parseDatabaseName","resolveDatabaseFromPool","pool","database","connectionString","ensure","baseConfig","targetDb","adminConfig","buildAdminConfig","warn","adminPool","Pool","exists","databaseExists","createDatabase","Error","end","applyDatabaseToConnectionString","client","rows","query","Boolean","release","createSql","escapeIdentifier","trim","url","URL","pathname","replace","candidate","split","decodeURIComponent","encodeURIComponent","toString","identifier","KpgMigrationManager","ctx","migrate","direction","steps","label","NO_MIGRATIONS","runMigration","migrator","migrateTo","migrateToLatest","stepCount","Number","isInteger","SeedcordRangeError","PluginKpgInvalidStepCount","logMigrationResults","runner","migrateUp","migrateDown","runStepwise","PluginKpgUnknownDirection","listMigrations","createMigrator","getMigrations","runningMessage","results","handleMigrationError","directionLabel","countLabel","aggregated","encounteredError","index","push","provider","getMigrationProvider","Migrator","allowUnorderedMigrations","path","resolvedTarget","Array","isArray","map","entry","resolvePath","logMigrationFiles","createModuleProvider","migrationStat","fs","stat","undefined","isDirectory","directory","relativePath","FileMigrationProvider","migrationFolder","isFile","join","PluginKpgUnresolvedMigrationsPath","files","PluginKpgNoMigrationFiles","comparator","nameComparator","nameA","nameB","localeCompare","entries","Promise","all","filePath","moduleUrl","pathToFileURL","href","isMigrationModule","PluginKpgInvalidMigrationModule","up","down","basename","migration","sorted","sort","a","b","logPreparedMigrations","resolve","fromEntries","file","result","status","migrationName","relative","baseDir","startsWith","isAbsolute","inspect","PluginKpgNonErrorFailure","value","PgServiceMetadataKey","PgTableMetadataKey","RegisterKpgService","tableName","table","KpgService","kysely","PluginKpgServiceDecoratorMissing","PluginKpgServiceTableMissing","KpgServiceRegistry","create","plugin","register","loadFromDirectory","KyselyPg","migrationManager","serviceRegistry","databaseBootstrapper","databaseName","startupConfig","migrations","onStartup","resolvePool","registerOnConnectStatements","onConnectSQL","testPoolConnection","Kysely","dialect","PostgresDialect","process","cwd","dbLabel","getMigrationManager","listPendingMigrations","filter","m","executedAt","manager","providedPool","createPoolConfig","poolConfig","forceInsecureSSL","rejectUnauthorized","statements","queuedStatements","on","sql","WrapDatabaseError","errorMessage","_target","_propertyKey","descriptor","originalMethod","args","DecoratorMethodNotFound","apply","CustomError","throwCustomError","DatabaseError"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { MongoService } from '../MongoService';\nimport type { MongoServiceKeys } from '../types/MongoServices';\nimport type { Constructor } from 'type-fest';\n\nexport const ServiceMetadataKey = Symbol('db:serviceKey');\n\n/**\n * Registers a database service with a typed key\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TService - The service key type\n * @param key - Service key for registration and type-safe access\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users<Doc extends IUser = IUser> extends MongoService<Doc> {\n * // Some code\n * }\n * ```\n */\nexport function RegisterMongoService<TService extends MongoServiceKeys>(key: TService) {\n return <DatabaseCtor extends Constructor<unknown> & { prototype: MongoService }>(ctor: DatabaseCtor): void => {\n Reflect.defineMetadata(ServiceMetadataKey, key, ctor);\n };\n}\n","import mongoose from 'mongoose';\n\nimport type { MongoServiceKeys } from '../types/MongoServices';\n\nexport const ModelMetadataKey = Symbol('db:model');\n\n/**\n * Associates a Mongoose model with a database service\n *\n * Creates a Mongoose model from the decorated static schema property and stores it\n * for service registration. The model becomes available as `this.model` in the service.\n * Must be applied to a `public static schema` property in the service class.\n *\n * @typeParam TService - The service key type\n * @param collection - Collection name for the Mongoose model\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n * }\n * ```\n */\nexport function RegisterMongoModel<TService extends MongoServiceKeys>(collection: TService) {\n return <\n SchemaObj extends Record<KeyOfSchema, mongoose.Schema>,\n KeyOfSchema extends keyof SchemaObj & (string | symbol)\n >(\n target: SchemaObj,\n propertyKey: KeyOfSchema\n ): void => {\n const schema = target[propertyKey];\n const name = String(collection);\n const model = mongoose.model(name, schema);\n Reflect.defineMetadata(ModelMetadataKey, model, target);\n };\n}\n","import { SeedcordError, SeedcordErrorCode } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\n\nimport type { Mongo } from './Mongo';\nimport type { MongoDocument } from './types/MongoDocument';\nimport type { MongoServices } from './types/MongoServices';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type mongoose from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * Base class for MongoDB service layers\n *\n * Provides typed access to MongoDB collections through Mongoose models.\n * Services are automatically registered with the Mongo plugin when instantiated.\n *\n * @typeParam Doc - The document type this service manages\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n *\n * // Custom methods here\n * public async findByUsername(username: string) {\n * return this.model.findOne({ username });\n * }\n * }\n * ```\n */\nexport abstract class MongoService<Doc extends MongoDocument = MongoDocument> {\n public readonly model: mongoose.Model<Doc>;\n\n public constructor(\n protected readonly db: Mongo,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n if (!key) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServiceDecoratorMissing, [ctor.name]);\n }\n\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<Doc> | undefined;\n if (!model) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoModelDecoratorMissing, [ctor.name]);\n }\n\n this.model = model;\n\n db._register(key as keyof MongoServices, this as unknown as MongoServices[keyof MongoServices]);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport {\n keepDefined,\n Logger,\n Plugin,\n SeedcordError,\n SeedcordErrorCode,\n ShutdownPhase,\n traverseDirectory\n} from 'seedcord';\n\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\nimport { MongoService } from './MongoService';\n\nimport type { MongoServiceConstructor } from './MongoService';\nimport type { MongoOptions } from './types/MongoOptions';\nimport type { MongoServices } from './types/MongoServices';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * MongoDB integration plugin for Seedcord.\n *\n * Manages MongoDB connections, service loading, and provides type-safe\n * access to database services through service registration decorators.\n */\nexport class Mongo extends Plugin {\n public readonly logger = new Logger('Mongo');\n private isInitialised = false;\n private readonly uri: string;\n\n /**\n * Map of all loaded services.\n * Keys come from `@RegisterMongoService('key')`\n */\n public readonly services: MongoServices = {} as MongoServices;\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n\n constructor(\n public readonly core: Core,\n private readonly options: MongoOptions\n ) {\n super(core);\n this.uri = options.uri;\n\n this.core.shutdown.addTask(\n ShutdownPhase.ExternalResources,\n 'stop-database',\n async () => await this.stop(),\n this.options.timeout\n );\n }\n\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n await this.loadServices();\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.connection = await mongoose\n .connect(this.uri, {\n dbName: this.options.name,\n ...(Envapter.isProduction && { tls: true, ssl: true }),\n ...keepDefined(this.options.connectionOptions ?? {})\n })\n .then((conn) => {\n this.logger.info(chalk.green.bold(`Connected to MongoDB: ${chalk.magenta.bold(conn.connection.name)}`));\n return conn;\n })\n .catch((err) => {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoConnectionFailed, [this.options.name], {\n cause: err\n });\n });\n }\n\n private async disconnect(): Promise<void> {\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`));\n }\n\n private async loadServices(): Promise<void> {\n const servicesDir = this.options.dir;\n this.logger.info(chalk.bold(servicesDir));\n\n await traverseDirectory(\n servicesDir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is MongoServiceConstructor {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof MongoService &&\n Reflect.hasMetadata(ServiceMetadataKey, obj)\n );\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register<SKey extends keyof MongoServices>(key: SKey, instance: MongoServices[SKey]): void {\n this.services[key] = instance;\n }\n}\n","import chalk from 'chalk';\nimport { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from 'seedcord';\n\n/**\n * Handles ensuring the target Postgres database exists, creating it if necessary.\n */\nexport class KpgDatabaseBootstrapper {\n private static readonly ADMIN_DB = 'postgres';\n private static readonly DATABASE_EXISTS_SQL =\n 'SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname = $1) AS \"exists\"';\n\n constructor(private readonly logger: Logger) {}\n\n public resolveDatabaseName(config: PoolConfig): string | null {\n return KpgDatabaseBootstrapper.parseDatabaseName(config);\n }\n\n public resolveDatabaseFromPool(pool: Pool): string | null {\n const config: PoolConfig = {};\n\n const { options } = pool;\n\n if (typeof options.database === 'string') {\n config.database = options.database;\n }\n\n if (typeof options.connectionString === 'string') {\n config.connectionString = options.connectionString;\n }\n\n return this.resolveDatabaseName(config);\n }\n\n public async ensure(baseConfig: PoolConfig): Promise<void> {\n const targetDb = this.resolveDatabaseName(baseConfig);\n if (!targetDb) {\n this.logger.info(chalk.gray('Skipping database existence check (no database specified).'));\n return;\n }\n\n if (targetDb === KpgDatabaseBootstrapper.ADMIN_DB) {\n this.logger.info(chalk.gray('Target database is postgres; skipping creation.'));\n return;\n }\n\n const adminConfig = this.buildAdminConfig(baseConfig);\n if (!adminConfig) {\n this.logger.warn(`Unable to derive admin connection when ensuring database ${targetDb}`);\n return;\n }\n\n this.logger.info(chalk.gray(`Ensuring database ${chalk.yellow(targetDb)} exists...`));\n\n const adminPool = new Pool(adminConfig);\n\n try {\n const exists = await this.databaseExists(adminPool, targetDb);\n if (exists) {\n this.logger.info(chalk.gray(`Database ${chalk.yellow(targetDb)} already exists.`));\n return;\n }\n\n await this.createDatabase(adminPool, targetDb);\n this.logger.info(chalk.green(`Created database ${chalk.bold(targetDb)}.`));\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to ensure database ${targetDb}: ${err.message}`);\n throw err;\n } finally {\n await adminPool.end();\n }\n }\n\n private buildAdminConfig(baseConfig: PoolConfig): PoolConfig | null {\n const adminConfig: PoolConfig = { ...baseConfig };\n\n const { connectionString } = adminConfig;\n if (connectionString) {\n const connection = KpgDatabaseBootstrapper.applyDatabaseToConnectionString(\n connectionString,\n KpgDatabaseBootstrapper.ADMIN_DB\n );\n if (!connection) return null;\n adminConfig.connectionString = connection;\n }\n\n adminConfig.database = KpgDatabaseBootstrapper.ADMIN_DB;\n return adminConfig;\n }\n\n private async databaseExists(pool: Pool, database: string): Promise<boolean> {\n const client = await pool.connect();\n try {\n const { rows } = await client.query<{ exists: boolean }>(KpgDatabaseBootstrapper.DATABASE_EXISTS_SQL, [\n database\n ]);\n return Boolean(rows[0]?.exists);\n } finally {\n client.release();\n }\n }\n\n private async createDatabase(pool: Pool, database: string): Promise<void> {\n const client = await pool.connect();\n try {\n const createSql = `CREATE DATABASE ${KpgDatabaseBootstrapper.escapeIdentifier(database)}`;\n await client.query(createSql);\n } finally {\n client.release();\n }\n }\n\n private static parseDatabaseName(config: PoolConfig): string | null {\n if (typeof config.database === 'string' && config.database.trim().length > 0) {\n return config.database.trim();\n }\n\n const connectionString = config.connectionString;\n if (!connectionString) return null;\n\n try {\n const url = new URL(connectionString);\n const pathname = url.pathname.replace(/^\\//, '');\n if (!pathname) return null;\n const [candidate] = pathname.split('/');\n return candidate ? decodeURIComponent(candidate) : null;\n } catch {\n return null;\n }\n }\n\n private static applyDatabaseToConnectionString(connectionString: string, database: string): string | null {\n try {\n const url = new URL(connectionString);\n url.pathname = `/${encodeURIComponent(database)}`;\n return url.toString();\n } catch {\n return null;\n }\n }\n\n private static escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { inspect } from 'node:util';\n\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely';\nimport { SeedcordError, SeedcordErrorCode, SeedcordRangeError } from 'seedcord';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type { Migration, MigrationInfo, MigrationProvider, MigrationResult, MigrationResultSet } from 'kysely';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n */\nexport class KpgMigrationManager<Database extends object> {\n constructor(private readonly ctx: MigrationManagerContext<Database>) {}\n\n public async migrate(options?: MigrationOptions): Promise<void> {\n const { target, direction = 'latest', steps } = options ?? {};\n\n if (typeof target !== 'undefined') {\n const label = target === NO_MIGRATIONS ? 'NO_MIGRATIONS' : target;\n await this.runMigration((migrator) => migrator.migrateTo(target), `Migrating to ${chalk.yellow(label)}...`);\n return;\n }\n\n switch (direction) {\n case 'latest':\n await this.runMigration((migrator) => migrator.migrateToLatest());\n return;\n case 'up':\n case 'down': {\n const stepCount = steps ?? 1;\n if (!Number.isInteger(stepCount) || stepCount < 0) {\n throw new SeedcordRangeError(SeedcordErrorCode.PluginKpgInvalidStepCount);\n }\n\n if (stepCount === 0) {\n this.logMigrationResults([]);\n return;\n }\n\n const runner =\n direction === 'up'\n ? (migrator: Migrator) => migrator.migrateUp()\n : (migrator: Migrator) => migrator.migrateDown();\n await this.runStepwise(stepCount, direction, runner);\n return;\n }\n default:\n throw new SeedcordError(SeedcordErrorCode.PluginKpgUnknownDirection, [direction]);\n }\n }\n\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'up' });\n return;\n }\n\n await this.migrate({ direction: 'up', steps: options.steps });\n }\n\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'down' });\n return;\n }\n\n await this.migrate({ direction: 'down', steps: options.steps });\n }\n\n public async listMigrations(): Promise<readonly MigrationInfo[]> {\n const migrator = await this.createMigrator();\n return migrator.getMigrations();\n }\n\n private async runMigration(\n runner: (migrator: Migrator) => Promise<MigrationResultSet>,\n runningMessage = 'Running migrations...'\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n this.ctx.logger.info(chalk.gray(runningMessage));\n const { error, results } = await runner(migrator);\n\n this.logMigrationResults(results ?? []);\n\n if (error) {\n this.handleMigrationError(error);\n }\n }\n\n private async runStepwise(\n steps: number,\n direction: 'up' | 'down',\n runner: (migrator: Migrator) => Promise<MigrationResultSet>\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n const directionLabel = direction === 'up' ? 'Running' : 'Reverting';\n const countLabel = steps === 1 ? 'one migration' : `${chalk.yellow(String(steps))} migrations`;\n this.ctx.logger.info(chalk.gray(`${directionLabel} ${countLabel}...`));\n\n const aggregated: MigrationResult[] = [];\n let encounteredError: unknown;\n\n for (let index = 0; index < steps; index += 1) {\n const { error, results } = await runner(migrator);\n\n if (results?.length) {\n aggregated.push(...results);\n }\n\n if (error) {\n encounteredError = error;\n break;\n }\n\n if (!results?.length) {\n break;\n }\n }\n\n this.logMigrationResults(aggregated);\n\n if (encounteredError) {\n this.handleMigrationError(encounteredError);\n }\n }\n\n private async createMigrator(): Promise<Migrator> {\n const provider = await this.getMigrationProvider();\n const { config } = this.ctx;\n\n return new Migrator({\n db: this.ctx.db,\n provider,\n allowUnorderedMigrations: config.allowUnorderedMigrations ?? false,\n ...keepDefined(config, 'migrationTableName', 'migrationLockTableName', 'migrationTableSchema')\n });\n }\n\n private async getMigrationProvider(): Promise<MigrationProvider> {\n const { path: target } = this.ctx.config;\n const resolvedTarget = Array.isArray(target)\n ? target.map((entry) => this.resolvePath(entry))\n : this.resolvePath(target);\n\n if (Array.isArray(resolvedTarget)) {\n this.logMigrationFiles(resolvedTarget);\n return this.createModuleProvider(resolvedTarget);\n }\n\n let migrationStat: Stats | undefined;\n try {\n migrationStat = await fs.stat(resolvedTarget);\n } catch {\n migrationStat = undefined;\n }\n\n if (migrationStat?.isDirectory()) {\n const directory = this.relativePath(resolvedTarget);\n this.ctx.logger.info(chalk.gray(`Loading migrations directory ${chalk.yellow(directory)}`));\n return new FileMigrationProvider({ fs, path, migrationFolder: resolvedTarget });\n }\n\n if (migrationStat?.isFile() ?? true) {\n this.logMigrationFiles([resolvedTarget]);\n return this.createModuleProvider([resolvedTarget]);\n }\n\n const label = Array.isArray(target) ? target.join(', ') : target;\n throw new SeedcordError(SeedcordErrorCode.PluginKpgUnresolvedMigrationsPath, [label]);\n }\n\n private async createModuleProvider(files: string[]): Promise<MigrationProvider> {\n if (files.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgNoMigrationFiles);\n }\n\n const comparator =\n this.ctx.config.nameComparator ?? ((nameA: string, nameB: string) => nameA.localeCompare(nameB));\n\n const entries = await Promise.all(\n files.map(async (filePath) => {\n const moduleUrl = pathToFileURL(filePath).href;\n const mod: unknown = await import(moduleUrl);\n\n if (!this.isMigrationModule(mod)) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgInvalidMigrationModule, [filePath]);\n }\n\n const { up, down } = mod;\n\n const name = path.basename(filePath);\n\n const migration: Migration = {\n async up(db) {\n await up(db);\n },\n async down(db) {\n await down(db);\n }\n };\n\n return [name, migration] as const;\n })\n );\n\n const sorted = entries.sort(([a], [b]) => comparator(a, b));\n this.logPreparedMigrations(sorted);\n\n return {\n getMigrations: () => Promise.resolve(Object.fromEntries(sorted))\n } satisfies MigrationProvider;\n }\n\n private logMigrationFiles(files: readonly string[]): void {\n if (!files.length) return;\n\n this.ctx.logger.info('Loading migration file(s):');\n for (const file of files) {\n this.ctx.logger.info(`→ ${chalk.yellow(this.relativePath(file))}`);\n }\n }\n\n private logPreparedMigrations(entries: readonly (readonly [string, Migration])[]): void {\n if (!entries.length) return;\n\n this.ctx.logger.info('Prepared migrations:');\n for (const [name] of entries) {\n this.ctx.logger.info(`→ ${chalk.green(name)}`);\n }\n }\n\n private logMigrationResults(results: readonly MigrationResult[]): void {\n if (!results.length) {\n this.ctx.logger.info(chalk.gray('No migrations executed.'));\n return;\n }\n\n this.ctx.logger.info('Migration results:');\n\n for (const result of results) {\n if (result.status === 'Success') {\n this.ctx.logger.info(`${chalk.green('✓')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n if (result.status === 'Error') {\n this.ctx.logger.error(`${chalk.red('✗')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n this.ctx.logger.info(`${chalk.yellow('•')} ${chalk.bold(result.migrationName)} ${chalk.gray('(skipped)')}`);\n }\n }\n\n private relativePath(filePath: string): string {\n const relative = path.relative(this.ctx.baseDir, filePath);\n return relative.startsWith('..') ? filePath : relative;\n }\n\n private resolvePath(target: string): string {\n if (path.isAbsolute(target)) return target;\n return path.resolve(this.ctx.baseDir, target);\n }\n\n private handleMigrationError(error: unknown): never {\n const message = error instanceof Error ? error.message : inspect(error);\n this.ctx.logger.error(`Migration failure: ${message}`);\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new SeedcordError(SeedcordErrorCode.PluginKpgNonErrorFailure, [message]);\n }\n\n private isMigrationModule(value: unknown): value is MigrationModule {\n if (!value || typeof value !== 'object') return false;\n if (!('up' in value) || !('down' in value)) return false;\n\n const { up, down } = value as { up: unknown; down: unknown };\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import type { KpgServiceRegistrationOptions } from '../types/KpgServiceRegistrationOptions';\nimport type { KpgServices, KpgServiceKeys } from '../types/KpgServices';\nimport type { Constructor } from 'type-fest';\n\nexport const PgServiceMetadataKey = Symbol('db:pgServiceKey');\nexport const PgTableMetadataKey = Symbol('db:pgTable');\n\n/**\n *\n * Registers a Kysely PG service with the specified key and options.\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TKey - The service key type\n * @param key - Service key for registration and type-safe access\n * @param options - Additional registration options\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterKpgService('users', { table: 'app_users' })\n * export class UsersService extends KpgService<{ users: IUser }, 'users'> {\n * // Some code\n * }\n * ```\n *\n * @see {@link KpgService}\n */\nexport function RegisterKpgService<TKey extends KpgServiceKeys>(key: TKey, options?: KpgServiceRegistrationOptions) {\n return <Ctor extends Constructor<KpgServices[TKey]>>(ctor: Ctor): void => {\n Reflect.defineMetadata(PgServiceMetadataKey, key, ctor);\n\n const tableName = options?.table ?? String(key);\n Reflect.defineMetadata(PgTableMetadataKey, tableName, ctor);\n };\n}\n","import { SeedcordError, SeedcordErrorCode } from 'seedcord';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServices } from './types/KpgServices';\nimport type { Kysely } from 'kysely';\nimport type { Core, TypedConstructor } from 'seedcord';\n\n/**\n * Base class for KyselyPg services.\n *\n * Provides a small, typed shim around the shared Kysely instance and ensures\n * that subclasses have been decorated with `@RegisterKpgService`.\n *\n * @typeParam Database - The database shape used by Kysely (tables as keys).\n * @typeParam TTable - The specific table key from `Database` this service works with.\n *\n * @example\n * ```typescript\n * \\@RegisterKpgService('users')\n * export class UsersService extends KpgService<ImportedDatabaseInterface, 'users'> {\n * public async findById(id: string) {\n * return this.entity\n * .selectFrom(this.table)\n * .selectAll().where('id', '=', id)\n * .executeTakeFirst();\n * }\n * }\n *\n * // Usage inside handlers:\n * const user = await this.core.db.services.users.findById('abc');\n * ```\n */\nexport abstract class KpgService<Database extends object, TTable extends keyof Database & string> {\n public readonly table: TTable;\n\n public constructor(\n protected readonly kysely: KyselyPg<Database>,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n if (!key) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceDecoratorMissing, [ctor.name]);\n }\n\n const table = Reflect.getMetadata(PgTableMetadataKey, ctor) as TTable | undefined;\n\n // This check should always pass since TTable is derived from the key if a table is not provided explicitly.\n if (!table) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceTableMissing, [ctor.name]);\n }\n\n this.table = table;\n this.kysely._register(key as keyof KpgServices, this as unknown as AnyKpgService);\n }\n\n /**\n * Shared Kysely instance used to interact with the Postgres database.\n */\n public get db(): Kysely<Database> {\n return this.kysely.connection;\n }\n}\n\n/** Constructor type for {@link KpgService} classes */\nexport type KyselyServiceConstructor<Database extends object = object> = TypedConstructor<\n typeof KpgService<Database, keyof Database & string>\n>;\n","import chalk from 'chalk';\nimport { traverseDirectory } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { Core, Logger } from 'seedcord';\n\n/**\n * Discovers and registers Postgres services for the plugin.\n */\nexport class KpgServiceRegistry<Database extends object> {\n private readonly services: Record<string, AnyKpgService> = Object.create(null) as Record<string, AnyKpgService>;\n\n constructor(\n private readonly plugin: KyselyPg<Database>,\n private readonly core: Core,\n private readonly logger: Logger\n ) {}\n\n public get map(): KpgServices {\n return this.services as unknown as KpgServices;\n }\n\n public register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.services[key] = instance;\n }\n\n public async loadFromDirectory(dir: string): Promise<void> {\n this.logger.info(chalk.bold(dir));\n\n await traverseDirectory(\n dir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this.plugin, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is KyselyServiceConstructor<Database> {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof KpgService &&\n Reflect.hasMetadata(PgServiceMetadataKey, obj)\n );\n }\n}\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig } from 'pg';\nimport { keepDefined, Logger, Plugin, ShutdownPhase } from 'seedcord';\n\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { MigrationInfo } from 'kysely';\nimport type { Core } from 'seedcord';\n\n/**\n * Postgres plugin using Kysely.\n *\n * Handles setting up the connection pool, applying migrations, and\n * registering decorated services so they can be resolved from the core.\n */\nexport class KyselyPg<Database extends object> extends Plugin {\n public readonly logger = new Logger('KyselyPg');\n private isInitialised = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private migrationManager: KpgMigrationManager<Database> | null = null;\n private readonly serviceRegistry: KpgServiceRegistry<Database>;\n private readonly databaseBootstrapper: KpgDatabaseBootstrapper;\n private databaseName: string | null = null;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n return this.serviceRegistry.map;\n }\n\n constructor(\n public readonly core: Core,\n private readonly options: KpgOptions\n ) {\n super(core);\n this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);\n this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);\n this.core.shutdown.addTask(\n ShutdownPhase.ExternalResources,\n 'stop-kyselypg',\n async () => await this.stop(),\n this.options.timeout\n );\n }\n\n /**\n * Connects to Postgres, runs any startup migrations, and loads decorated services.\n *\n * Safe to call multiple times; subsequent calls exit early.\n */\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n\n const startupConfig = this.options.migrations.onStartup;\n if (startupConfig !== false) {\n if (startupConfig && typeof startupConfig !== 'boolean') {\n await this.migrate(startupConfig);\n } else {\n await this.migrate();\n }\n }\n await this.serviceRegistry.loadFromDirectory(this.options.dir);\n }\n\n /**\n * Tears down the connection pool and clears the migration manager reference.\n */\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n const pool = await this.resolvePool();\n this.pool = pool;\n\n this.registerOnConnectStatements(pool, this.options.onConnectSQL);\n\n try {\n await this.testPoolConnection(pool);\n\n this.connection = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n ...keepDefined(this.options.kysely ?? {})\n });\n\n this.migrationManager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n const dbLabel = this.databaseName ?? 'unknown';\n this.logger.info(`Connected to Postgres database ${chalk.bold.magenta(dbLabel)}`);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.logger.error(`Could not connect to Postgres: ${error.message}`);\n throw error;\n }\n }\n\n private async disconnect(): Promise<void> {\n const pool = this.pool;\n if (!pool) return;\n\n this.pool = null;\n this.migrationManager = null;\n\n this.logger.info(chalk.gray('Closing Postgres pool.'));\n await pool.end().catch((err) => {\n this.logger.error(`Could not close pg pool: ${(err as Error).message}`);\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options or defaults to `latest`.\n *\n * @param options - Target migration or direction overrides\n */\n public async migrate(options?: MigrationOptions): Promise<void> {\n await this.getMigrationManager().migrate(options);\n }\n\n /**\n * Runs a single upwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateUp(options);\n }\n\n /**\n * Runs a single downwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateDown(options);\n }\n\n /**\n * Lists every migration the manager knows about along with its execution state.\n */\n public listMigrations(): Promise<readonly MigrationInfo[]> {\n return this.getMigrationManager().listMigrations();\n }\n\n /**\n * Lists unapplied migrations.\n */\n public async listPendingMigrations(): Promise<MigrationInfo[]> {\n const all = await this.listMigrations();\n return all.filter((m) => !m.executedAt);\n }\n\n private getMigrationManager(): KpgMigrationManager<Database> {\n if (this.migrationManager) return this.migrationManager;\n\n const manager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n this.migrationManager = manager;\n return manager;\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.serviceRegistry.register(key, instance);\n }\n\n private async resolvePool(): Promise<Pool> {\n const { pool: providedPool, connectionString } = this.options;\n\n if (providedPool instanceof Pool) {\n this.logger.info(chalk.gray('Reusing provided Postgres pool instance.'));\n this.databaseName = this.databaseBootstrapper.resolveDatabaseFromPool(providedPool);\n return providedPool;\n }\n\n const baseConfig = this.createPoolConfig(providedPool, connectionString);\n await this.databaseBootstrapper.ensure(baseConfig);\n this.databaseName = this.databaseBootstrapper.resolveDatabaseName(baseConfig);\n\n this.logger.info(chalk.gray('Creating new Postgres pool.'));\n return new Pool(baseConfig);\n }\n\n private createPoolConfig(poolConfig?: PoolConfig, connectionString?: string): PoolConfig {\n const config: PoolConfig = poolConfig ? { ...poolConfig } : {};\n\n if (connectionString) {\n config.connectionString = connectionString;\n }\n\n if (this.options.forceInsecureSSL) {\n config.ssl = { rejectUnauthorized: false };\n }\n\n return config;\n }\n\n private registerOnConnectStatements(pool: Pool, statements?: string[]): void {\n if (!statements?.length) return;\n\n const queuedStatements = [...statements];\n pool.on('connect', (client) => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })();\n });\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","import { CustomError, DatabaseError, SeedcordError, SeedcordErrorCode, throwCustomError } from 'seedcord';\n\n/**\n * Catches and wraps database operation errors.\n *\n * Wraps non-CustomError exceptions in DatabaseError instances\n * with UUID tracking. Should be applied to database service methods.\n *\n * @typeParam TypeReturn - The return type of the decorated method\n * @param errorMessage - Message to include when wrapping errors\n * @decorator\n * @example\n * ```typescript\n * class UserService extends MongoService<IUser> {\n * \\@WrapDatabaseError('Failed to find user')\n * async findById(id: string) {\n * return this.model.findById(id);\n * }\n * }\n * ```\n *\n * @see {@link DatabaseError}\n * @see {@link CustomError}\n * @see {@link MongoService}\n */\nexport function WrapDatabaseError<TypeReturn>(errorMessage: string) {\n return function (\n _target: unknown,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>\n ): void {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]): Promise<TypeReturn> {\n if (!originalMethod) {\n throw new SeedcordError(SeedcordErrorCode.DecoratorMethodNotFound);\n }\n\n try {\n return await originalMethod.apply(this, args);\n } catch (error) {\n if (!(error instanceof CustomError)) {\n throwCustomError(error, errorMessage, DatabaseError);\n } else {\n throw error;\n }\n }\n };\n };\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -8,6 +8,7 @@ import { KyselyConfig, Kysely, NO_MIGRATIONS, Migration, MigrationInfo } from 'k
8
8
  /**
9
9
  * Configuration options for MongoDB connection and service loading.
10
10
  */
11
+
11
12
  interface MongoOptions {
12
13
  /** Directory path containing database service classes */
13
14
  dir: string;
@@ -15,6 +16,10 @@ interface MongoOptions {
15
16
  uri: string;
16
17
  /** Database name to use */
17
18
  name: string;
19
+ /** mongoose connection options */
20
+ connectionOptions?: mongoose.ConnectOptions | undefined;
21
+ /** Plugin timeout in milliseconds */
22
+ timeout?: number;
18
23
  }
19
24
 
20
25
  /**
@@ -226,6 +231,8 @@ interface KpgOptions {
226
231
  readonly forceInsecureSSL?: boolean;
227
232
  /** Kysely config (excludes dialect because it's Postgres for this plugin) */
228
233
  readonly kysely?: TypedOmit<KyselyConfig, 'dialect'>;
234
+ /** Plugin timeout in milliseconds */
235
+ timeout?: number;
229
236
  }
230
237
 
231
238
  /**
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ import { KyselyConfig, Kysely, NO_MIGRATIONS, Migration, MigrationInfo } from 'k
8
8
  /**
9
9
  * Configuration options for MongoDB connection and service loading.
10
10
  */
11
+
11
12
  interface MongoOptions {
12
13
  /** Directory path containing database service classes */
13
14
  dir: string;
@@ -15,6 +16,10 @@ interface MongoOptions {
15
16
  uri: string;
16
17
  /** Database name to use */
17
18
  name: string;
19
+ /** mongoose connection options */
20
+ connectionOptions?: mongoose.ConnectOptions | undefined;
21
+ /** Plugin timeout in milliseconds */
22
+ timeout?: number;
18
23
  }
19
24
 
20
25
  /**
@@ -226,6 +231,8 @@ interface KpgOptions {
226
231
  readonly forceInsecureSSL?: boolean;
227
232
  /** Kysely config (excludes dialect because it's Postgres for this plugin) */
228
233
  readonly kysely?: TypedOmit<KyselyConfig, 'dialect'>;
234
+ /** Plugin timeout in milliseconds */
235
+ timeout?: number;
229
236
  }
230
237
 
231
238
  /**
package/dist/index.mjs CHANGED
@@ -2,13 +2,13 @@ import 'reflect-metadata';
2
2
  import chalk3 from 'chalk';
3
3
  import { Envapter } from 'envapt';
4
4
  import mongoose from 'mongoose';
5
- import { Plugin, Logger, ShutdownPhase, traverseDirectory, keepDefined as keepDefined$1, CustomError, throwCustomError, DatabaseError } from 'seedcord';
5
+ import { SeedcordError, SeedcordErrorCode, Plugin, Logger, ShutdownPhase, keepDefined, traverseDirectory, SeedcordRangeError, CustomError, throwCustomError, DatabaseError } from 'seedcord';
6
6
  import { Pool } from 'pg';
7
7
  import { promises } from 'fs';
8
8
  import path from 'path';
9
9
  import { pathToFileURL } from 'url';
10
10
  import { inspect } from 'util';
11
- import { keepDefined } from '@seedcord/utils';
11
+ import { keepDefined as keepDefined$1 } from '@seedcord/utils';
12
12
  import { Migrator, FileMigrationProvider, Kysely, PostgresDialect, NO_MIGRATIONS } from 'kysely';
13
13
 
14
14
  var __defProp = Object.defineProperty;
@@ -46,9 +46,17 @@ var MongoService = class {
46
46
  this.core = core;
47
47
  const ctor = this.constructor;
48
48
  const key = Reflect.getMetadata(ServiceMetadataKey, ctor);
49
- if (!key) throw new Error(`Missing @RegisterMongoService on ${ctor.name}`);
49
+ if (!key) {
50
+ throw new SeedcordError(SeedcordErrorCode.PluginMongoServiceDecoratorMissing, [
51
+ ctor.name
52
+ ]);
53
+ }
50
54
  const model = Reflect.getMetadata(ModelMetadataKey, ctor);
51
- if (!model) throw new Error(`Missing @RegisterMongoModel on ${ctor.name}`);
55
+ if (!model) {
56
+ throw new SeedcordError(SeedcordErrorCode.PluginMongoModelDecoratorMissing, [
57
+ ctor.name
58
+ ]);
59
+ }
52
60
  this.model = model;
53
61
  db._register(key, this);
54
62
  }
@@ -61,7 +69,7 @@ var Mongo = class extends Plugin {
61
69
  }
62
70
  core;
63
71
  options;
64
- logger = new Logger("MongoDB");
72
+ logger = new Logger("Mongo");
65
73
  isInitialised = false;
66
74
  uri;
67
75
  /**
@@ -72,7 +80,7 @@ var Mongo = class extends Plugin {
72
80
  constructor(core, options) {
73
81
  super(core), this.core = core, this.options = options;
74
82
  this.uri = options.uri;
75
- this.core.shutdown.addTask(ShutdownPhase.ExternalResources, "stop-database", async () => await this.stop());
83
+ this.core.shutdown.addTask(ShutdownPhase.ExternalResources, "stop-database", async () => await this.stop(), this.options.timeout);
76
84
  }
77
85
  async init() {
78
86
  if (this.isInitialised) return;
@@ -89,12 +97,17 @@ var Mongo = class extends Plugin {
89
97
  ...Envapter.isProduction && {
90
98
  tls: true,
91
99
  ssl: true
92
- }
100
+ },
101
+ ...keepDefined(this.options.connectionOptions ?? {})
93
102
  }).then((conn) => {
94
103
  this.logger.info(chalk3.green.bold(`Connected to MongoDB: ${chalk3.magenta.bold(conn.connection.name)}`));
95
104
  return conn;
96
105
  }).catch((err) => {
97
- throw new Error(`Could not connect to MongoDB`, err);
106
+ throw new SeedcordError(SeedcordErrorCode.PluginMongoConnectionFailed, [
107
+ this.options.name
108
+ ], {
109
+ cause: err
110
+ });
98
111
  });
99
112
  }
100
113
  async disconnect() {
@@ -267,7 +280,7 @@ var KpgMigrationManager = class {
267
280
  case "down": {
268
281
  const stepCount = steps ?? 1;
269
282
  if (!Number.isInteger(stepCount) || stepCount < 0) {
270
- throw new Error("Migration step count must be a non-negative integer");
283
+ throw new SeedcordRangeError(SeedcordErrorCode.PluginKpgInvalidStepCount);
271
284
  }
272
285
  if (stepCount === 0) {
273
286
  this.logMigrationResults([]);
@@ -278,7 +291,9 @@ var KpgMigrationManager = class {
278
291
  return;
279
292
  }
280
293
  default:
281
- throw new Error(`Unknown migration direction: ${String(direction)}`);
294
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgUnknownDirection, [
295
+ direction
296
+ ]);
282
297
  }
283
298
  }
284
299
  async migrateUp(options) {
@@ -352,7 +367,7 @@ var KpgMigrationManager = class {
352
367
  db: this.ctx.db,
353
368
  provider,
354
369
  allowUnorderedMigrations: config.allowUnorderedMigrations ?? false,
355
- ...keepDefined(config, "migrationTableName", "migrationLockTableName", "migrationTableSchema")
370
+ ...keepDefined$1(config, "migrationTableName", "migrationLockTableName", "migrationTableSchema")
356
371
  });
357
372
  }
358
373
  async getMigrationProvider() {
@@ -386,18 +401,22 @@ var KpgMigrationManager = class {
386
401
  ]);
387
402
  }
388
403
  const label = Array.isArray(target) ? target.join(", ") : target;
389
- throw new Error(`Unable to resolve migrations at path: ${label}`);
404
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgUnresolvedMigrationsPath, [
405
+ label
406
+ ]);
390
407
  }
391
408
  async createModuleProvider(files) {
392
409
  if (files.length === 0) {
393
- throw new Error("No migration files provided");
410
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgNoMigrationFiles);
394
411
  }
395
412
  const comparator = this.ctx.config.nameComparator ?? ((nameA, nameB) => nameA.localeCompare(nameB));
396
413
  const entries = await Promise.all(files.map(async (filePath) => {
397
414
  const moduleUrl = pathToFileURL(filePath).href;
398
415
  const mod = await import(moduleUrl);
399
416
  if (!this.isMigrationModule(mod)) {
400
- throw new Error(`Migration file ${filePath} must export async functions up and down`);
417
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgInvalidMigrationModule, [
418
+ filePath
419
+ ]);
401
420
  }
402
421
  const { up, down } = mod;
403
422
  const name = path.basename(filePath);
@@ -442,14 +461,14 @@ var KpgMigrationManager = class {
442
461
  this.ctx.logger.info("Migration results:");
443
462
  for (const result of results) {
444
463
  if (result.status === "Success") {
445
- this.ctx.logger.info(` ${chalk3.green("\u2713")} ${chalk3.bold(result.migrationName)}`);
464
+ this.ctx.logger.info(`${chalk3.green("\u2713")} ${chalk3.bold(result.migrationName)}`);
446
465
  continue;
447
466
  }
448
467
  if (result.status === "Error") {
449
- this.ctx.logger.error(` ${chalk3.red("\u2717")} ${chalk3.bold(result.migrationName)}`);
468
+ this.ctx.logger.error(`${chalk3.red("\u2717")} ${chalk3.bold(result.migrationName)}`);
450
469
  continue;
451
470
  }
452
- this.ctx.logger.info(` ${chalk3.yellow("\u2022")} ${chalk3.bold(result.migrationName)} ${chalk3.gray("(skipped)")}`);
471
+ this.ctx.logger.info(`${chalk3.yellow("\u2022")} ${chalk3.bold(result.migrationName)} ${chalk3.gray("(skipped)")}`);
453
472
  }
454
473
  }
455
474
  relativePath(filePath) {
@@ -466,7 +485,9 @@ var KpgMigrationManager = class {
466
485
  if (error instanceof Error) {
467
486
  throw error;
468
487
  }
469
- throw new Error(message);
488
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgNonErrorFailure, [
489
+ message
490
+ ]);
470
491
  }
471
492
  isMigrationModule(value) {
472
493
  if (!value || typeof value !== "object") return false;
@@ -501,10 +522,16 @@ var KpgService = class {
501
522
  this.core = core;
502
523
  const ctor = this.constructor;
503
524
  const key = Reflect.getMetadata(PgServiceMetadataKey, ctor);
504
- if (!key) throw new Error(`Missing @RegisterKpgService on ${ctor.name}`);
525
+ if (!key) {
526
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceDecoratorMissing, [
527
+ ctor.name
528
+ ]);
529
+ }
505
530
  const table = Reflect.getMetadata(PgTableMetadataKey, ctor);
506
531
  if (!table) {
507
- throw new Error(`Missing table metadata for ${ctor.name}. Provide a table via @RegisterKpgService().`);
532
+ throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceTableMissing, [
533
+ ctor.name
534
+ ]);
508
535
  }
509
536
  this.table = table;
510
537
  this.kysely._register(key, this);
@@ -574,7 +601,7 @@ var KyselyPg = class extends Plugin {
574
601
  super(core), this.core = core, this.options = options;
575
602
  this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);
576
603
  this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);
577
- this.core.shutdown.addTask(ShutdownPhase.ExternalResources, "stop-kyselypg", async () => await this.stop());
604
+ this.core.shutdown.addTask(ShutdownPhase.ExternalResources, "stop-kyselypg", async () => await this.stop(), this.options.timeout);
578
605
  }
579
606
  /**
580
607
  * Connects to Postgres, runs any startup migrations, and loads decorated services.
@@ -611,7 +638,7 @@ var KyselyPg = class extends Plugin {
611
638
  dialect: new PostgresDialect({
612
639
  pool
613
640
  }),
614
- ...keepDefined$1(this.options.kysely ?? {})
641
+ ...keepDefined(this.options.kysely ?? {})
615
642
  });
616
643
  this.migrationManager = new KpgMigrationManager({
617
644
  db: this.connection,
@@ -744,7 +771,7 @@ function WrapDatabaseError(errorMessage) {
744
771
  const originalMethod = descriptor.value;
745
772
  descriptor.value = async function(...args) {
746
773
  if (!originalMethod) {
747
- throw new Error("Method not found");
774
+ throw new SeedcordError(SeedcordErrorCode.DecoratorMethodNotFound);
748
775
  }
749
776
  try {
750
777
  return await originalMethod.apply(this, args);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/shared/WrapDatabaseError.ts"],"names":["ServiceMetadataKey","Symbol","RegisterMongoService","key","ctor","Reflect","defineMetadata","ModelMetadataKey","RegisterMongoModel","collection","target","propertyKey","schema","name","String","model","mongoose","MongoService","db","core","getMetadata","Error","_register","Mongo","Plugin","logger","Logger","isInitialised","uri","services","options","shutdown","addTask","ShutdownPhase","ExternalResources","stop","init","connect","loadServices","disconnect","connection","dbName","Envapter","isProduction","tls","ssl","then","conn","info","chalk","green","bold","magenta","catch","err","red","error","message","servicesDir","dir","traverseDirectory","_full","rel","mod","Service","Object","values","isServiceClass","instance","italic","yellow","gray","keys","length","obj","prototype","hasMetadata","KpgDatabaseBootstrapper","ADMIN_DB","DATABASE_EXISTS_SQL","resolveDatabaseName","config","parseDatabaseName","resolveDatabaseFromPool","pool","database","connectionString","ensure","baseConfig","targetDb","adminConfig","buildAdminConfig","warn","adminPool","Pool","exists","databaseExists","createDatabase","end","applyDatabaseToConnectionString","client","rows","query","Boolean","release","createSql","escapeIdentifier","trim","url","URL","pathname","replace","candidate","split","decodeURIComponent","encodeURIComponent","toString","identifier","KpgMigrationManager","ctx","migrate","direction","steps","label","NO_MIGRATIONS","runMigration","migrator","migrateTo","migrateToLatest","stepCount","Number","isInteger","logMigrationResults","runner","migrateUp","migrateDown","runStepwise","listMigrations","createMigrator","getMigrations","runningMessage","results","handleMigrationError","directionLabel","countLabel","aggregated","encounteredError","index","push","provider","getMigrationProvider","Migrator","allowUnorderedMigrations","keepDefined","path","resolvedTarget","Array","isArray","map","entry","resolvePath","logMigrationFiles","createModuleProvider","migrationStat","fs","stat","undefined","isDirectory","directory","relativePath","FileMigrationProvider","migrationFolder","isFile","join","files","comparator","nameComparator","nameA","nameB","localeCompare","entries","Promise","all","filePath","moduleUrl","pathToFileURL","href","isMigrationModule","up","down","basename","migration","sorted","sort","a","b","logPreparedMigrations","resolve","fromEntries","file","result","status","migrationName","relative","baseDir","startsWith","isAbsolute","inspect","value","PgServiceMetadataKey","PgTableMetadataKey","RegisterKpgService","tableName","table","KpgService","kysely","KpgServiceRegistry","create","plugin","register","loadFromDirectory","KyselyPg","migrationManager","serviceRegistry","databaseBootstrapper","databaseName","startupConfig","migrations","onStartup","resolvePool","registerOnConnectStatements","onConnectSQL","testPoolConnection","Kysely","dialect","PostgresDialect","process","cwd","dbLabel","getMigrationManager","listPendingMigrations","filter","m","executedAt","manager","providedPool","createPoolConfig","poolConfig","forceInsecureSSL","rejectUnauthorized","statements","queuedStatements","on","sql","WrapDatabaseError","errorMessage","_target","_propertyKey","descriptor","originalMethod","args","apply","CustomError","throwCustomError","DatabaseError"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { MongoService } from '../MongoService';\nimport type { MongoServiceKeys } from '../types/MongoServices';\nimport type { Constructor } from 'type-fest';\n\nexport const ServiceMetadataKey = Symbol('db:serviceKey');\n\n/**\n * Registers a database service with a typed key\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TService - The service key type\n * @param key - Service key for registration and type-safe access\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users<Doc extends IUser = IUser> extends MongoService<Doc> {\n * // Some code\n * }\n * ```\n */\nexport function RegisterMongoService<TService extends MongoServiceKeys>(key: TService) {\n return <DatabaseCtor extends Constructor<unknown> & { prototype: MongoService }>(ctor: DatabaseCtor): void => {\n Reflect.defineMetadata(ServiceMetadataKey, key, ctor);\n };\n}\n","import mongoose from 'mongoose';\n\nimport type { MongoServiceKeys } from '../types/MongoServices';\n\nexport const ModelMetadataKey = Symbol('db:model');\n\n/**\n * Associates a Mongoose model with a database service\n *\n * Creates a Mongoose model from the decorated static schema property and stores it\n * for service registration. The model becomes available as `this.model` in the service.\n * Must be applied to a `public static schema` property in the service class.\n *\n * @typeParam TService - The service key type\n * @param collection - Collection name for the Mongoose model\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n * }\n * ```\n */\nexport function RegisterMongoModel<TService extends MongoServiceKeys>(collection: TService) {\n return <\n SchemaObj extends Record<KeyOfSchema, mongoose.Schema>,\n KeyOfSchema extends keyof SchemaObj & (string | symbol)\n >(\n target: SchemaObj,\n propertyKey: KeyOfSchema\n ): void => {\n const schema = target[propertyKey];\n const name = String(collection);\n const model = mongoose.model(name, schema);\n Reflect.defineMetadata(ModelMetadataKey, model, target);\n };\n}\n","import { ModelMetadataKey } from './decorators/RegisterMongoModel';\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\n\nimport type { Mongo } from './Mongo';\nimport type { MongoDocument } from './types/MongoDocument';\nimport type { MongoServices } from './types/MongoServices';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type mongoose from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * Base class for MongoDB service layers\n *\n * Provides typed access to MongoDB collections through Mongoose models.\n * Services are automatically registered with the Mongo plugin when instantiated.\n *\n * @typeParam Doc - The document type this service manages\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n *\n * // Custom methods here\n * public async findByUsername(username: string) {\n * return this.model.findOne({ username });\n * }\n * }\n * ```\n */\nexport abstract class MongoService<Doc extends MongoDocument = MongoDocument> {\n public readonly model: mongoose.Model<Doc>;\n\n public constructor(\n protected readonly db: Mongo,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n if (!key) throw new Error(`Missing @RegisterMongoService on ${ctor.name}`);\n\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<Doc> | undefined;\n if (!model) throw new Error(`Missing @RegisterMongoModel on ${ctor.name}`);\n\n this.model = model;\n\n db._register(key as keyof MongoServices, this as unknown as MongoServices[keyof MongoServices]);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { Logger, Plugin, ShutdownPhase, traverseDirectory } from 'seedcord';\n\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\nimport { MongoService } from './MongoService';\n\nimport type { MongoServiceConstructor } from './MongoService';\nimport type { MongoOptions } from './types/MongoOptions';\nimport type { MongoServices } from './types/MongoServices';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * MongoDB integration plugin for Seedcord.\n *\n * Manages MongoDB connections, service loading, and provides type-safe\n * access to database services through service registration decorators.\n */\nexport class Mongo extends Plugin {\n public readonly logger = new Logger('MongoDB');\n private isInitialised = false;\n private readonly uri: string;\n\n /**\n * Map of all loaded services.\n * Keys come from `@RegisterMongoService('key')`\n */\n public readonly services: MongoServices = {} as MongoServices;\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n\n constructor(\n public readonly core: Core,\n private readonly options: MongoOptions\n ) {\n super(core);\n this.uri = options.uri;\n\n this.core.shutdown.addTask(ShutdownPhase.ExternalResources, 'stop-database', async () => await this.stop());\n }\n\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n await this.loadServices();\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.connection = await mongoose\n .connect(this.uri, {\n dbName: this.options.name,\n ...(Envapter.isProduction && { tls: true, ssl: true })\n })\n .then((conn) => {\n this.logger.info(chalk.green.bold(`Connected to MongoDB: ${chalk.magenta.bold(conn.connection.name)}`));\n return conn;\n })\n .catch((err) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n throw new Error(`Could not connect to MongoDB`, err);\n });\n }\n\n private async disconnect(): Promise<void> {\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`));\n }\n\n private async loadServices(): Promise<void> {\n const servicesDir = this.options.dir;\n this.logger.info(chalk.bold(servicesDir));\n\n await traverseDirectory(\n servicesDir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is MongoServiceConstructor {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof MongoService &&\n Reflect.hasMetadata(ServiceMetadataKey, obj)\n );\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register<SKey extends keyof MongoServices>(key: SKey, instance: MongoServices[SKey]): void {\n this.services[key] = instance;\n }\n}\n","import chalk from 'chalk';\nimport { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from 'seedcord';\n\n/**\n * Handles ensuring the target Postgres database exists, creating it if necessary.\n */\nexport class KpgDatabaseBootstrapper {\n private static readonly ADMIN_DB = 'postgres';\n private static readonly DATABASE_EXISTS_SQL =\n 'SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname = $1) AS \"exists\"';\n\n constructor(private readonly logger: Logger) {}\n\n public resolveDatabaseName(config: PoolConfig): string | null {\n return KpgDatabaseBootstrapper.parseDatabaseName(config);\n }\n\n public resolveDatabaseFromPool(pool: Pool): string | null {\n const config: PoolConfig = {};\n\n const { options } = pool;\n\n if (typeof options.database === 'string') {\n config.database = options.database;\n }\n\n if (typeof options.connectionString === 'string') {\n config.connectionString = options.connectionString;\n }\n\n return this.resolveDatabaseName(config);\n }\n\n public async ensure(baseConfig: PoolConfig): Promise<void> {\n const targetDb = this.resolveDatabaseName(baseConfig);\n if (!targetDb) {\n this.logger.info(chalk.gray('Skipping database existence check (no database specified).'));\n return;\n }\n\n if (targetDb === KpgDatabaseBootstrapper.ADMIN_DB) {\n this.logger.info(chalk.gray('Target database is postgres; skipping creation.'));\n return;\n }\n\n const adminConfig = this.buildAdminConfig(baseConfig);\n if (!adminConfig) {\n this.logger.warn(`Unable to derive admin connection when ensuring database ${targetDb}`);\n return;\n }\n\n this.logger.info(chalk.gray(`Ensuring database ${chalk.yellow(targetDb)} exists...`));\n\n const adminPool = new Pool(adminConfig);\n\n try {\n const exists = await this.databaseExists(adminPool, targetDb);\n if (exists) {\n this.logger.info(chalk.gray(`Database ${chalk.yellow(targetDb)} already exists.`));\n return;\n }\n\n await this.createDatabase(adminPool, targetDb);\n this.logger.info(chalk.green(`Created database ${chalk.bold(targetDb)}.`));\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to ensure database ${targetDb}: ${err.message}`);\n throw err;\n } finally {\n await adminPool.end();\n }\n }\n\n private buildAdminConfig(baseConfig: PoolConfig): PoolConfig | null {\n const adminConfig: PoolConfig = { ...baseConfig };\n\n const { connectionString } = adminConfig;\n if (connectionString) {\n const connection = KpgDatabaseBootstrapper.applyDatabaseToConnectionString(\n connectionString,\n KpgDatabaseBootstrapper.ADMIN_DB\n );\n if (!connection) return null;\n adminConfig.connectionString = connection;\n }\n\n adminConfig.database = KpgDatabaseBootstrapper.ADMIN_DB;\n return adminConfig;\n }\n\n private async databaseExists(pool: Pool, database: string): Promise<boolean> {\n const client = await pool.connect();\n try {\n const { rows } = await client.query<{ exists: boolean }>(KpgDatabaseBootstrapper.DATABASE_EXISTS_SQL, [\n database\n ]);\n return Boolean(rows[0]?.exists);\n } finally {\n client.release();\n }\n }\n\n private async createDatabase(pool: Pool, database: string): Promise<void> {\n const client = await pool.connect();\n try {\n const createSql = `CREATE DATABASE ${KpgDatabaseBootstrapper.escapeIdentifier(database)}`;\n await client.query(createSql);\n } finally {\n client.release();\n }\n }\n\n private static parseDatabaseName(config: PoolConfig): string | null {\n if (typeof config.database === 'string' && config.database.trim().length > 0) {\n return config.database.trim();\n }\n\n const connectionString = config.connectionString;\n if (!connectionString) return null;\n\n try {\n const url = new URL(connectionString);\n const pathname = url.pathname.replace(/^\\//, '');\n if (!pathname) return null;\n const [candidate] = pathname.split('/');\n return candidate ? decodeURIComponent(candidate) : null;\n } catch {\n return null;\n }\n }\n\n private static applyDatabaseToConnectionString(connectionString: string, database: string): string | null {\n try {\n const url = new URL(connectionString);\n url.pathname = `/${encodeURIComponent(database)}`;\n return url.toString();\n } catch {\n return null;\n }\n }\n\n private static escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { inspect } from 'node:util';\n\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type { Migration, MigrationInfo, MigrationProvider, MigrationResult, MigrationResultSet } from 'kysely';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n */\nexport class KpgMigrationManager<Database extends object> {\n constructor(private readonly ctx: MigrationManagerContext<Database>) {}\n\n public async migrate(options?: MigrationOptions): Promise<void> {\n const { target, direction = 'latest', steps } = options ?? {};\n\n if (typeof target !== 'undefined') {\n const label = target === NO_MIGRATIONS ? 'NO_MIGRATIONS' : target;\n await this.runMigration((migrator) => migrator.migrateTo(target), `Migrating to ${chalk.yellow(label)}...`);\n return;\n }\n\n switch (direction) {\n case 'latest':\n await this.runMigration((migrator) => migrator.migrateToLatest());\n return;\n case 'up':\n case 'down': {\n const stepCount = steps ?? 1;\n if (!Number.isInteger(stepCount) || stepCount < 0) {\n throw new Error('Migration step count must be a non-negative integer');\n }\n\n if (stepCount === 0) {\n this.logMigrationResults([]);\n return;\n }\n\n const runner =\n direction === 'up'\n ? (migrator: Migrator) => migrator.migrateUp()\n : (migrator: Migrator) => migrator.migrateDown();\n await this.runStepwise(stepCount, direction, runner);\n return;\n }\n default:\n throw new Error(`Unknown migration direction: ${String(direction)}`);\n }\n }\n\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'up' });\n return;\n }\n\n await this.migrate({ direction: 'up', steps: options.steps });\n }\n\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'down' });\n return;\n }\n\n await this.migrate({ direction: 'down', steps: options.steps });\n }\n\n public async listMigrations(): Promise<readonly MigrationInfo[]> {\n const migrator = await this.createMigrator();\n return migrator.getMigrations();\n }\n\n private async runMigration(\n runner: (migrator: Migrator) => Promise<MigrationResultSet>,\n runningMessage = 'Running migrations...'\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n this.ctx.logger.info(chalk.gray(runningMessage));\n const { error, results } = await runner(migrator);\n\n this.logMigrationResults(results ?? []);\n\n if (error) {\n this.handleMigrationError(error);\n }\n }\n\n private async runStepwise(\n steps: number,\n direction: 'up' | 'down',\n runner: (migrator: Migrator) => Promise<MigrationResultSet>\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n const directionLabel = direction === 'up' ? 'Running' : 'Reverting';\n const countLabel = steps === 1 ? 'one migration' : `${chalk.yellow(String(steps))} migrations`;\n this.ctx.logger.info(chalk.gray(`${directionLabel} ${countLabel}...`));\n\n const aggregated: MigrationResult[] = [];\n let encounteredError: unknown;\n\n for (let index = 0; index < steps; index += 1) {\n const { error, results } = await runner(migrator);\n\n if (results?.length) {\n aggregated.push(...results);\n }\n\n if (error) {\n encounteredError = error;\n break;\n }\n\n if (!results?.length) {\n break;\n }\n }\n\n this.logMigrationResults(aggregated);\n\n if (encounteredError) {\n this.handleMigrationError(encounteredError);\n }\n }\n\n private async createMigrator(): Promise<Migrator> {\n const provider = await this.getMigrationProvider();\n const { config } = this.ctx;\n\n return new Migrator({\n db: this.ctx.db,\n provider,\n allowUnorderedMigrations: config.allowUnorderedMigrations ?? false,\n ...keepDefined(config, 'migrationTableName', 'migrationLockTableName', 'migrationTableSchema')\n });\n }\n\n private async getMigrationProvider(): Promise<MigrationProvider> {\n const { path: target } = this.ctx.config;\n const resolvedTarget = Array.isArray(target)\n ? target.map((entry) => this.resolvePath(entry))\n : this.resolvePath(target);\n\n if (Array.isArray(resolvedTarget)) {\n this.logMigrationFiles(resolvedTarget);\n return this.createModuleProvider(resolvedTarget);\n }\n\n let migrationStat: Stats | undefined;\n try {\n migrationStat = await fs.stat(resolvedTarget);\n } catch {\n migrationStat = undefined;\n }\n\n if (migrationStat?.isDirectory()) {\n const directory = this.relativePath(resolvedTarget);\n this.ctx.logger.info(chalk.gray(`Loading migrations directory ${chalk.yellow(directory)}`));\n return new FileMigrationProvider({ fs, path, migrationFolder: resolvedTarget });\n }\n\n if (migrationStat?.isFile() ?? true) {\n this.logMigrationFiles([resolvedTarget]);\n return this.createModuleProvider([resolvedTarget]);\n }\n\n const label = Array.isArray(target) ? target.join(', ') : target;\n throw new Error(`Unable to resolve migrations at path: ${label}`);\n }\n\n private async createModuleProvider(files: string[]): Promise<MigrationProvider> {\n if (files.length === 0) {\n throw new Error('No migration files provided');\n }\n\n const comparator =\n this.ctx.config.nameComparator ?? ((nameA: string, nameB: string) => nameA.localeCompare(nameB));\n\n const entries = await Promise.all(\n files.map(async (filePath) => {\n const moduleUrl = pathToFileURL(filePath).href;\n const mod: unknown = await import(moduleUrl);\n\n if (!this.isMigrationModule(mod)) {\n throw new Error(`Migration file ${filePath} must export async functions up and down`);\n }\n\n const { up, down } = mod;\n\n const name = path.basename(filePath);\n\n const migration: Migration = {\n async up(db) {\n await up(db);\n },\n async down(db) {\n await down(db);\n }\n };\n\n return [name, migration] as const;\n })\n );\n\n const sorted = entries.sort(([a], [b]) => comparator(a, b));\n this.logPreparedMigrations(sorted);\n\n return {\n getMigrations: () => Promise.resolve(Object.fromEntries(sorted))\n } satisfies MigrationProvider;\n }\n\n private logMigrationFiles(files: readonly string[]): void {\n if (!files.length) return;\n\n this.ctx.logger.info('Loading migration file(s):');\n for (const file of files) {\n this.ctx.logger.info(`→ ${chalk.yellow(this.relativePath(file))}`);\n }\n }\n\n private logPreparedMigrations(entries: readonly (readonly [string, Migration])[]): void {\n if (!entries.length) return;\n\n this.ctx.logger.info('Prepared migrations:');\n for (const [name] of entries) {\n this.ctx.logger.info(`→ ${chalk.green(name)}`);\n }\n }\n\n private logMigrationResults(results: readonly MigrationResult[]): void {\n if (!results.length) {\n this.ctx.logger.info(chalk.gray('No migrations executed.'));\n return;\n }\n\n this.ctx.logger.info('Migration results:');\n\n for (const result of results) {\n if (result.status === 'Success') {\n this.ctx.logger.info(` ${chalk.green('✓')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n if (result.status === 'Error') {\n this.ctx.logger.error(` ${chalk.red('✗')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n this.ctx.logger.info(\n ` ${chalk.yellow('•')} ${chalk.bold(result.migrationName)} ${chalk.gray('(skipped)')}`\n );\n }\n }\n\n private relativePath(filePath: string): string {\n const relative = path.relative(this.ctx.baseDir, filePath);\n return relative.startsWith('..') ? filePath : relative;\n }\n\n private resolvePath(target: string): string {\n if (path.isAbsolute(target)) return target;\n return path.resolve(this.ctx.baseDir, target);\n }\n\n private handleMigrationError(error: unknown): never {\n const message = error instanceof Error ? error.message : inspect(error);\n this.ctx.logger.error(`Migration failure: ${message}`);\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new Error(message);\n }\n\n private isMigrationModule(value: unknown): value is MigrationModule {\n if (!value || typeof value !== 'object') return false;\n if (!('up' in value) || !('down' in value)) return false;\n\n const { up, down } = value as { up: unknown; down: unknown };\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import type { KpgServiceRegistrationOptions } from '../types/KpgServiceRegistrationOptions';\nimport type { KpgServices, KpgServiceKeys } from '../types/KpgServices';\nimport type { Constructor } from 'type-fest';\n\nexport const PgServiceMetadataKey = Symbol('db:pgServiceKey');\nexport const PgTableMetadataKey = Symbol('db:pgTable');\n\n/**\n *\n * Registers a Kysely PG service with the specified key and options.\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TKey - The service key type\n * @param key - Service key for registration and type-safe access\n * @param options - Additional registration options\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterKpgService('users', { table: 'app_users' })\n * export class UsersService extends KpgService<{ users: IUser }, 'users'> {\n * // Some code\n * }\n * ```\n *\n * @see {@link KpgService}\n */\nexport function RegisterKpgService<TKey extends KpgServiceKeys>(key: TKey, options?: KpgServiceRegistrationOptions) {\n return <Ctor extends Constructor<KpgServices[TKey]>>(ctor: Ctor): void => {\n Reflect.defineMetadata(PgServiceMetadataKey, key, ctor);\n\n const tableName = options?.table ?? String(key);\n Reflect.defineMetadata(PgTableMetadataKey, tableName, ctor);\n };\n}\n","import { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServices } from './types/KpgServices';\nimport type { Kysely } from 'kysely';\nimport type { Core, TypedConstructor } from 'seedcord';\n\n/**\n * Base class for KyselyPg services.\n *\n * Provides a small, typed shim around the shared Kysely instance and ensures\n * that subclasses have been decorated with `@RegisterKpgService`.\n *\n * @typeParam Database - The database shape used by Kysely (tables as keys).\n * @typeParam TTable - The specific table key from `Database` this service works with.\n *\n * @example\n * ```typescript\n * \\@RegisterKpgService('users')\n * export class UsersService extends KpgService<ImportedDatabaseInterface, 'users'> {\n * public async findById(id: string) {\n * return this.entity\n * .selectFrom(this.table)\n * .selectAll().where('id', '=', id)\n * .executeTakeFirst();\n * }\n * }\n *\n * // Usage inside handlers:\n * const user = await this.core.db.services.users.findById('abc');\n * ```\n */\nexport abstract class KpgService<Database extends object, TTable extends keyof Database & string> {\n public readonly table: TTable;\n\n public constructor(\n protected readonly kysely: KyselyPg<Database>,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n if (!key) throw new Error(`Missing @RegisterKpgService on ${ctor.name}`);\n\n const table = Reflect.getMetadata(PgTableMetadataKey, ctor) as TTable | undefined;\n\n // This check should always pass since TTable is derived from the key if a table is not provided explicitly.\n if (!table) {\n throw new Error(`Missing table metadata for ${ctor.name}. Provide a table via @RegisterKpgService().`);\n }\n\n this.table = table;\n this.kysely._register(key as keyof KpgServices, this as unknown as AnyKpgService);\n }\n\n /**\n * Shared Kysely instance used to interact with the Postgres database.\n */\n public get db(): Kysely<Database> {\n return this.kysely.connection;\n }\n}\n\n/** Constructor type for {@link KpgService} classes */\nexport type KyselyServiceConstructor<Database extends object = object> = TypedConstructor<\n typeof KpgService<Database, keyof Database & string>\n>;\n","import chalk from 'chalk';\nimport { traverseDirectory } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { Core, Logger } from 'seedcord';\n\n/**\n * Discovers and registers Postgres services for the plugin.\n */\nexport class KpgServiceRegistry<Database extends object> {\n private readonly services: Record<string, AnyKpgService> = Object.create(null) as Record<string, AnyKpgService>;\n\n constructor(\n private readonly plugin: KyselyPg<Database>,\n private readonly core: Core,\n private readonly logger: Logger\n ) {}\n\n public get map(): KpgServices {\n return this.services as unknown as KpgServices;\n }\n\n public register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.services[key] = instance;\n }\n\n public async loadFromDirectory(dir: string): Promise<void> {\n this.logger.info(chalk.bold(dir));\n\n await traverseDirectory(\n dir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this.plugin, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is KyselyServiceConstructor<Database> {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof KpgService &&\n Reflect.hasMetadata(PgServiceMetadataKey, obj)\n );\n }\n}\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig } from 'pg';\nimport { keepDefined, Logger, Plugin, ShutdownPhase } from 'seedcord';\n\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { MigrationInfo } from 'kysely';\nimport type { Core } from 'seedcord';\n\n/**\n * Postgres plugin using Kysely.\n *\n * Handles setting up the connection pool, applying migrations, and\n * registering decorated services so they can be resolved from the core.\n */\nexport class KyselyPg<Database extends object> extends Plugin {\n public readonly logger = new Logger('KyselyPg');\n private isInitialised = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private migrationManager: KpgMigrationManager<Database> | null = null;\n private readonly serviceRegistry: KpgServiceRegistry<Database>;\n private readonly databaseBootstrapper: KpgDatabaseBootstrapper;\n private databaseName: string | null = null;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n return this.serviceRegistry.map;\n }\n\n constructor(\n public readonly core: Core,\n private readonly options: KpgOptions\n ) {\n super(core);\n this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);\n this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);\n this.core.shutdown.addTask(ShutdownPhase.ExternalResources, 'stop-kyselypg', async () => await this.stop());\n }\n\n /**\n * Connects to Postgres, runs any startup migrations, and loads decorated services.\n *\n * Safe to call multiple times; subsequent calls exit early.\n */\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n\n const startupConfig = this.options.migrations.onStartup;\n if (startupConfig !== false) {\n if (startupConfig && typeof startupConfig !== 'boolean') {\n await this.migrate(startupConfig);\n } else {\n await this.migrate();\n }\n }\n await this.serviceRegistry.loadFromDirectory(this.options.dir);\n }\n\n /**\n * Tears down the connection pool and clears the migration manager reference.\n */\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n const pool = await this.resolvePool();\n this.pool = pool;\n\n this.registerOnConnectStatements(pool, this.options.onConnectSQL);\n\n try {\n await this.testPoolConnection(pool);\n\n this.connection = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n ...keepDefined(this.options.kysely ?? {})\n });\n\n this.migrationManager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n const dbLabel = this.databaseName ?? 'unknown';\n this.logger.info(`Connected to Postgres database ${chalk.bold.magenta(dbLabel)}`);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.logger.error(`Could not connect to Postgres: ${error.message}`);\n throw error;\n }\n }\n\n private async disconnect(): Promise<void> {\n const pool = this.pool;\n if (!pool) return;\n\n this.pool = null;\n this.migrationManager = null;\n\n this.logger.info(chalk.gray('Closing Postgres pool.'));\n await pool.end().catch((err) => {\n this.logger.error(`Could not close pg pool: ${(err as Error).message}`);\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options or defaults to `latest`.\n *\n * @param options - Target migration or direction overrides\n */\n public async migrate(options?: MigrationOptions): Promise<void> {\n await this.getMigrationManager().migrate(options);\n }\n\n /**\n * Runs a single upwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateUp(options);\n }\n\n /**\n * Runs a single downwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateDown(options);\n }\n\n /**\n * Lists every migration the manager knows about along with its execution state.\n */\n public listMigrations(): Promise<readonly MigrationInfo[]> {\n return this.getMigrationManager().listMigrations();\n }\n\n /**\n * Lists unapplied migrations.\n */\n public async listPendingMigrations(): Promise<MigrationInfo[]> {\n const all = await this.listMigrations();\n return all.filter((m) => !m.executedAt);\n }\n\n private getMigrationManager(): KpgMigrationManager<Database> {\n if (this.migrationManager) return this.migrationManager;\n\n const manager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n this.migrationManager = manager;\n return manager;\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.serviceRegistry.register(key, instance);\n }\n\n private async resolvePool(): Promise<Pool> {\n const { pool: providedPool, connectionString } = this.options;\n\n if (providedPool instanceof Pool) {\n this.logger.info(chalk.gray('Reusing provided Postgres pool instance.'));\n this.databaseName = this.databaseBootstrapper.resolveDatabaseFromPool(providedPool);\n return providedPool;\n }\n\n const baseConfig = this.createPoolConfig(providedPool, connectionString);\n await this.databaseBootstrapper.ensure(baseConfig);\n this.databaseName = this.databaseBootstrapper.resolveDatabaseName(baseConfig);\n\n this.logger.info(chalk.gray('Creating new Postgres pool.'));\n return new Pool(baseConfig);\n }\n\n private createPoolConfig(poolConfig?: PoolConfig, connectionString?: string): PoolConfig {\n const config: PoolConfig = poolConfig ? { ...poolConfig } : {};\n\n if (connectionString) {\n config.connectionString = connectionString;\n }\n\n if (this.options.forceInsecureSSL) {\n config.ssl = { rejectUnauthorized: false };\n }\n\n return config;\n }\n\n private registerOnConnectStatements(pool: Pool, statements?: string[]): void {\n if (!statements?.length) return;\n\n const queuedStatements = [...statements];\n pool.on('connect', (client) => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })();\n });\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","import { CustomError, throwCustomError, DatabaseError } from 'seedcord';\n\n/**\n * Catches and wraps database operation errors.\n *\n * Wraps non-CustomError exceptions in DatabaseError instances\n * with UUID tracking. Should be applied to database service methods.\n *\n * @typeParam TypeReturn - The return type of the decorated method\n * @param errorMessage - Message to include when wrapping errors\n * @decorator\n * @example\n * ```typescript\n * class UserService extends MongoService<IUser> {\n * \\@WrapDatabaseError('Failed to find user')\n * async findById(id: string) {\n * return this.model.findById(id);\n * }\n * }\n * ```\n *\n * @see {@link DatabaseError}\n * @see {@link CustomError}\n * @see {@link MongoService}\n */\nexport function WrapDatabaseError<TypeReturn>(errorMessage: string) {\n return function (\n _target: unknown,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>\n ): void {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]): Promise<TypeReturn> {\n if (!originalMethod) {\n throw new Error('Method not found');\n }\n\n try {\n return await originalMethod.apply(this, args);\n } catch (error) {\n if (!(error instanceof CustomError)) {\n throwCustomError(error, errorMessage, DatabaseError);\n } else {\n throw error;\n }\n }\n };\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/shared/WrapDatabaseError.ts"],"names":["ServiceMetadataKey","Symbol","RegisterMongoService","key","ctor","Reflect","defineMetadata","ModelMetadataKey","RegisterMongoModel","collection","target","propertyKey","schema","name","String","model","mongoose","MongoService","db","core","getMetadata","SeedcordError","SeedcordErrorCode","PluginMongoServiceDecoratorMissing","PluginMongoModelDecoratorMissing","_register","Mongo","Plugin","logger","Logger","isInitialised","uri","services","options","shutdown","addTask","ShutdownPhase","ExternalResources","stop","timeout","init","connect","loadServices","disconnect","connection","dbName","Envapter","isProduction","tls","ssl","keepDefined","connectionOptions","then","conn","info","chalk","green","bold","magenta","catch","err","PluginMongoConnectionFailed","cause","red","error","message","servicesDir","dir","traverseDirectory","_full","rel","mod","Service","Object","values","isServiceClass","instance","italic","yellow","gray","keys","length","obj","prototype","hasMetadata","KpgDatabaseBootstrapper","ADMIN_DB","DATABASE_EXISTS_SQL","resolveDatabaseName","config","parseDatabaseName","resolveDatabaseFromPool","pool","database","connectionString","ensure","baseConfig","targetDb","adminConfig","buildAdminConfig","warn","adminPool","Pool","exists","databaseExists","createDatabase","Error","end","applyDatabaseToConnectionString","client","rows","query","Boolean","release","createSql","escapeIdentifier","trim","url","URL","pathname","replace","candidate","split","decodeURIComponent","encodeURIComponent","toString","identifier","KpgMigrationManager","ctx","migrate","direction","steps","label","NO_MIGRATIONS","runMigration","migrator","migrateTo","migrateToLatest","stepCount","Number","isInteger","SeedcordRangeError","PluginKpgInvalidStepCount","logMigrationResults","runner","migrateUp","migrateDown","runStepwise","PluginKpgUnknownDirection","listMigrations","createMigrator","getMigrations","runningMessage","results","handleMigrationError","directionLabel","countLabel","aggregated","encounteredError","index","push","provider","getMigrationProvider","Migrator","allowUnorderedMigrations","path","resolvedTarget","Array","isArray","map","entry","resolvePath","logMigrationFiles","createModuleProvider","migrationStat","fs","stat","undefined","isDirectory","directory","relativePath","FileMigrationProvider","migrationFolder","isFile","join","PluginKpgUnresolvedMigrationsPath","files","PluginKpgNoMigrationFiles","comparator","nameComparator","nameA","nameB","localeCompare","entries","Promise","all","filePath","moduleUrl","pathToFileURL","href","isMigrationModule","PluginKpgInvalidMigrationModule","up","down","basename","migration","sorted","sort","a","b","logPreparedMigrations","resolve","fromEntries","file","result","status","migrationName","relative","baseDir","startsWith","isAbsolute","inspect","PluginKpgNonErrorFailure","value","PgServiceMetadataKey","PgTableMetadataKey","RegisterKpgService","tableName","table","KpgService","kysely","PluginKpgServiceDecoratorMissing","PluginKpgServiceTableMissing","KpgServiceRegistry","create","plugin","register","loadFromDirectory","KyselyPg","migrationManager","serviceRegistry","databaseBootstrapper","databaseName","startupConfig","migrations","onStartup","resolvePool","registerOnConnectStatements","onConnectSQL","testPoolConnection","Kysely","dialect","PostgresDialect","process","cwd","dbLabel","getMigrationManager","listPendingMigrations","filter","m","executedAt","manager","providedPool","createPoolConfig","poolConfig","forceInsecureSSL","rejectUnauthorized","statements","queuedStatements","on","sql","WrapDatabaseError","errorMessage","_target","_propertyKey","descriptor","originalMethod","args","DecoratorMethodNotFound","apply","CustomError","throwCustomError","DatabaseError"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { MongoService } from '../MongoService';\nimport type { MongoServiceKeys } from '../types/MongoServices';\nimport type { Constructor } from 'type-fest';\n\nexport const ServiceMetadataKey = Symbol('db:serviceKey');\n\n/**\n * Registers a database service with a typed key\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TService - The service key type\n * @param key - Service key for registration and type-safe access\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users<Doc extends IUser = IUser> extends MongoService<Doc> {\n * // Some code\n * }\n * ```\n */\nexport function RegisterMongoService<TService extends MongoServiceKeys>(key: TService) {\n return <DatabaseCtor extends Constructor<unknown> & { prototype: MongoService }>(ctor: DatabaseCtor): void => {\n Reflect.defineMetadata(ServiceMetadataKey, key, ctor);\n };\n}\n","import mongoose from 'mongoose';\n\nimport type { MongoServiceKeys } from '../types/MongoServices';\n\nexport const ModelMetadataKey = Symbol('db:model');\n\n/**\n * Associates a Mongoose model with a database service\n *\n * Creates a Mongoose model from the decorated static schema property and stores it\n * for service registration. The model becomes available as `this.model` in the service.\n * Must be applied to a `public static schema` property in the service class.\n *\n * @typeParam TService - The service key type\n * @param collection - Collection name for the Mongoose model\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n * }\n * ```\n */\nexport function RegisterMongoModel<TService extends MongoServiceKeys>(collection: TService) {\n return <\n SchemaObj extends Record<KeyOfSchema, mongoose.Schema>,\n KeyOfSchema extends keyof SchemaObj & (string | symbol)\n >(\n target: SchemaObj,\n propertyKey: KeyOfSchema\n ): void => {\n const schema = target[propertyKey];\n const name = String(collection);\n const model = mongoose.model(name, schema);\n Reflect.defineMetadata(ModelMetadataKey, model, target);\n };\n}\n","import { SeedcordError, SeedcordErrorCode } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\n\nimport type { Mongo } from './Mongo';\nimport type { MongoDocument } from './types/MongoDocument';\nimport type { MongoServices } from './types/MongoServices';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type mongoose from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * Base class for MongoDB service layers\n *\n * Provides typed access to MongoDB collections through Mongoose models.\n * Services are automatically registered with the Mongo plugin when instantiated.\n *\n * @typeParam Doc - The document type this service manages\n * @example\n * ```typescript\n * \\@RegisterMongoService('users')\n * export class Users extends MongoService<IUser> {\n * \\@RegisterMongoModel('users')\n * public static schema = new mongoose.Schema<IUser>({\n * username: { type: String, required: true, unique: true }\n * });\n *\n * // Custom methods here\n * public async findByUsername(username: string) {\n * return this.model.findOne({ username });\n * }\n * }\n * ```\n */\nexport abstract class MongoService<Doc extends MongoDocument = MongoDocument> {\n public readonly model: mongoose.Model<Doc>;\n\n public constructor(\n protected readonly db: Mongo,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n if (!key) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServiceDecoratorMissing, [ctor.name]);\n }\n\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<Doc> | undefined;\n if (!model) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoModelDecoratorMissing, [ctor.name]);\n }\n\n this.model = model;\n\n db._register(key as keyof MongoServices, this as unknown as MongoServices[keyof MongoServices]);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport {\n keepDefined,\n Logger,\n Plugin,\n SeedcordError,\n SeedcordErrorCode,\n ShutdownPhase,\n traverseDirectory\n} from 'seedcord';\n\nimport { ServiceMetadataKey } from './decorators/RegisterMongoService';\nimport { MongoService } from './MongoService';\n\nimport type { MongoServiceConstructor } from './MongoService';\nimport type { MongoOptions } from './types/MongoOptions';\nimport type { MongoServices } from './types/MongoServices';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\n/**\n * MongoDB integration plugin for Seedcord.\n *\n * Manages MongoDB connections, service loading, and provides type-safe\n * access to database services through service registration decorators.\n */\nexport class Mongo extends Plugin {\n public readonly logger = new Logger('Mongo');\n private isInitialised = false;\n private readonly uri: string;\n\n /**\n * Map of all loaded services.\n * Keys come from `@RegisterMongoService('key')`\n */\n public readonly services: MongoServices = {} as MongoServices;\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n\n constructor(\n public readonly core: Core,\n private readonly options: MongoOptions\n ) {\n super(core);\n this.uri = options.uri;\n\n this.core.shutdown.addTask(\n ShutdownPhase.ExternalResources,\n 'stop-database',\n async () => await this.stop(),\n this.options.timeout\n );\n }\n\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n await this.loadServices();\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.connection = await mongoose\n .connect(this.uri, {\n dbName: this.options.name,\n ...(Envapter.isProduction && { tls: true, ssl: true }),\n ...keepDefined(this.options.connectionOptions ?? {})\n })\n .then((conn) => {\n this.logger.info(chalk.green.bold(`Connected to MongoDB: ${chalk.magenta.bold(conn.connection.name)}`));\n return conn;\n })\n .catch((err) => {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoConnectionFailed, [this.options.name], {\n cause: err\n });\n });\n }\n\n private async disconnect(): Promise<void> {\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`));\n }\n\n private async loadServices(): Promise<void> {\n const servicesDir = this.options.dir;\n this.logger.info(chalk.bold(servicesDir));\n\n await traverseDirectory(\n servicesDir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is MongoServiceConstructor {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof MongoService &&\n Reflect.hasMetadata(ServiceMetadataKey, obj)\n );\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register<SKey extends keyof MongoServices>(key: SKey, instance: MongoServices[SKey]): void {\n this.services[key] = instance;\n }\n}\n","import chalk from 'chalk';\nimport { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from 'seedcord';\n\n/**\n * Handles ensuring the target Postgres database exists, creating it if necessary.\n */\nexport class KpgDatabaseBootstrapper {\n private static readonly ADMIN_DB = 'postgres';\n private static readonly DATABASE_EXISTS_SQL =\n 'SELECT EXISTS (SELECT 1 FROM pg_database WHERE datname = $1) AS \"exists\"';\n\n constructor(private readonly logger: Logger) {}\n\n public resolveDatabaseName(config: PoolConfig): string | null {\n return KpgDatabaseBootstrapper.parseDatabaseName(config);\n }\n\n public resolveDatabaseFromPool(pool: Pool): string | null {\n const config: PoolConfig = {};\n\n const { options } = pool;\n\n if (typeof options.database === 'string') {\n config.database = options.database;\n }\n\n if (typeof options.connectionString === 'string') {\n config.connectionString = options.connectionString;\n }\n\n return this.resolveDatabaseName(config);\n }\n\n public async ensure(baseConfig: PoolConfig): Promise<void> {\n const targetDb = this.resolveDatabaseName(baseConfig);\n if (!targetDb) {\n this.logger.info(chalk.gray('Skipping database existence check (no database specified).'));\n return;\n }\n\n if (targetDb === KpgDatabaseBootstrapper.ADMIN_DB) {\n this.logger.info(chalk.gray('Target database is postgres; skipping creation.'));\n return;\n }\n\n const adminConfig = this.buildAdminConfig(baseConfig);\n if (!adminConfig) {\n this.logger.warn(`Unable to derive admin connection when ensuring database ${targetDb}`);\n return;\n }\n\n this.logger.info(chalk.gray(`Ensuring database ${chalk.yellow(targetDb)} exists...`));\n\n const adminPool = new Pool(adminConfig);\n\n try {\n const exists = await this.databaseExists(adminPool, targetDb);\n if (exists) {\n this.logger.info(chalk.gray(`Database ${chalk.yellow(targetDb)} already exists.`));\n return;\n }\n\n await this.createDatabase(adminPool, targetDb);\n this.logger.info(chalk.green(`Created database ${chalk.bold(targetDb)}.`));\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n this.logger.error(`Failed to ensure database ${targetDb}: ${err.message}`);\n throw err;\n } finally {\n await adminPool.end();\n }\n }\n\n private buildAdminConfig(baseConfig: PoolConfig): PoolConfig | null {\n const adminConfig: PoolConfig = { ...baseConfig };\n\n const { connectionString } = adminConfig;\n if (connectionString) {\n const connection = KpgDatabaseBootstrapper.applyDatabaseToConnectionString(\n connectionString,\n KpgDatabaseBootstrapper.ADMIN_DB\n );\n if (!connection) return null;\n adminConfig.connectionString = connection;\n }\n\n adminConfig.database = KpgDatabaseBootstrapper.ADMIN_DB;\n return adminConfig;\n }\n\n private async databaseExists(pool: Pool, database: string): Promise<boolean> {\n const client = await pool.connect();\n try {\n const { rows } = await client.query<{ exists: boolean }>(KpgDatabaseBootstrapper.DATABASE_EXISTS_SQL, [\n database\n ]);\n return Boolean(rows[0]?.exists);\n } finally {\n client.release();\n }\n }\n\n private async createDatabase(pool: Pool, database: string): Promise<void> {\n const client = await pool.connect();\n try {\n const createSql = `CREATE DATABASE ${KpgDatabaseBootstrapper.escapeIdentifier(database)}`;\n await client.query(createSql);\n } finally {\n client.release();\n }\n }\n\n private static parseDatabaseName(config: PoolConfig): string | null {\n if (typeof config.database === 'string' && config.database.trim().length > 0) {\n return config.database.trim();\n }\n\n const connectionString = config.connectionString;\n if (!connectionString) return null;\n\n try {\n const url = new URL(connectionString);\n const pathname = url.pathname.replace(/^\\//, '');\n if (!pathname) return null;\n const [candidate] = pathname.split('/');\n return candidate ? decodeURIComponent(candidate) : null;\n } catch {\n return null;\n }\n }\n\n private static applyDatabaseToConnectionString(connectionString: string, database: string): string | null {\n try {\n const url = new URL(connectionString);\n url.pathname = `/${encodeURIComponent(database)}`;\n return url.toString();\n } catch {\n return null;\n }\n }\n\n private static escapeIdentifier(identifier: string): string {\n return `\"${identifier.replace(/\"/g, '\"\"')}\"`;\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { inspect } from 'node:util';\n\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely';\nimport { SeedcordError, SeedcordErrorCode, SeedcordRangeError } from 'seedcord';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type { Migration, MigrationInfo, MigrationProvider, MigrationResult, MigrationResultSet } from 'kysely';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n */\nexport class KpgMigrationManager<Database extends object> {\n constructor(private readonly ctx: MigrationManagerContext<Database>) {}\n\n public async migrate(options?: MigrationOptions): Promise<void> {\n const { target, direction = 'latest', steps } = options ?? {};\n\n if (typeof target !== 'undefined') {\n const label = target === NO_MIGRATIONS ? 'NO_MIGRATIONS' : target;\n await this.runMigration((migrator) => migrator.migrateTo(target), `Migrating to ${chalk.yellow(label)}...`);\n return;\n }\n\n switch (direction) {\n case 'latest':\n await this.runMigration((migrator) => migrator.migrateToLatest());\n return;\n case 'up':\n case 'down': {\n const stepCount = steps ?? 1;\n if (!Number.isInteger(stepCount) || stepCount < 0) {\n throw new SeedcordRangeError(SeedcordErrorCode.PluginKpgInvalidStepCount);\n }\n\n if (stepCount === 0) {\n this.logMigrationResults([]);\n return;\n }\n\n const runner =\n direction === 'up'\n ? (migrator: Migrator) => migrator.migrateUp()\n : (migrator: Migrator) => migrator.migrateDown();\n await this.runStepwise(stepCount, direction, runner);\n return;\n }\n default:\n throw new SeedcordError(SeedcordErrorCode.PluginKpgUnknownDirection, [direction]);\n }\n }\n\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'up' });\n return;\n }\n\n await this.migrate({ direction: 'up', steps: options.steps });\n }\n\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n if (typeof options?.steps === 'undefined') {\n await this.migrate({ direction: 'down' });\n return;\n }\n\n await this.migrate({ direction: 'down', steps: options.steps });\n }\n\n public async listMigrations(): Promise<readonly MigrationInfo[]> {\n const migrator = await this.createMigrator();\n return migrator.getMigrations();\n }\n\n private async runMigration(\n runner: (migrator: Migrator) => Promise<MigrationResultSet>,\n runningMessage = 'Running migrations...'\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n this.ctx.logger.info(chalk.gray(runningMessage));\n const { error, results } = await runner(migrator);\n\n this.logMigrationResults(results ?? []);\n\n if (error) {\n this.handleMigrationError(error);\n }\n }\n\n private async runStepwise(\n steps: number,\n direction: 'up' | 'down',\n runner: (migrator: Migrator) => Promise<MigrationResultSet>\n ): Promise<void> {\n this.ctx.logger.info(chalk.gray('Preparing migrations...'));\n const migrator = await this.createMigrator();\n\n const directionLabel = direction === 'up' ? 'Running' : 'Reverting';\n const countLabel = steps === 1 ? 'one migration' : `${chalk.yellow(String(steps))} migrations`;\n this.ctx.logger.info(chalk.gray(`${directionLabel} ${countLabel}...`));\n\n const aggregated: MigrationResult[] = [];\n let encounteredError: unknown;\n\n for (let index = 0; index < steps; index += 1) {\n const { error, results } = await runner(migrator);\n\n if (results?.length) {\n aggregated.push(...results);\n }\n\n if (error) {\n encounteredError = error;\n break;\n }\n\n if (!results?.length) {\n break;\n }\n }\n\n this.logMigrationResults(aggregated);\n\n if (encounteredError) {\n this.handleMigrationError(encounteredError);\n }\n }\n\n private async createMigrator(): Promise<Migrator> {\n const provider = await this.getMigrationProvider();\n const { config } = this.ctx;\n\n return new Migrator({\n db: this.ctx.db,\n provider,\n allowUnorderedMigrations: config.allowUnorderedMigrations ?? false,\n ...keepDefined(config, 'migrationTableName', 'migrationLockTableName', 'migrationTableSchema')\n });\n }\n\n private async getMigrationProvider(): Promise<MigrationProvider> {\n const { path: target } = this.ctx.config;\n const resolvedTarget = Array.isArray(target)\n ? target.map((entry) => this.resolvePath(entry))\n : this.resolvePath(target);\n\n if (Array.isArray(resolvedTarget)) {\n this.logMigrationFiles(resolvedTarget);\n return this.createModuleProvider(resolvedTarget);\n }\n\n let migrationStat: Stats | undefined;\n try {\n migrationStat = await fs.stat(resolvedTarget);\n } catch {\n migrationStat = undefined;\n }\n\n if (migrationStat?.isDirectory()) {\n const directory = this.relativePath(resolvedTarget);\n this.ctx.logger.info(chalk.gray(`Loading migrations directory ${chalk.yellow(directory)}`));\n return new FileMigrationProvider({ fs, path, migrationFolder: resolvedTarget });\n }\n\n if (migrationStat?.isFile() ?? true) {\n this.logMigrationFiles([resolvedTarget]);\n return this.createModuleProvider([resolvedTarget]);\n }\n\n const label = Array.isArray(target) ? target.join(', ') : target;\n throw new SeedcordError(SeedcordErrorCode.PluginKpgUnresolvedMigrationsPath, [label]);\n }\n\n private async createModuleProvider(files: string[]): Promise<MigrationProvider> {\n if (files.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgNoMigrationFiles);\n }\n\n const comparator =\n this.ctx.config.nameComparator ?? ((nameA: string, nameB: string) => nameA.localeCompare(nameB));\n\n const entries = await Promise.all(\n files.map(async (filePath) => {\n const moduleUrl = pathToFileURL(filePath).href;\n const mod: unknown = await import(moduleUrl);\n\n if (!this.isMigrationModule(mod)) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgInvalidMigrationModule, [filePath]);\n }\n\n const { up, down } = mod;\n\n const name = path.basename(filePath);\n\n const migration: Migration = {\n async up(db) {\n await up(db);\n },\n async down(db) {\n await down(db);\n }\n };\n\n return [name, migration] as const;\n })\n );\n\n const sorted = entries.sort(([a], [b]) => comparator(a, b));\n this.logPreparedMigrations(sorted);\n\n return {\n getMigrations: () => Promise.resolve(Object.fromEntries(sorted))\n } satisfies MigrationProvider;\n }\n\n private logMigrationFiles(files: readonly string[]): void {\n if (!files.length) return;\n\n this.ctx.logger.info('Loading migration file(s):');\n for (const file of files) {\n this.ctx.logger.info(`→ ${chalk.yellow(this.relativePath(file))}`);\n }\n }\n\n private logPreparedMigrations(entries: readonly (readonly [string, Migration])[]): void {\n if (!entries.length) return;\n\n this.ctx.logger.info('Prepared migrations:');\n for (const [name] of entries) {\n this.ctx.logger.info(`→ ${chalk.green(name)}`);\n }\n }\n\n private logMigrationResults(results: readonly MigrationResult[]): void {\n if (!results.length) {\n this.ctx.logger.info(chalk.gray('No migrations executed.'));\n return;\n }\n\n this.ctx.logger.info('Migration results:');\n\n for (const result of results) {\n if (result.status === 'Success') {\n this.ctx.logger.info(`${chalk.green('✓')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n if (result.status === 'Error') {\n this.ctx.logger.error(`${chalk.red('✗')} ${chalk.bold(result.migrationName)}`);\n continue;\n }\n\n this.ctx.logger.info(`${chalk.yellow('•')} ${chalk.bold(result.migrationName)} ${chalk.gray('(skipped)')}`);\n }\n }\n\n private relativePath(filePath: string): string {\n const relative = path.relative(this.ctx.baseDir, filePath);\n return relative.startsWith('..') ? filePath : relative;\n }\n\n private resolvePath(target: string): string {\n if (path.isAbsolute(target)) return target;\n return path.resolve(this.ctx.baseDir, target);\n }\n\n private handleMigrationError(error: unknown): never {\n const message = error instanceof Error ? error.message : inspect(error);\n this.ctx.logger.error(`Migration failure: ${message}`);\n\n if (error instanceof Error) {\n throw error;\n }\n\n throw new SeedcordError(SeedcordErrorCode.PluginKpgNonErrorFailure, [message]);\n }\n\n private isMigrationModule(value: unknown): value is MigrationModule {\n if (!value || typeof value !== 'object') return false;\n if (!('up' in value) || !('down' in value)) return false;\n\n const { up, down } = value as { up: unknown; down: unknown };\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import type { KpgServiceRegistrationOptions } from '../types/KpgServiceRegistrationOptions';\nimport type { KpgServices, KpgServiceKeys } from '../types/KpgServices';\nimport type { Constructor } from 'type-fest';\n\nexport const PgServiceMetadataKey = Symbol('db:pgServiceKey');\nexport const PgTableMetadataKey = Symbol('db:pgTable');\n\n/**\n *\n * Registers a Kysely PG service with the specified key and options.\n *\n * Associates a service class with a key for dependency injection.\n * The service becomes available via `core.db.services[key]`.\n *\n * @typeParam TKey - The service key type\n * @param key - Service key for registration and type-safe access\n * @param options - Additional registration options\n * @decorator\n * @example\n * ```typescript\n * \\@RegisterKpgService('users', { table: 'app_users' })\n * export class UsersService extends KpgService<{ users: IUser }, 'users'> {\n * // Some code\n * }\n * ```\n *\n * @see {@link KpgService}\n */\nexport function RegisterKpgService<TKey extends KpgServiceKeys>(key: TKey, options?: KpgServiceRegistrationOptions) {\n return <Ctor extends Constructor<KpgServices[TKey]>>(ctor: Ctor): void => {\n Reflect.defineMetadata(PgServiceMetadataKey, key, ctor);\n\n const tableName = options?.table ?? String(key);\n Reflect.defineMetadata(PgTableMetadataKey, tableName, ctor);\n };\n}\n","import { SeedcordError, SeedcordErrorCode } from 'seedcord';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServices } from './types/KpgServices';\nimport type { Kysely } from 'kysely';\nimport type { Core, TypedConstructor } from 'seedcord';\n\n/**\n * Base class for KyselyPg services.\n *\n * Provides a small, typed shim around the shared Kysely instance and ensures\n * that subclasses have been decorated with `@RegisterKpgService`.\n *\n * @typeParam Database - The database shape used by Kysely (tables as keys).\n * @typeParam TTable - The specific table key from `Database` this service works with.\n *\n * @example\n * ```typescript\n * \\@RegisterKpgService('users')\n * export class UsersService extends KpgService<ImportedDatabaseInterface, 'users'> {\n * public async findById(id: string) {\n * return this.entity\n * .selectFrom(this.table)\n * .selectAll().where('id', '=', id)\n * .executeTakeFirst();\n * }\n * }\n *\n * // Usage inside handlers:\n * const user = await this.core.db.services.users.findById('abc');\n * ```\n */\nexport abstract class KpgService<Database extends object, TTable extends keyof Database & string> {\n public readonly table: TTable;\n\n public constructor(\n protected readonly kysely: KyselyPg<Database>,\n protected readonly core: Core\n ) {\n const ctor = this.constructor;\n\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n if (!key) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceDecoratorMissing, [ctor.name]);\n }\n\n const table = Reflect.getMetadata(PgTableMetadataKey, ctor) as TTable | undefined;\n\n // This check should always pass since TTable is derived from the key if a table is not provided explicitly.\n if (!table) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServiceTableMissing, [ctor.name]);\n }\n\n this.table = table;\n this.kysely._register(key as keyof KpgServices, this as unknown as AnyKpgService);\n }\n\n /**\n * Shared Kysely instance used to interact with the Postgres database.\n */\n public get db(): Kysely<Database> {\n return this.kysely.connection;\n }\n}\n\n/** Constructor type for {@link KpgService} classes */\nexport type KyselyServiceConstructor<Database extends object = object> = TypedConstructor<\n typeof KpgService<Database, keyof Database & string>\n>;\n","import chalk from 'chalk';\nimport { traverseDirectory } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyPg } from './KyselyPg';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { Core, Logger } from 'seedcord';\n\n/**\n * Discovers and registers Postgres services for the plugin.\n */\nexport class KpgServiceRegistry<Database extends object> {\n private readonly services: Record<string, AnyKpgService> = Object.create(null) as Record<string, AnyKpgService>;\n\n constructor(\n private readonly plugin: KyselyPg<Database>,\n private readonly core: Core,\n private readonly logger: Logger\n ) {}\n\n public get map(): KpgServices {\n return this.services as unknown as KpgServices;\n }\n\n public register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.services[key] = instance;\n }\n\n public async loadFromDirectory(dir: string): Promise<void> {\n this.logger.info(chalk.bold(dir));\n\n await traverseDirectory(\n dir,\n (_full, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n const instance = new Service(this.plugin, this.core);\n this.logger.info(\n `${chalk.italic('Registered')} ${chalk.bold.yellow(instance.constructor.name)} from ${chalk.gray(rel)}`\n );\n }\n }\n },\n this.logger\n );\n\n this.logger.info(`${chalk.bold.green('Loaded')}: ${chalk.magenta(Object.keys(this.services).length)} services`);\n }\n\n private isServiceClass(obj: unknown): obj is KyselyServiceConstructor<Database> {\n return (\n typeof obj === 'function' &&\n obj.prototype instanceof KpgService &&\n Reflect.hasMetadata(PgServiceMetadataKey, obj)\n );\n }\n}\n","import 'reflect-metadata';\n\nimport chalk from 'chalk';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig } from 'pg';\nimport { keepDefined, Logger, Plugin, ShutdownPhase } from 'seedcord';\n\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { AnyKpgService, KpgServiceKeys, KpgServices } from './types/KpgServices';\nimport type { MigrationInfo } from 'kysely';\nimport type { Core } from 'seedcord';\n\n/**\n * Postgres plugin using Kysely.\n *\n * Handles setting up the connection pool, applying migrations, and\n * registering decorated services so they can be resolved from the core.\n */\nexport class KyselyPg<Database extends object> extends Plugin {\n public readonly logger = new Logger('KyselyPg');\n private isInitialised = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private migrationManager: KpgMigrationManager<Database> | null = null;\n private readonly serviceRegistry: KpgServiceRegistry<Database>;\n private readonly databaseBootstrapper: KpgDatabaseBootstrapper;\n private databaseName: string | null = null;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n return this.serviceRegistry.map;\n }\n\n constructor(\n public readonly core: Core,\n private readonly options: KpgOptions\n ) {\n super(core);\n this.serviceRegistry = new KpgServiceRegistry(this, core, this.logger);\n this.databaseBootstrapper = new KpgDatabaseBootstrapper(this.logger);\n this.core.shutdown.addTask(\n ShutdownPhase.ExternalResources,\n 'stop-kyselypg',\n async () => await this.stop(),\n this.options.timeout\n );\n }\n\n /**\n * Connects to Postgres, runs any startup migrations, and loads decorated services.\n *\n * Safe to call multiple times; subsequent calls exit early.\n */\n public async init(): Promise<void> {\n if (this.isInitialised) return;\n this.isInitialised = true;\n\n await this.connect();\n\n const startupConfig = this.options.migrations.onStartup;\n if (startupConfig !== false) {\n if (startupConfig && typeof startupConfig !== 'boolean') {\n await this.migrate(startupConfig);\n } else {\n await this.migrate();\n }\n }\n await this.serviceRegistry.loadFromDirectory(this.options.dir);\n }\n\n /**\n * Tears down the connection pool and clears the migration manager reference.\n */\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n const pool = await this.resolvePool();\n this.pool = pool;\n\n this.registerOnConnectStatements(pool, this.options.onConnectSQL);\n\n try {\n await this.testPoolConnection(pool);\n\n this.connection = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n ...keepDefined(this.options.kysely ?? {})\n });\n\n this.migrationManager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n const dbLabel = this.databaseName ?? 'unknown';\n this.logger.info(`Connected to Postgres database ${chalk.bold.magenta(dbLabel)}`);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n this.logger.error(`Could not connect to Postgres: ${error.message}`);\n throw error;\n }\n }\n\n private async disconnect(): Promise<void> {\n const pool = this.pool;\n if (!pool) return;\n\n this.pool = null;\n this.migrationManager = null;\n\n this.logger.info(chalk.gray('Closing Postgres pool.'));\n await pool.end().catch((err) => {\n this.logger.error(`Could not close pg pool: ${(err as Error).message}`);\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options or defaults to `latest`.\n *\n * @param options - Target migration or direction overrides\n */\n public async migrate(options?: MigrationOptions): Promise<void> {\n await this.getMigrationManager().migrate(options);\n }\n\n /**\n * Runs a single upwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateUp(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateUp(options);\n }\n\n /**\n * Runs a single downwards migration step unless a custom count is provided.\n *\n * @param options - Optional configuration for step-based execution\n */\n public async migrateDown(options?: StepMigrationOptions): Promise<void> {\n await this.getMigrationManager().migrateDown(options);\n }\n\n /**\n * Lists every migration the manager knows about along with its execution state.\n */\n public listMigrations(): Promise<readonly MigrationInfo[]> {\n return this.getMigrationManager().listMigrations();\n }\n\n /**\n * Lists unapplied migrations.\n */\n public async listPendingMigrations(): Promise<MigrationInfo[]> {\n const all = await this.listMigrations();\n return all.filter((m) => !m.executedAt);\n }\n\n private getMigrationManager(): KpgMigrationManager<Database> {\n if (this.migrationManager) return this.migrationManager;\n\n const manager = new KpgMigrationManager({\n db: this.connection,\n logger: this.logger,\n config: this.options.migrations,\n baseDir: process.cwd()\n });\n\n this.migrationManager = manager;\n return manager;\n }\n\n /**\n * Register hook used by decorated services.\n *\n * @internal\n */\n _register(key: KpgServiceKeys, instance: AnyKpgService): void {\n this.serviceRegistry.register(key, instance);\n }\n\n private async resolvePool(): Promise<Pool> {\n const { pool: providedPool, connectionString } = this.options;\n\n if (providedPool instanceof Pool) {\n this.logger.info(chalk.gray('Reusing provided Postgres pool instance.'));\n this.databaseName = this.databaseBootstrapper.resolveDatabaseFromPool(providedPool);\n return providedPool;\n }\n\n const baseConfig = this.createPoolConfig(providedPool, connectionString);\n await this.databaseBootstrapper.ensure(baseConfig);\n this.databaseName = this.databaseBootstrapper.resolveDatabaseName(baseConfig);\n\n this.logger.info(chalk.gray('Creating new Postgres pool.'));\n return new Pool(baseConfig);\n }\n\n private createPoolConfig(poolConfig?: PoolConfig, connectionString?: string): PoolConfig {\n const config: PoolConfig = poolConfig ? { ...poolConfig } : {};\n\n if (connectionString) {\n config.connectionString = connectionString;\n }\n\n if (this.options.forceInsecureSSL) {\n config.ssl = { rejectUnauthorized: false };\n }\n\n return config;\n }\n\n private registerOnConnectStatements(pool: Pool, statements?: string[]): void {\n if (!statements?.length) return;\n\n const queuedStatements = [...statements];\n pool.on('connect', (client) => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })();\n });\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","import { CustomError, DatabaseError, SeedcordError, SeedcordErrorCode, throwCustomError } from 'seedcord';\n\n/**\n * Catches and wraps database operation errors.\n *\n * Wraps non-CustomError exceptions in DatabaseError instances\n * with UUID tracking. Should be applied to database service methods.\n *\n * @typeParam TypeReturn - The return type of the decorated method\n * @param errorMessage - Message to include when wrapping errors\n * @decorator\n * @example\n * ```typescript\n * class UserService extends MongoService<IUser> {\n * \\@WrapDatabaseError('Failed to find user')\n * async findById(id: string) {\n * return this.model.findById(id);\n * }\n * }\n * ```\n *\n * @see {@link DatabaseError}\n * @see {@link CustomError}\n * @see {@link MongoService}\n */\nexport function WrapDatabaseError<TypeReturn>(errorMessage: string) {\n return function (\n _target: unknown,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<TypeReturn>>\n ): void {\n const originalMethod = descriptor.value;\n\n descriptor.value = async function (...args: any[]): Promise<TypeReturn> {\n if (!originalMethod) {\n throw new SeedcordError(SeedcordErrorCode.DecoratorMethodNotFound);\n }\n\n try {\n return await originalMethod.apply(this, args);\n } catch (error) {\n if (!(error instanceof CustomError)) {\n throwCustomError(error, errorMessage, DatabaseError);\n } else {\n throw error;\n }\n }\n };\n };\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@seedcord/plugins",
3
3
  "type": "module",
4
- "version": "0.4.2",
4
+ "version": "0.4.4",
5
5
  "description": "Official plugins for Seedcord Discord bot framework",
6
6
  "repository": {
7
7
  "type": "git",
@@ -34,14 +34,14 @@
34
34
  "pg": "^8.16.3",
35
35
  "reflect-metadata": "0.2.2",
36
36
  "type-fest": "5.1.0",
37
- "@seedcord/utils": "^0.3.4",
38
37
  "@seedcord/types": "^0.3.3",
39
- "seedcord": "^0.7.0"
38
+ "seedcord": "^0.9.0",
39
+ "@seedcord/utils": "^0.3.5"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/pg": "^8.15.6",
43
43
  "@seedcord/eslint-config": "^1.3.1",
44
- "@seedcord/tsconfig": "^1.0.5",
44
+ "@seedcord/tsconfig": "^1.0.6",
45
45
  "@seedcord/tsup-config": "^1.0.5"
46
46
  },
47
47
  "scripts": {