@seedcord/plugins 0.7.0-next.0 → 0.7.1-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -165,7 +165,7 @@ var Mongo = class extends seedcord.Plugin {
165
165
  /**
166
166
  * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.
167
167
  *
168
- * @throws A {@link SeedcordError} if accessed before the plugin finishes initializing (e.g. from
168
+ * @throws A **SeedcordError** if accessed before the plugin finishes initializing (e.g. from
169
169
  * a plugin that starts in an earlier phase).
170
170
  */
171
171
  get services() {
@@ -930,7 +930,7 @@ var KyselyPg = class extends seedcord.Plugin {
930
930
  //#endregion
931
931
  //#region src/index.ts
932
932
  /** Package version */
933
- const version = "0.7.0-next.0";
933
+ const version = "0.7.1-next.0";
934
934
 
935
935
  //#endregion
936
936
  exports.KpgService = KpgService;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["SeedcordError","SeedcordErrorCode","Plugin","Logger","SeedcordError","SeedcordErrorCode","ShutdownPhase","Envapter","HmrModuleHandler","SeedcordError","SeedcordErrorCode","Pool","NO_MIGRATIONS","SeedcordRangeError","SeedcordErrorCode","SeedcordError","Migrator","fs","FileMigrationProvider","path","Plugin","Logger","SeedcordError","SeedcordErrorCode","ShutdownPhase","Envapter","HmrModuleHandler","Kysely","PostgresDialect","Pool"],"sources":["../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/index.ts"],"sourcesContent":["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 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\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 { 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, this);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined, traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\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 { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\ninterface MongoArtifact {\n key?: string;\n modelName?: string;\n}\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 servicesReady = false;\n private readonly uri: string;\n\n private readonly _services: Record<string, unknown> = {};\n\n /**\n * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.\n *\n * @throws A {@link SeedcordError} if accessed before the plugin finishes initializing (e.g. from\n * a plugin that starts in an earlier phase).\n */\n public get services(): MongoServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServicesNotReady);\n }\n // MongoServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this public boundary.\n return this._services;\n }\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n private readonly hmrHandler?: HmrModuleHandler<MongoServiceConstructor, void, MongoArtifact>;\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 if (!Envapter.isDevelopment) return;\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.isServiceClass.bind(this),\n registerHandler: this.initializeService.bind(this),\n unregisterHandler: this.unregister.bind(this),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'Mongo'\n });\n }\n\n private getArtifacts(ctor: MongoServiceConstructor): MongoArtifact {\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<unknown> | undefined;\n return {\n ...(key ? { key } : {}),\n ...(model?.modelName ? { modelName: model.modelName } : {})\n };\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.clearModels();\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 clearModels(): void {\n const modelNames = Object.keys(mongoose.models);\n if (modelNames.length > 0) {\n this.logger.debug(`Clearing ${modelNames.length} mongoose models`);\n for (const name of modelNames) mongoose.deleteModel(name);\n }\n }\n\n private async disconnect(): Promise<void> {\n this.clearModels();\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- connect() may have failed before assigning, so there is nothing to disconnect\n if (!this.connection) return;\n\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => {\n this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`);\n throw new SeedcordError(SeedcordErrorCode.PluginMongoDisconnectFailed, { cause: err });\n });\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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.hmrHandler?.trackHandler(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this._services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n private initializeService(Service: MongoServiceConstructor, relativePath: string): void {\n const instance = new Service(this, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\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(key: string, instance: unknown): void {\n this._services[key] = instance;\n }\n\n private unregister(Service: MongoServiceConstructor, artifacts?: { key?: string; modelName?: string }): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(ServiceMetadataKey, Service) as string | undefined);\n const modelName =\n artifacts?.modelName ??\n (Reflect.getMetadata(ModelMetadataKey, Service) as mongoose.Model<unknown> | undefined)?.modelName;\n\n if (key && this._services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this._services[key];\n }\n\n if (modelName) {\n mongoose.deleteModel(modelName);\n }\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type { Kysely } from 'kysely';\nimport type { Core } from 'seedcord';\nimport type { LiteralUnion } from 'type-fest';\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 LiteralUnion<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, this);\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 { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from '@seedcord/services';\n\n/**\n * Ensures the target Postgres database exists, creating it if missing.\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError, SeedcordRangeError } from '@seedcord/errors/internal';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely/migration';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type {\n Migration,\n MigrationInfo,\n MigrationProvider,\n MigrationResult,\n MigrationResultSet\n} from 'kysely/migration';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n *\n * @sealed\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.utils.item(`${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.utils.item(`${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;\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import { traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyArtifact, KyselyPg } from './KyselyPg';\nimport type { KpgServices } from './types/KpgServices';\nimport type { Logger } from '@seedcord/services';\nimport type { Core } 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, unknown> = Object.create(null) as Record<string, unknown>;\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 // KpgServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this boundary.\n return this.services;\n }\n\n public register(key: string, instance: unknown): 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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.plugin.trackServiceFile(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this.services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n public unregister(Service: KyselyServiceConstructor<Database>, artifacts?: KyselyArtifact): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(PgServiceMetadataKey, Service) as string | undefined);\n if (key && this.services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this.services[key];\n }\n }\n\n public initializeService(Service: KyselyServiceConstructor<Database>, relativePath: string): void {\n const instance = new Service(this.plugin, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\n }\n\n public 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig, type PoolClient } from 'pg';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { KpgServices } from './types/KpgServices';\nimport type { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { MigrationInfo } from 'kysely/migration';\nimport type { Core } from 'seedcord';\n\nexport interface KyselyArtifact {\n key?: string;\n}\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 private servicesReady = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private onConnectHandler: ((client: PoolClient) => void) | 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 private readonly hmrHandler?: HmrModuleHandler<KyselyServiceConstructor<Database>, void, KyselyArtifact>;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServicesNotReady);\n }\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 if (!Envapter.isDevelopment) return; // HMR only in development\n\n const relPaths = this.options.migrations.path;\n super.registerCriticalFiles(Array.isArray(relPaths) ? relPaths : [relPaths]);\n\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.serviceRegistry.isServiceClass.bind(this.serviceRegistry),\n registerHandler: this.serviceRegistry.initializeService.bind(this.serviceRegistry),\n unregisterHandler: this.serviceRegistry.unregister.bind(this.serviceRegistry),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'KyselyPg'\n });\n }\n\n private getArtifacts(ctor: KyselyServiceConstructor<Database>): KyselyArtifact {\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n return key ? { key } : {};\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\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 if (this.onConnectHandler) {\n pool.removeListener('connect', this.onConnectHandler);\n this.onConnectHandler = null;\n }\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 throw new SeedcordError(SeedcordErrorCode.PluginKpgDisconnectFailed, { cause: err });\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options.\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 registered with the manager 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: string, instance: unknown): void {\n this.serviceRegistry.register(key, instance);\n }\n\n /**\n * Tracks a service file with the HMR handler so dev reloads can swap it. No-op outside dev.\n *\n * @internal Lets {@link KpgServiceRegistry} reach the dev-only HMR handler without poking a\n * private field.\n */\n public trackServiceFile(filePath: string, ctor: KyselyServiceConstructor<Database>): void {\n this.hmrHandler?.trackHandler(filePath, ctor);\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 const handler = (client: PoolClient): void => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })().catch((err) => this.logger.error('Failed to run onConnect SQL', err));\n };\n\n this.onConnectHandler = handler;\n pool.on('connect', handler);\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","export * from './mongo';\nexport * from './kysely-pg';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["SeedcordError","SeedcordErrorCode","Plugin","Logger","SeedcordError","SeedcordErrorCode","ShutdownPhase","Envapter","HmrModuleHandler","SeedcordError","SeedcordErrorCode","Pool","NO_MIGRATIONS","SeedcordRangeError","SeedcordErrorCode","SeedcordError","Migrator","fs","FileMigrationProvider","path","Plugin","Logger","SeedcordError","SeedcordErrorCode","ShutdownPhase","Envapter","HmrModuleHandler","Kysely","PostgresDialect","Pool"],"sources":["../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/index.ts"],"sourcesContent":["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 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\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 { 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, this);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined, traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\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 { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\ninterface MongoArtifact {\n key?: string;\n modelName?: string;\n}\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 servicesReady = false;\n private readonly uri: string;\n\n private readonly _services: Record<string, unknown> = {};\n\n /**\n * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.\n *\n * @throws A **SeedcordError** if accessed before the plugin finishes initializing (e.g. from\n * a plugin that starts in an earlier phase).\n */\n public get services(): MongoServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServicesNotReady);\n }\n // MongoServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this public boundary.\n return this._services;\n }\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n private readonly hmrHandler?: HmrModuleHandler<MongoServiceConstructor, void, MongoArtifact>;\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 if (!Envapter.isDevelopment) return;\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.isServiceClass.bind(this),\n registerHandler: this.initializeService.bind(this),\n unregisterHandler: this.unregister.bind(this),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'Mongo'\n });\n }\n\n private getArtifacts(ctor: MongoServiceConstructor): MongoArtifact {\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<unknown> | undefined;\n return {\n ...(key ? { key } : {}),\n ...(model?.modelName ? { modelName: model.modelName } : {})\n };\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.clearModels();\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 clearModels(): void {\n const modelNames = Object.keys(mongoose.models);\n if (modelNames.length > 0) {\n this.logger.debug(`Clearing ${modelNames.length} mongoose models`);\n for (const name of modelNames) mongoose.deleteModel(name);\n }\n }\n\n private async disconnect(): Promise<void> {\n this.clearModels();\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- connect() may have failed before assigning, so there is nothing to disconnect\n if (!this.connection) return;\n\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => {\n this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`);\n throw new SeedcordError(SeedcordErrorCode.PluginMongoDisconnectFailed, { cause: err });\n });\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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.hmrHandler?.trackHandler(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this._services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n private initializeService(Service: MongoServiceConstructor, relativePath: string): void {\n const instance = new Service(this, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\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(key: string, instance: unknown): void {\n this._services[key] = instance;\n }\n\n private unregister(Service: MongoServiceConstructor, artifacts?: { key?: string; modelName?: string }): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(ServiceMetadataKey, Service) as string | undefined);\n const modelName =\n artifacts?.modelName ??\n (Reflect.getMetadata(ModelMetadataKey, Service) as mongoose.Model<unknown> | undefined)?.modelName;\n\n if (key && this._services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this._services[key];\n }\n\n if (modelName) {\n mongoose.deleteModel(modelName);\n }\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type { Kysely } from 'kysely';\nimport type { Core } from 'seedcord';\nimport type { LiteralUnion } from 'type-fest';\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 LiteralUnion<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, this);\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 { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from '@seedcord/services';\n\n/**\n * Ensures the target Postgres database exists, creating it if missing.\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError, SeedcordRangeError } from '@seedcord/errors/internal';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely/migration';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type {\n Migration,\n MigrationInfo,\n MigrationProvider,\n MigrationResult,\n MigrationResultSet\n} from 'kysely/migration';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n *\n * @sealed\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.utils.item(`${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.utils.item(`${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;\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import { traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyArtifact, KyselyPg } from './KyselyPg';\nimport type { KpgServices } from './types/KpgServices';\nimport type { Logger } from '@seedcord/services';\nimport type { Core } 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, unknown> = Object.create(null) as Record<string, unknown>;\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 // KpgServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this boundary.\n return this.services;\n }\n\n public register(key: string, instance: unknown): 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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.plugin.trackServiceFile(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this.services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n public unregister(Service: KyselyServiceConstructor<Database>, artifacts?: KyselyArtifact): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(PgServiceMetadataKey, Service) as string | undefined);\n if (key && this.services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this.services[key];\n }\n }\n\n public initializeService(Service: KyselyServiceConstructor<Database>, relativePath: string): void {\n const instance = new Service(this.plugin, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\n }\n\n public 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig, type PoolClient } from 'pg';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { KpgServices } from './types/KpgServices';\nimport type { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { MigrationInfo } from 'kysely/migration';\nimport type { Core } from 'seedcord';\n\nexport interface KyselyArtifact {\n key?: string;\n}\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 private servicesReady = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private onConnectHandler: ((client: PoolClient) => void) | 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 private readonly hmrHandler?: HmrModuleHandler<KyselyServiceConstructor<Database>, void, KyselyArtifact>;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServicesNotReady);\n }\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 if (!Envapter.isDevelopment) return; // HMR only in development\n\n const relPaths = this.options.migrations.path;\n super.registerCriticalFiles(Array.isArray(relPaths) ? relPaths : [relPaths]);\n\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.serviceRegistry.isServiceClass.bind(this.serviceRegistry),\n registerHandler: this.serviceRegistry.initializeService.bind(this.serviceRegistry),\n unregisterHandler: this.serviceRegistry.unregister.bind(this.serviceRegistry),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'KyselyPg'\n });\n }\n\n private getArtifacts(ctor: KyselyServiceConstructor<Database>): KyselyArtifact {\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n return key ? { key } : {};\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\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 if (this.onConnectHandler) {\n pool.removeListener('connect', this.onConnectHandler);\n this.onConnectHandler = null;\n }\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 throw new SeedcordError(SeedcordErrorCode.PluginKpgDisconnectFailed, { cause: err });\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options.\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 registered with the manager 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: string, instance: unknown): void {\n this.serviceRegistry.register(key, instance);\n }\n\n /**\n * Tracks a service file with the HMR handler so dev reloads can swap it. No-op outside dev.\n *\n * @internal Lets {@link KpgServiceRegistry} reach the dev-only HMR handler without poking a\n * private field.\n */\n public trackServiceFile(filePath: string, ctor: KyselyServiceConstructor<Database>): void {\n this.hmrHandler?.trackHandler(filePath, ctor);\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 const handler = (client: PoolClient): void => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })().catch((err) => this.logger.error('Failed to run onConnect SQL', err));\n };\n\n this.onConnectHandler = handler;\n pool.on('connect', handler);\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","export * from './mongo';\nexport * from './kysely-pg';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -65,7 +65,7 @@ declare class Mongo extends Plugin {
65
65
  /**
66
66
  * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.
67
67
  *
68
- * @throws A {@link SeedcordError} if accessed before the plugin finishes initializing (e.g. from
68
+ * @throws A **SeedcordError** if accessed before the plugin finishes initializing (e.g. from
69
69
  * a plugin that starts in an earlier phase).
70
70
  */
71
71
  get services(): MongoServices;
package/dist/index.mjs CHANGED
@@ -134,7 +134,7 @@ var Mongo = class extends Plugin {
134
134
  /**
135
135
  * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.
136
136
  *
137
- * @throws A {@link SeedcordError} if accessed before the plugin finishes initializing (e.g. from
137
+ * @throws A **SeedcordError** if accessed before the plugin finishes initializing (e.g. from
138
138
  * a plugin that starts in an earlier phase).
139
139
  */
140
140
  get services() {
@@ -899,7 +899,7 @@ var KyselyPg = class extends Plugin {
899
899
  //#endregion
900
900
  //#region src/index.ts
901
901
  /** Package version */
902
- const version = "0.7.0-next.0";
902
+ const version = "0.7.1-next.0";
903
903
 
904
904
  //#endregion
905
905
  export { KpgService, KyselyPg, Mongo, MongoService, RegisterKpgService, RegisterMongoModel, RegisterMongoService, version };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["fs"],"sources":["../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/index.ts"],"sourcesContent":["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 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\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 { 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, this);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined, traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\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 { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\ninterface MongoArtifact {\n key?: string;\n modelName?: string;\n}\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 servicesReady = false;\n private readonly uri: string;\n\n private readonly _services: Record<string, unknown> = {};\n\n /**\n * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.\n *\n * @throws A {@link SeedcordError} if accessed before the plugin finishes initializing (e.g. from\n * a plugin that starts in an earlier phase).\n */\n public get services(): MongoServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServicesNotReady);\n }\n // MongoServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this public boundary.\n return this._services;\n }\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n private readonly hmrHandler?: HmrModuleHandler<MongoServiceConstructor, void, MongoArtifact>;\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 if (!Envapter.isDevelopment) return;\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.isServiceClass.bind(this),\n registerHandler: this.initializeService.bind(this),\n unregisterHandler: this.unregister.bind(this),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'Mongo'\n });\n }\n\n private getArtifacts(ctor: MongoServiceConstructor): MongoArtifact {\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<unknown> | undefined;\n return {\n ...(key ? { key } : {}),\n ...(model?.modelName ? { modelName: model.modelName } : {})\n };\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.clearModels();\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 clearModels(): void {\n const modelNames = Object.keys(mongoose.models);\n if (modelNames.length > 0) {\n this.logger.debug(`Clearing ${modelNames.length} mongoose models`);\n for (const name of modelNames) mongoose.deleteModel(name);\n }\n }\n\n private async disconnect(): Promise<void> {\n this.clearModels();\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- connect() may have failed before assigning, so there is nothing to disconnect\n if (!this.connection) return;\n\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => {\n this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`);\n throw new SeedcordError(SeedcordErrorCode.PluginMongoDisconnectFailed, { cause: err });\n });\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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.hmrHandler?.trackHandler(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this._services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n private initializeService(Service: MongoServiceConstructor, relativePath: string): void {\n const instance = new Service(this, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\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(key: string, instance: unknown): void {\n this._services[key] = instance;\n }\n\n private unregister(Service: MongoServiceConstructor, artifacts?: { key?: string; modelName?: string }): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(ServiceMetadataKey, Service) as string | undefined);\n const modelName =\n artifacts?.modelName ??\n (Reflect.getMetadata(ModelMetadataKey, Service) as mongoose.Model<unknown> | undefined)?.modelName;\n\n if (key && this._services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this._services[key];\n }\n\n if (modelName) {\n mongoose.deleteModel(modelName);\n }\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type { Kysely } from 'kysely';\nimport type { Core } from 'seedcord';\nimport type { LiteralUnion } from 'type-fest';\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 LiteralUnion<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, this);\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 { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from '@seedcord/services';\n\n/**\n * Ensures the target Postgres database exists, creating it if missing.\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError, SeedcordRangeError } from '@seedcord/errors/internal';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely/migration';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type {\n Migration,\n MigrationInfo,\n MigrationProvider,\n MigrationResult,\n MigrationResultSet\n} from 'kysely/migration';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n *\n * @sealed\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.utils.item(`${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.utils.item(`${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;\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import { traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyArtifact, KyselyPg } from './KyselyPg';\nimport type { KpgServices } from './types/KpgServices';\nimport type { Logger } from '@seedcord/services';\nimport type { Core } 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, unknown> = Object.create(null) as Record<string, unknown>;\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 // KpgServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this boundary.\n return this.services;\n }\n\n public register(key: string, instance: unknown): 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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.plugin.trackServiceFile(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this.services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n public unregister(Service: KyselyServiceConstructor<Database>, artifacts?: KyselyArtifact): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(PgServiceMetadataKey, Service) as string | undefined);\n if (key && this.services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this.services[key];\n }\n }\n\n public initializeService(Service: KyselyServiceConstructor<Database>, relativePath: string): void {\n const instance = new Service(this.plugin, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\n }\n\n public 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig, type PoolClient } from 'pg';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { KpgServices } from './types/KpgServices';\nimport type { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { MigrationInfo } from 'kysely/migration';\nimport type { Core } from 'seedcord';\n\nexport interface KyselyArtifact {\n key?: string;\n}\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 private servicesReady = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private onConnectHandler: ((client: PoolClient) => void) | 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 private readonly hmrHandler?: HmrModuleHandler<KyselyServiceConstructor<Database>, void, KyselyArtifact>;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServicesNotReady);\n }\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 if (!Envapter.isDevelopment) return; // HMR only in development\n\n const relPaths = this.options.migrations.path;\n super.registerCriticalFiles(Array.isArray(relPaths) ? relPaths : [relPaths]);\n\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.serviceRegistry.isServiceClass.bind(this.serviceRegistry),\n registerHandler: this.serviceRegistry.initializeService.bind(this.serviceRegistry),\n unregisterHandler: this.serviceRegistry.unregister.bind(this.serviceRegistry),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'KyselyPg'\n });\n }\n\n private getArtifacts(ctor: KyselyServiceConstructor<Database>): KyselyArtifact {\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n return key ? { key } : {};\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\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 if (this.onConnectHandler) {\n pool.removeListener('connect', this.onConnectHandler);\n this.onConnectHandler = null;\n }\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 throw new SeedcordError(SeedcordErrorCode.PluginKpgDisconnectFailed, { cause: err });\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options.\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 registered with the manager 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: string, instance: unknown): void {\n this.serviceRegistry.register(key, instance);\n }\n\n /**\n * Tracks a service file with the HMR handler so dev reloads can swap it. No-op outside dev.\n *\n * @internal Lets {@link KpgServiceRegistry} reach the dev-only HMR handler without poking a\n * private field.\n */\n public trackServiceFile(filePath: string, ctor: KyselyServiceConstructor<Database>): void {\n this.hmrHandler?.trackHandler(filePath, ctor);\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 const handler = (client: PoolClient): void => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })().catch((err) => this.logger.error('Failed to run onConnect SQL', err));\n };\n\n this.onConnectHandler = handler;\n pool.on('connect', handler);\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","export * from './mongo';\nexport * from './kysely-pg';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAIA,MAAa,mBAAmB,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;;;AAuBjD,SAAgB,mBAAsD,YAAsB;CACxF,QAII,QACA,gBACO;EACP,MAAM,SAAS,OAAO;EACtB,MAAM,OAAO,OAAO,UAAU;EAC9B,MAAM,QAAQ,SAAS,MAAM,MAAM,MAAM;EACzC,QAAQ,eAAe,kBAAkB,OAAO,MAAM;CAC1D;AACJ;;;;ACpCA,MAAa,qBAAqB,OAAO,eAAe;;;;;;;;;;;;;;;;;;AAmBxD,SAAgB,qBAAwD,KAAe;CACnF,QAAiF,SAA6B;EAC1G,QAAQ,eAAe,oBAAoB,KAAK,IAAI;CACxD;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;ACQA,IAAsB,eAAtB,MAA8E;CAInD;CACA;CAJvB,AAAgB;CAEhB,AAAO,YACH,AAAmB,IACnB,AAAmB,MACrB;EAFqB;EACA;EAEnB,MAAM,OAAO,KAAK;EAElB,MAAM,MAAM,QAAQ,YAAY,oBAAoB,IAAI;EACxD,IAAI,CAAC,KACD,MAAM,IAAI,cAAc,kBAAkB,oCAAoC,CAAC,KAAK,IAAI,CAAC;EAG7F,MAAM,QAAQ,QAAQ,YAAY,kBAAkB,IAAI;EACxD,IAAI,CAAC,OACD,MAAM,IAAI,cAAc,kBAAkB,kCAAkC,CAAC,KAAK,IAAI,CAAC;EAG3F,KAAK,QAAQ;EAEb,GAAG,UAAU,KAAK,IAAI;CAC1B;AACJ;;;;;;;;;;ACzBA,IAAa,QAAb,cAA2B,OAAO;CA4BV;CACC;CA5BrB,AAAgB,SAAS,IAAI,OAAO,OAAO;CAC3C,AAAQ,gBAAgB;CACxB,AAAQ,gBAAgB;CACxB,AAAiB;CAEjB,AAAiB,YAAqC,CAAC;;;;;;;CAQvD,IAAW,WAA0B;EACjC,IAAI,CAAC,KAAK,eACN,MAAM,IAAI,cAAc,kBAAkB,2BAA2B;EAIzE,OAAO,KAAK;CAChB;CAIA,AAAiB;CAEjB,YACI,AAAgB,MAChB,AAAiB,SACnB;EACE,MAAM,IAAI;EAHM;EACC;EAGjB,KAAK,MAAM,QAAQ;EAEnB,KAAK,KAAK,SAAS,QACf,cAAc,mBACd,iBACA,YAAY,MAAM,KAAK,KAAK,GAC5B,KAAK,QAAQ,OACjB;EAEA,IAAI,CAAC,SAAS,eAAe;EAC7B,KAAK,aAAa,IAAI,iBAAiB;GACnC,aAAa,KAAK,QAAQ;GAC1B,WAAW,KAAK,eAAe,KAAK,IAAI;GACxC,iBAAiB,KAAK,kBAAkB,KAAK,IAAI;GACjD,mBAAmB,KAAK,WAAW,KAAK,IAAI;GAC5C,cAAc,KAAK,aAAa,KAAK,IAAI;GACzC,QAAQ,KAAK;GACb,MAAM;EACV,CAAC;CACL;CAEA,AAAQ,aAAa,MAA8C;EAC/D,MAAM,MAAM,QAAQ,YAAY,oBAAoB,IAAI;EACxD,MAAM,QAAQ,QAAQ,YAAY,kBAAkB,IAAI;EACxD,OAAO;GACH,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;GACrB,GAAI,OAAO,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;EAC7D;CACJ;;CAGA,MAAsB,MAAM,OAAsC;EAC9D,MAAM,KAAK,YAAY,OAAO,KAAK;CACvC;CAEA,MAAa,OAAsB;EAC/B,IAAI,KAAK,eAAe;EACxB,KAAK,gBAAgB;EAErB,MAAM,KAAK,QAAQ;EACnB,MAAM,KAAK,aAAa;EACxB,KAAK,gBAAgB;CACzB;CAEA,MAAa,OAAsB;EAC/B,MAAM,KAAK,WAAW;CAC1B;CAEA,MAAc,UAAyB;EACnC,KAAK,YAAY;EACjB,KAAK,aAAa,MAAM,SACnB,QAAQ,KAAK,KAAK;GACf,QAAQ,KAAK,QAAQ;GACrB,GAAI,SAAS,gBAAgB;IAAE,KAAK;IAAM,KAAK;GAAK;GACpD,GAAG,YAAY,KAAK,QAAQ,qBAAqB,CAAC,CAAC;EACvD,CAAC,CAAC,CACD,MAAM,SAAS;GACZ,KAAK,OAAO,KAAK,MAAM,MAAM,KAAK,yBAAyB,MAAM,QAAQ,KAAK,KAAK,WAAW,IAAI,GAAG,CAAC;GACtG,OAAO;EACX,CAAC,CAAC,CACD,OAAO,QAAQ;GACZ,MAAM,IAAI,cAAc,kBAAkB,6BAA6B,CAAC,KAAK,QAAQ,IAAI,GAAG,EACxF,OAAO,IACX,CAAC;EACL,CAAC;CACT;CAEA,AAAQ,cAAoB;EACxB,MAAM,aAAa,OAAO,KAAK,SAAS,MAAM;EAC9C,IAAI,WAAW,SAAS,GAAG;GACvB,KAAK,OAAO,MAAM,YAAY,WAAW,OAAO,iBAAiB;GACjE,KAAK,MAAM,QAAQ,YAAY,SAAS,YAAY,IAAI;EAC5D;CACJ;CAEA,MAAc,aAA4B;EACtC,KAAK,YAAY;EAGjB,IAAI,CAAC,KAAK,YAAY;EAEtB,MAAM,KAAK,WACN,WAAW,CAAC,CACZ,WAAW,KAAK,OAAO,KAAK,MAAM,IAAI,KAAK,2BAA2B,CAAC,CAAC,CAAC,CACzE,OAAO,QAAQ;GACZ,KAAK,OAAO,MAAM,sCAAuC,IAAc,SAAS;GAChF,MAAM,IAAI,cAAc,kBAAkB,6BAA6B,EAAE,OAAO,IAAI,CAAC;EACzF,CAAC;CACT;CAEA,MAAc,eAA8B;EACxC,MAAM,cAAc,KAAK,QAAQ;EACjC,KAAK,OAAO,KAAK,MAAM,KAAK,WAAW,CAAC;EAExC,MAAM,kBACF,cACC,UAAU,KAAK,QAAQ;GACpB,KAAK,MAAM,WAAW,OAAO,OAAO,GAAG,GACnC,IAAI,KAAK,eAAe,OAAO,GAAG;IAC9B,KAAK,kBAAkB,SAAS,GAAG;IACnC,KAAK,YAAY,aAAa,UAAU,OAAO;GACnD;EAER,GACA,KAAK,MACT;EAEA,KAAK,OAAO,MAAM,KACd,CAAC,GAAG,MAAM,QAAQ,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,MAAM,EAAE,UAAU,GAChE,MAAM,KAAK,MAAM,QAAQ,CAC7B;CACJ;CAEA,AAAQ,kBAAkB,SAAkC,cAA4B;EACpF,MAAM,WAAW,IAAI,QAAQ,MAAM,KAAK,IAAI;EAC5C,KAAK,OAAO,MAAM,aAAa,SAAS,YAAY,MAAM,YAAY;CAC1E;CAEA,AAAQ,eAAe,KAA8C;EACjE,OACI,OAAO,QAAQ,cACf,IAAI,qBAAqB,gBACzB,QAAQ,YAAY,oBAAoB,GAAG;CAEnD;;;;;;CAOA,UAAU,KAAa,UAAyB;EAC5C,KAAK,UAAU,OAAO;CAC1B;CAEA,AAAQ,WAAW,SAAkC,WAAwD;EACzG,MAAM,MAAM,WAAW,OAAQ,QAAQ,YAAY,oBAAoB,OAAO;EAC9E,MAAM,YACF,WAAW,aACV,QAAQ,YAAY,kBAAkB,OAAO,CAAC,EAA0C;EAE7F,IAAI,OAAO,KAAK,UAAU,MAEtB,OAAO,KAAK,UAAU;EAG1B,IAAI,WACA,SAAS,YAAY,SAAS;CAEtC;AACJ;;;;ACnNA,MAAa,uBAAuB,OAAO,iBAAiB;AAC5D,MAAa,qBAAqB,OAAO,YAAY;;;;;;;;;;;;;;;;;;;;;;AAuBrD,SAAgB,mBAAgD,KAAW,SAAyC;CAChH,QAAqD,SAAqB;EACtE,QAAQ,eAAe,sBAAsB,KAAK,IAAI;EAEtD,MAAM,YAAY,SAAS,SAAS,OAAO,GAAG;EAC9C,QAAQ,eAAe,oBAAoB,WAAW,IAAI;CAC9D;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACCA,IAAsB,aAAtB,MAA+G;CAIpF;CACA;CAJvB,AAAgB;CAEhB,AAAO,YACH,AAAmB,QACnB,AAAmB,MACrB;EAFqB;EACA;EAEnB,MAAM,OAAO,KAAK;EAElB,MAAM,MAAM,QAAQ,YAAY,sBAAsB,IAAI;EAC1D,IAAI,CAAC,KACD,MAAM,IAAI,cAAc,kBAAkB,kCAAkC,CAAC,KAAK,IAAI,CAAC;EAG3F,MAAM,QAAQ,QAAQ,YAAY,oBAAoB,IAAI;EAG1D,IAAI,CAAC,OACD,MAAM,IAAI,cAAc,kBAAkB,8BAA8B,CAAC,KAAK,IAAI,CAAC;EAGvF,KAAK,QAAQ;EACb,KAAK,OAAO,UAAU,KAAK,IAAI;CACnC;;;;CAKA,IAAW,KAAuB;EAC9B,OAAO,KAAK,OAAO;CACvB;AACJ;;;;;;;AC3DA,IAAa,0BAAb,MAAa,wBAAwB;CAKJ;CAJ7B,OAAwB,WAAW;CACnC,OAAwB,sBACpB;CAEJ,YAAY,AAAiB,QAAgB;EAAhB;CAAiB;CAE9C,AAAO,oBAAoB,QAAmC;EAC1D,OAAO,wBAAwB,kBAAkB,MAAM;CAC3D;CAEA,AAAO,wBAAwB,MAA2B;EACtD,MAAM,SAAqB,CAAC;EAE5B,MAAM,EAAE,YAAY;EAEpB,IAAI,OAAO,QAAQ,aAAa,UAC5B,OAAO,WAAW,QAAQ;EAG9B,IAAI,OAAO,QAAQ,qBAAqB,UACpC,OAAO,mBAAmB,QAAQ;EAGtC,OAAO,KAAK,oBAAoB,MAAM;CAC1C;CAEA,MAAa,OAAO,YAAuC;EACvD,MAAM,WAAW,KAAK,oBAAoB,UAAU;EACpD,IAAI,CAAC,UAAU;GACX,KAAK,OAAO,KAAK,MAAM,KAAK,4DAA4D,CAAC;GACzF;EACJ;EAEA,IAAI,aAAa,wBAAwB,UAAU;GAC/C,KAAK,OAAO,KAAK,MAAM,KAAK,iDAAiD,CAAC;GAC9E;EACJ;EAEA,MAAM,cAAc,KAAK,iBAAiB,UAAU;EACpD,IAAI,CAAC,aAAa;GACd,KAAK,OAAO,KAAK,4DAA4D,UAAU;GACvF;EACJ;EAEA,KAAK,OAAO,KAAK,MAAM,KAAK,qBAAqB,MAAM,OAAO,QAAQ,EAAE,WAAW,CAAC;EAEpF,MAAM,YAAY,IAAI,KAAK,WAAW;EAEtC,IAAI;GAEA,IAAI,MADiB,KAAK,eAAe,WAAW,QAAQ,GAChD;IACR,KAAK,OAAO,KAAK,MAAM,KAAK,YAAY,MAAM,OAAO,QAAQ,EAAE,iBAAiB,CAAC;IACjF;GACJ;GAEA,MAAM,KAAK,eAAe,WAAW,QAAQ;GAC7C,KAAK,OAAO,KAAK,MAAM,MAAM,oBAAoB,MAAM,KAAK,QAAQ,EAAE,EAAE,CAAC;EAC7E,SAAS,OAAO;GACZ,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GACpE,KAAK,OAAO,MAAM,6BAA6B,SAAS,IAAI,IAAI,SAAS;GACzE,MAAM;EACV,UAAU;GACN,MAAM,UAAU,IAAI;EACxB;CACJ;CAEA,AAAQ,iBAAiB,YAA2C;EAChE,MAAM,cAA0B,EAAE,GAAG,WAAW;EAEhD,MAAM,EAAE,qBAAqB;EAC7B,IAAI,kBAAkB;GAClB,MAAM,aAAa,wBAAwB,gCACvC,kBACA,wBAAwB,QAC5B;GACA,IAAI,CAAC,YAAY,OAAO;GACxB,YAAY,mBAAmB;EACnC;EAEA,YAAY,WAAW,wBAAwB;EAC/C,OAAO;CACX;CAEA,MAAc,eAAe,MAAY,UAAoC;EACzE,MAAM,SAAS,MAAM,KAAK,QAAQ;EAClC,IAAI;GACA,MAAM,EAAE,SAAS,MAAM,OAAO,MAA2B,wBAAwB,qBAAqB,CAClG,QACJ,CAAC;GACD,OAAO,QAAQ,KAAK,EAAE,EAAE,MAAM;EAClC,UAAU;GACN,OAAO,QAAQ;EACnB;CACJ;CAEA,MAAc,eAAe,MAAY,UAAiC;EACtE,MAAM,SAAS,MAAM,KAAK,QAAQ;EAClC,IAAI;GACA,MAAM,YAAY,mBAAmB,wBAAwB,iBAAiB,QAAQ;GACtF,MAAM,OAAO,MAAM,SAAS;EAChC,UAAU;GACN,OAAO,QAAQ;EACnB;CACJ;CAEA,OAAe,kBAAkB,QAAmC;EAChE,IAAI,OAAO,OAAO,aAAa,YAAY,OAAO,SAAS,KAAK,CAAC,CAAC,SAAS,GACvE,OAAO,OAAO,SAAS,KAAK;EAGhC,MAAM,mBAAmB,OAAO;EAChC,IAAI,CAAC,kBAAkB,OAAO;EAE9B,IAAI;GAEA,MAAM,WAAW,IADD,IAAI,gBACD,CAAC,CAAC,SAAS,QAAQ,OAAO,EAAE;GAC/C,IAAI,CAAC,UAAU,OAAO;GACtB,MAAM,CAAC,aAAa,SAAS,MAAM,GAAG;GACtC,OAAO,YAAY,mBAAmB,SAAS,IAAI;EACvD,QAAQ;GACJ,OAAO;EACX;CACJ;CAEA,OAAe,gCAAgC,kBAA0B,UAAiC;EACtG,IAAI;GACA,MAAM,MAAM,IAAI,IAAI,gBAAgB;GACpC,IAAI,WAAW,IAAI,mBAAmB,QAAQ;GAC9C,OAAO,IAAI,SAAS;EACxB,QAAQ;GACJ,OAAO;EACX;CACJ;CAEA,OAAe,iBAAiB,YAA4B;EACxD,OAAO,IAAI,WAAW,QAAQ,MAAM,MAAI,EAAE;CAC9C;AACJ;;;;;;;;;ACnHA,IAAa,sBAAb,MAA0D;CACzB;CAA7B,YAAY,AAAiB,KAAwC;EAAxC;CAAyC;CAEtE,MAAa,QAAQ,SAA2C;EAC5D,MAAM,EAAE,QAAQ,YAAY,UAAU,UAAU,WAAW,CAAC;EAE5D,IAAI,OAAO,WAAW,aAAa;GAC/B,MAAM,QAAQ,WAAW,gBAAgB,kBAAkB;GAC3D,MAAM,KAAK,cAAc,aAAa,SAAS,UAAU,MAAM,GAAG,gBAAgB,MAAM,OAAO,KAAK,EAAE,IAAI;GAC1G;EACJ;EAEA,QAAQ,WAAR;GACI,KAAK;IACD,MAAM,KAAK,cAAc,aAAa,SAAS,gBAAgB,CAAC;IAChE;GACJ,KAAK;GACL,KAAK,QAAQ;IACT,MAAM,YAAY,SAAS;IAC3B,IAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,GAC5C,MAAM,IAAI,mBAAmB,kBAAkB,yBAAyB;IAG5E,IAAI,cAAc,GAAG;KACjB,KAAK,oBAAoB,CAAC,CAAC;KAC3B;IACJ;IAEA,MAAM,SACF,cAAc,QACP,aAAuB,SAAS,UAAU,KAC1C,aAAuB,SAAS,YAAY;IACvD,MAAM,KAAK,YAAY,WAAW,WAAW,MAAM;IACnD;GACJ;GACA,SACI,MAAM,IAAI,cAAc,kBAAkB,2BAA2B,CAAC,SAAS,CAAC;EACxF;CACJ;CAEA,MAAa,UAAU,SAA+C;EAClE,IAAI,OAAO,SAAS,UAAU,aAAa;GACvC,MAAM,KAAK,QAAQ,EAAE,WAAW,KAAK,CAAC;GACtC;EACJ;EAEA,MAAM,KAAK,QAAQ;GAAE,WAAW;GAAM,OAAO,QAAQ;EAAM,CAAC;CAChE;CAEA,MAAa,YAAY,SAA+C;EACpE,IAAI,OAAO,SAAS,UAAU,aAAa;GACvC,MAAM,KAAK,QAAQ,EAAE,WAAW,OAAO,CAAC;GACxC;EACJ;EAEA,MAAM,KAAK,QAAQ;GAAE,WAAW;GAAQ,OAAO,QAAQ;EAAM,CAAC;CAClE;CAEA,MAAa,iBAAoD;EAE7D,QAAO,MADgB,KAAK,eAAe,EAC5B,CAAC,cAAc;CAClC;CAEA,MAAc,aACV,QACA,iBAAiB,yBACJ;EACb,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,yBAAyB,CAAC;EAC1D,MAAM,WAAW,MAAM,KAAK,eAAe;EAE3C,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,cAAc,CAAC;EAC/C,MAAM,EAAE,OAAO,YAAY,MAAM,OAAO,QAAQ;EAEhD,KAAK,oBAAoB,WAAW,CAAC,CAAC;EAEtC,IAAI,OACA,KAAK,qBAAqB,KAAK;CAEvC;CAEA,MAAc,YACV,OACA,WACA,QACa;EACb,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,yBAAyB,CAAC;EAC1D,MAAM,WAAW,MAAM,KAAK,eAAe;EAE3C,MAAM,iBAAiB,cAAc,OAAO,YAAY;EACxD,MAAM,aAAa,UAAU,IAAI,kBAAkB,GAAG,MAAM,OAAO,OAAO,KAAK,CAAC,EAAE;EAClF,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,GAAG,eAAe,GAAG,WAAW,IAAI,CAAC;EAErE,MAAM,aAAgC,CAAC;EACvC,IAAI;EAEJ,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAAG;GAC3C,MAAM,EAAE,OAAO,YAAY,MAAM,OAAO,QAAQ;GAEhD,IAAI,SAAS,QACT,WAAW,KAAK,GAAG,OAAO;GAG9B,IAAI,OAAO;IACP,mBAAmB;IACnB;GACJ;GAEA,IAAI,CAAC,SAAS,QACV;EAER;EAEA,KAAK,oBAAoB,UAAU;EAEnC,IAAI,kBACA,KAAK,qBAAqB,gBAAgB;CAElD;CAEA,MAAc,iBAAoC;EAC9C,MAAM,WAAW,MAAM,KAAK,qBAAqB;EACjD,MAAM,EAAE,WAAW,KAAK;EAExB,OAAO,IAAI,SAAS;GAChB,IAAI,KAAK,IAAI;GACb;GACA,0BAA0B,OAAO,4BAA4B;GAC7D,GAAG,YAAY,QAAQ,sBAAsB,0BAA0B,sBAAsB;EACjG,CAAC;CACL;CAEA,MAAc,uBAAmD;EAC7D,MAAM,EAAE,MAAM,WAAW,KAAK,IAAI;EAClC,MAAM,iBAAiB,MAAM,QAAQ,MAAM,IACrC,OAAO,KAAK,UAAU,KAAK,YAAY,KAAK,CAAC,IAC7C,KAAK,YAAY,MAAM;EAE7B,IAAI,MAAM,QAAQ,cAAc,GAAG;GAC/B,KAAK,kBAAkB,cAAc;GACrC,OAAO,KAAK,qBAAqB,cAAc;EACnD;EAEA,IAAI;EACJ,IAAI;GACA,gBAAgB,MAAMA,SAAG,KAAK,cAAc;EAChD,QAAQ;GACJ,gBAAgB;EACpB;EAEA,IAAI,eAAe,YAAY,GAAG;GAC9B,MAAM,YAAY,KAAK,aAAa,cAAc;GAClD,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,gCAAgC,MAAM,OAAO,SAAS,GAAG,CAAC;GAC1F,OAAO,IAAI,sBAAsB;IAAE;IAAI;IAAM,iBAAiB;GAAe,CAAC;EAClF;EAEA,IAAI,eAAe,OAAO,KAAK,MAAM;GACjC,KAAK,kBAAkB,CAAC,cAAc,CAAC;GACvC,OAAO,KAAK,qBAAqB,CAAC,cAAc,CAAC;EACrD;EAEA,MAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,IAAI,IAAI;EAC1D,MAAM,IAAI,cAAc,kBAAkB,mCAAmC,CAAC,KAAK,CAAC;CACxF;CAEA,MAAc,qBAAqB,OAA6C;EAC5E,IAAI,MAAM,WAAW,GACjB,MAAM,IAAI,cAAc,kBAAkB,yBAAyB;EAGvE,MAAM,aACF,KAAK,IAAI,OAAO,oBAAoB,OAAe,UAAkB,MAAM,cAAc,KAAK;EA4BlG,MAAM,UAAS,MA1BO,QAAQ,IAC1B,MAAM,IAAI,OAAO,aAAa;GAE1B,MAAM,MAAe,MAAM,OADT,cAAc,QAAQ,CAAC,CAAC;GAG1C,IAAI,CAAC,KAAK,kBAAkB,GAAG,GAC3B,MAAM,IAAI,cAAc,kBAAkB,iCAAiC,CAAC,QAAQ,CAAC;GAGzF,MAAM,EAAE,IAAI,SAAS;GAarB,OAAO,CAXM,KAAK,SAAS,QAWhB,GAAG;IARV,MAAM,GAAG,IAAI;KACT,MAAM,GAAG,EAAE;IACf;IACA,MAAM,KAAK,IAAI;KACX,MAAM,KAAK,EAAE;IACjB;GAGkB,CAAC;EAC3B,CAAC,CACL,EAEsB,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,GAAG,CAAC,CAAC;EAC1D,KAAK,sBAAsB,MAAM;EAEjC,OAAO,EACH,qBAAqB,QAAQ,QAAQ,OAAO,YAAY,MAAM,CAAC,EACnE;CACJ;CAEA,AAAQ,kBAAkB,OAAgC;EACtD,IAAI,CAAC,MAAM,QAAQ;EAEnB,KAAK,IAAI,OAAO,KAAK,4BAA4B;EACjD,KAAK,MAAM,QAAQ,OACf,KAAK,IAAI,OAAO,MAAM,KAAK,GAAG,MAAM,OAAO,KAAK,aAAa,IAAI,CAAC,GAAG;CAE7E;CAEA,AAAQ,sBAAsB,SAA0D;EACpF,IAAI,CAAC,QAAQ,QAAQ;EAErB,KAAK,IAAI,OAAO,KAAK,sBAAsB;EAC3C,KAAK,MAAM,CAAC,SAAS,SACjB,KAAK,IAAI,OAAO,MAAM,KAAK,GAAG,MAAM,MAAM,IAAI,GAAG;CAEzD;CAEA,AAAQ,oBAAoB,SAA2C;EACnE,IAAI,CAAC,QAAQ,QAAQ;GACjB,KAAK,IAAI,OAAO,KAAK,MAAM,KAAK,yBAAyB,CAAC;GAC1D;EACJ;EAEA,KAAK,IAAI,OAAO,KAAK,oBAAoB;EAEzC,KAAK,MAAM,UAAU,SAAS;GAC1B,IAAI,OAAO,WAAW,WAAW;IAC7B,KAAK,IAAI,OAAO,KAAK,GAAG,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,KAAK,OAAO,aAAa,GAAG;IAC9E;GACJ;GAEA,IAAI,OAAO,WAAW,SAAS;IAC3B,KAAK,IAAI,OAAO,MAAM,GAAG,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,KAAK,OAAO,aAAa,GAAG;IAC7E;GACJ;GAEA,KAAK,IAAI,OAAO,KAAK,GAAG,MAAM,OAAO,GAAG,EAAE,GAAG,MAAM,KAAK,OAAO,aAAa,EAAE,GAAG,MAAM,KAAK,WAAW,GAAG;EAC9G;CACJ;CAEA,AAAQ,aAAa,UAA0B;EAC3C,MAAM,WAAW,KAAK,SAAS,KAAK,IAAI,SAAS,QAAQ;EACzD,OAAO,SAAS,WAAW,IAAI,IAAI,WAAW;CAClD;CAEA,AAAQ,YAAY,QAAwB;EACxC,IAAI,KAAK,WAAW,MAAM,GAAG,OAAO;EACpC,OAAO,KAAK,QAAQ,KAAK,IAAI,SAAS,MAAM;CAChD;CAEA,AAAQ,qBAAqB,OAAuB;EAChD,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,QAAQ,KAAK;EACtE,KAAK,IAAI,OAAO,MAAM,sBAAsB,SAAS;EAErD,IAAI,iBAAiB,OACjB,MAAM;EAGV,MAAM,IAAI,cAAc,kBAAkB,0BAA0B,CAAC,OAAO,CAAC;CACjF;CAEA,AAAQ,kBAAkB,OAA0C;EAChE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;EAChD,IAAI,EAAE,QAAQ,UAAU,EAAE,UAAU,QAAQ,OAAO;EAEnD,MAAM,EAAE,IAAI,SAAS;EAErB,OAAO,OAAO,OAAO,cAAc,OAAO,SAAS;CACvD;AACJ;;;;;;;ACpSA,IAAa,qBAAb,MAAyD;CAIhC;CACA;CACA;CALrB,AAAiB,WAAoC,OAAO,OAAO,IAAI;CAEvE,YACI,AAAiB,QACjB,AAAiB,MACjB,AAAiB,QACnB;EAHmB;EACA;EACA;CAClB;CAEH,IAAW,MAAmB;EAG1B,OAAO,KAAK;CAChB;CAEA,AAAO,SAAS,KAAa,UAAyB;EAClD,KAAK,SAAS,OAAO;CACzB;CAEA,MAAa,kBAAkB,KAA4B;EACvD,KAAK,OAAO,KAAK,MAAM,KAAK,GAAG,CAAC;EAEhC,MAAM,kBACF,MACC,UAAU,KAAK,QAAQ;GACpB,KAAK,MAAM,WAAW,OAAO,OAAO,GAAG,GACnC,IAAI,KAAK,eAAe,OAAO,GAAG;IAC9B,KAAK,kBAAkB,SAAS,GAAG;IACnC,KAAK,OAAO,iBAAiB,UAAU,OAAO;GAClD;EAER,GACA,KAAK,MACT;EAEA,KAAK,OAAO,MAAM,KACd,CAAC,GAAG,MAAM,QAAQ,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,MAAM,EAAE,UAAU,GAC/D,MAAM,KAAK,MAAM,QAAQ,CAC7B;CACJ;CAEA,AAAO,WAAW,SAA6C,WAAkC;EAC7F,MAAM,MAAM,WAAW,OAAQ,QAAQ,YAAY,sBAAsB,OAAO;EAChF,IAAI,OAAO,KAAK,SAAS,MAErB,OAAO,KAAK,SAAS;CAE7B;CAEA,AAAO,kBAAkB,SAA6C,cAA4B;EAC9F,MAAM,WAAW,IAAI,QAAQ,KAAK,QAAQ,KAAK,IAAI;EACnD,KAAK,OAAO,MAAM,aAAa,SAAS,YAAY,MAAM,YAAY;CAC1E;CAEA,AAAO,eAAe,KAAyD;EAC3E,OACI,OAAO,QAAQ,cACf,IAAI,qBAAqB,cACzB,QAAQ,YAAY,sBAAsB,GAAG;CAErD;AACJ;;;;;;;;;;ACzCA,IAAa,WAAb,cAAuD,OAAO;CA0BtC;CACC;CA1BrB,AAAgB,SAAS,IAAI,OAAO,UAAU;CAC9C,AAAQ,gBAAgB;CACxB,AAAQ,gBAAgB;CAIxB,AAAQ,OAAoB;CAC5B,AAAQ,mBAA0D;CAClE,AAAQ,mBAAyD;CACjE,AAAiB;CACjB,AAAiB;CACjB,AAAQ,eAA8B;CACtC,AAAiB;;;;CAKjB,IAAW,WAAwB;EAC/B,IAAI,CAAC,KAAK,eACN,MAAM,IAAI,cAAc,kBAAkB,yBAAyB;EAEvE,OAAO,KAAK,gBAAgB;CAChC;CAEA,YACI,AAAgB,MAChB,AAAiB,SACnB;EACE,MAAM,IAAI;EAHM;EACC;EAGjB,KAAK,kBAAkB,IAAI,mBAAmB,MAAM,MAAM,KAAK,MAAM;EACrE,KAAK,uBAAuB,IAAI,wBAAwB,KAAK,MAAM;EACnE,KAAK,KAAK,SAAS,QACf,cAAc,mBACd,iBACA,YAAY,MAAM,KAAK,KAAK,GAC5B,KAAK,QAAQ,OACjB;EAEA,IAAI,CAAC,SAAS,eAAe;EAE7B,MAAM,WAAW,KAAK,QAAQ,WAAW;EACzC,MAAM,sBAAsB,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC;EAE3E,KAAK,aAAa,IAAI,iBAAiB;GACnC,aAAa,KAAK,QAAQ;GAC1B,WAAW,KAAK,gBAAgB,eAAe,KAAK,KAAK,eAAe;GACxE,iBAAiB,KAAK,gBAAgB,kBAAkB,KAAK,KAAK,eAAe;GACjF,mBAAmB,KAAK,gBAAgB,WAAW,KAAK,KAAK,eAAe;GAC5E,cAAc,KAAK,aAAa,KAAK,IAAI;GACzC,QAAQ,KAAK;GACb,MAAM;EACV,CAAC;CACL;CAEA,AAAQ,aAAa,MAA0D;EAC3E,MAAM,MAAM,QAAQ,YAAY,sBAAsB,IAAI;EAC1D,OAAO,MAAM,EAAE,IAAI,IAAI,CAAC;CAC5B;;CAGA,MAAsB,MAAM,OAAsC;EAC9D,MAAM,KAAK,YAAY,OAAO,KAAK;CACvC;;;;;;CAOA,MAAa,OAAsB;EAC/B,IAAI,KAAK,eAAe;EACxB,KAAK,gBAAgB;EAErB,MAAM,KAAK,QAAQ;EAEnB,MAAM,gBAAgB,KAAK,QAAQ,WAAW;EAC9C,IAAI,kBAAkB,OAClB,IAAI,iBAAiB,OAAO,kBAAkB,WAC1C,MAAM,KAAK,QAAQ,aAAa;OAEhC,MAAM,KAAK,QAAQ;EAG3B,MAAM,KAAK,gBAAgB,kBAAkB,KAAK,QAAQ,GAAG;EAC7D,KAAK,gBAAgB;CACzB;;;;CAKA,MAAa,OAAsB;EAC/B,MAAM,KAAK,WAAW;CAC1B;CAEA,MAAc,UAAyB;EACnC,MAAM,OAAO,MAAM,KAAK,YAAY;EACpC,KAAK,OAAO;EAEZ,KAAK,4BAA4B,MAAM,KAAK,QAAQ,YAAY;EAEhE,IAAI;GACA,MAAM,KAAK,mBAAmB,IAAI;GAElC,KAAK,aAAa,IAAI,OAAiB;IACnC,SAAS,IAAI,gBAAgB,EAAE,KAAK,CAAC;IACrC,GAAG,YAAY,KAAK,QAAQ,UAAU,CAAC,CAAC;GAC5C,CAAC;GAED,KAAK,mBAAmB,IAAI,oBAAoB;IAC5C,IAAI,KAAK;IACT,QAAQ,KAAK;IACb,QAAQ,KAAK,QAAQ;IACrB,SAAS,QAAQ,IAAI;GACzB,CAAC;GAED,MAAM,UAAU,KAAK,gBAAgB;GACrC,KAAK,OAAO,KAAK,kCAAkC,MAAM,KAAK,QAAQ,OAAO,GAAG;EACpF,SAAS,KAAK;GACV,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;GAChE,KAAK,OAAO,MAAM,kCAAkC,MAAM,SAAS;GACnE,MAAM;EACV;CACJ;CAEA,MAAc,aAA4B;EACtC,MAAM,OAAO,KAAK;EAClB,IAAI,CAAC,MAAM;EAEX,IAAI,KAAK,kBAAkB;GACvB,KAAK,eAAe,WAAW,KAAK,gBAAgB;GACpD,KAAK,mBAAmB;EAC5B;EAEA,KAAK,OAAO;EACZ,KAAK,mBAAmB;EAExB,KAAK,OAAO,KAAK,MAAM,KAAK,wBAAwB,CAAC;EACrD,MAAM,KAAK,IAAI,CAAC,CAAC,OAAO,QAAQ;GAC5B,KAAK,OAAO,MAAM,4BAA6B,IAAc,SAAS;GACtE,MAAM,IAAI,cAAc,kBAAkB,2BAA2B,EAAE,OAAO,IAAI,CAAC;EACvF,CAAC;EACD,KAAK,OAAO,KAAK,MAAM,IAAI,KAAK,4BAA4B,CAAC;CACjE;;;;;;CAOA,MAAa,QAAQ,SAA2C;EAC5D,MAAM,KAAK,oBAAoB,CAAC,CAAC,QAAQ,OAAO;CACpD;;;;;;CAOA,MAAa,UAAU,SAA+C;EAClE,MAAM,KAAK,oBAAoB,CAAC,CAAC,UAAU,OAAO;CACtD;;;;;;CAOA,MAAa,YAAY,SAA+C;EACpE,MAAM,KAAK,oBAAoB,CAAC,CAAC,YAAY,OAAO;CACxD;;;;CAKA,AAAO,iBAAoD;EACvD,OAAO,KAAK,oBAAoB,CAAC,CAAC,eAAe;CACrD;;;;CAKA,MAAa,wBAAkD;EAE3D,QAAO,MADW,KAAK,eAAe,EAC5B,CAAC,QAAQ,MAAM,CAAC,EAAE,UAAU;CAC1C;CAEA,AAAQ,sBAAqD;EACzD,IAAI,KAAK,kBAAkB,OAAO,KAAK;EAEvC,MAAM,UAAU,IAAI,oBAAoB;GACpC,IAAI,KAAK;GACT,QAAQ,KAAK;GACb,QAAQ,KAAK,QAAQ;GACrB,SAAS,QAAQ,IAAI;EACzB,CAAC;EAED,KAAK,mBAAmB;EACxB,OAAO;CACX;;;;;;CAOA,UAAU,KAAa,UAAyB;EAC5C,KAAK,gBAAgB,SAAS,KAAK,QAAQ;CAC/C;;;;;;;CAQA,AAAO,iBAAiB,UAAkB,MAAgD;EACtF,KAAK,YAAY,aAAa,UAAU,IAAI;CAChD;CAEA,MAAc,cAA6B;EACvC,MAAM,EAAE,MAAM,cAAc,qBAAqB,KAAK;EAEtD,IAAI,wBAAwB,MAAM;GAC9B,KAAK,OAAO,KAAK,MAAM,KAAK,0CAA0C,CAAC;GACvE,KAAK,eAAe,KAAK,qBAAqB,wBAAwB,YAAY;GAClF,OAAO;EACX;EAEA,MAAM,aAAa,KAAK,iBAAiB,cAAc,gBAAgB;EACvE,MAAM,KAAK,qBAAqB,OAAO,UAAU;EACjD,KAAK,eAAe,KAAK,qBAAqB,oBAAoB,UAAU;EAE5E,KAAK,OAAO,KAAK,MAAM,KAAK,6BAA6B,CAAC;EAC1D,OAAO,IAAI,KAAK,UAAU;CAC9B;CAEA,AAAQ,iBAAiB,YAAyB,kBAAuC;EACrF,MAAM,SAAqB,aAAa,EAAE,GAAG,WAAW,IAAI,CAAC;EAE7D,IAAI,kBACA,OAAO,mBAAmB;EAG9B,IAAI,KAAK,QAAQ,kBACb,OAAO,MAAM,EAAE,oBAAoB,MAAM;EAG7C,OAAO;CACX;CAEA,AAAQ,4BAA4B,MAAY,YAA6B;EACzE,IAAI,CAAC,YAAY,QAAQ;EAEzB,MAAM,mBAAmB,CAAC,GAAG,UAAU;EACvC,MAAM,WAAW,WAA6B;GAC1C,CAAM,YAAY;IACd,KAAK,MAAM,OAAO,kBACd,MAAM,OAAO,MAAM,GAAG;GAE9B,EAAC,CAAE,CAAC,CAAC,OAAO,QAAQ,KAAK,OAAO,MAAM,+BAA+B,GAAG,CAAC;EAC7E;EAEA,KAAK,mBAAmB;EACxB,KAAK,GAAG,WAAW,OAAO;CAC9B;CAEA,MAAc,mBAAmB,MAA2B;EAExD,OADqB,KAAK,QAAQ,EAC5B,CAAC,QAAQ;CACnB;AACJ;;;;;AC9SA,MAAa"}
1
+ {"version":3,"file":"index.mjs","names":["fs"],"sources":["../src/mongo/decorators/RegisterMongoModel.ts","../src/mongo/decorators/RegisterMongoService.ts","../src/mongo/MongoService.ts","../src/mongo/Mongo.ts","../src/kysely-pg/decorators/RegisterKpgService.ts","../src/kysely-pg/KpgService.ts","../src/kysely-pg/KpgDatabaseBootstrapper.ts","../src/kysely-pg/KpgMigrationManager.ts","../src/kysely-pg/KpgServiceRegistry.ts","../src/kysely-pg/KyselyPg.ts","../src/index.ts"],"sourcesContent":["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 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\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 { 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, this);\n }\n}\n\n/** Constructor type for {@link MongoService} classes */\nexport type MongoServiceConstructor = TypedConstructor<typeof MongoService>;\n","import 'reflect-metadata';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined, traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport mongoose from 'mongoose';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { ModelMetadataKey } from './decorators/RegisterMongoModel';\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 { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { Mongoose } from 'mongoose';\nimport type { Core } from 'seedcord';\n\ninterface MongoArtifact {\n key?: string;\n modelName?: string;\n}\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 servicesReady = false;\n private readonly uri: string;\n\n private readonly _services: Record<string, unknown> = {};\n\n /**\n * Map of all loaded services. Keys come from `@RegisterMongoService('key')`.\n *\n * @throws A **SeedcordError** if accessed before the plugin finishes initializing (e.g. from\n * a plugin that starts in an earlier phase).\n */\n public get services(): MongoServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginMongoServicesNotReady);\n }\n // MongoServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this public boundary.\n return this._services;\n }\n\n /** Exposed Mongoose instance once `init` completes. */\n declare public connection: Mongoose;\n private readonly hmrHandler?: HmrModuleHandler<MongoServiceConstructor, void, MongoArtifact>;\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 if (!Envapter.isDevelopment) return;\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.isServiceClass.bind(this),\n registerHandler: this.initializeService.bind(this),\n unregisterHandler: this.unregister.bind(this),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'Mongo'\n });\n }\n\n private getArtifacts(ctor: MongoServiceConstructor): MongoArtifact {\n const key = Reflect.getMetadata(ServiceMetadataKey, ctor) as string | undefined;\n const model = Reflect.getMetadata(ModelMetadataKey, ctor) as mongoose.Model<unknown> | undefined;\n return {\n ...(key ? { key } : {}),\n ...(model?.modelName ? { modelName: model.modelName } : {})\n };\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\n }\n\n public async stop(): Promise<void> {\n await this.disconnect();\n }\n\n private async connect(): Promise<void> {\n this.clearModels();\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 clearModels(): void {\n const modelNames = Object.keys(mongoose.models);\n if (modelNames.length > 0) {\n this.logger.debug(`Clearing ${modelNames.length} mongoose models`);\n for (const name of modelNames) mongoose.deleteModel(name);\n }\n }\n\n private async disconnect(): Promise<void> {\n this.clearModels();\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- connect() may have failed before assigning, so there is nothing to disconnect\n if (!this.connection) return;\n\n await this.connection\n .disconnect()\n .then(() => this.logger.info(chalk.red.bold('Disconnected from MongoDB')))\n .catch((err) => {\n this.logger.error(`Could not disconnect from MongoDB: ${(err as Error).message}`);\n throw new SeedcordError(SeedcordErrorCode.PluginMongoDisconnectFailed, { cause: err });\n });\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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.hmrHandler?.trackHandler(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this._services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n private initializeService(Service: MongoServiceConstructor, relativePath: string): void {\n const instance = new Service(this, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\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(key: string, instance: unknown): void {\n this._services[key] = instance;\n }\n\n private unregister(Service: MongoServiceConstructor, artifacts?: { key?: string; modelName?: string }): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(ServiceMetadataKey, Service) as string | undefined);\n const modelName =\n artifacts?.modelName ??\n (Reflect.getMetadata(ModelMetadataKey, Service) as mongoose.Model<unknown> | undefined)?.modelName;\n\n if (key && this._services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this._services[key];\n }\n\n if (modelName) {\n mongoose.deleteModel(modelName);\n }\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { PgServiceMetadataKey, PgTableMetadataKey } from './decorators/RegisterKpgService';\n\nimport type { KyselyPg } from './KyselyPg';\nimport type { TypedConstructor } from '@seedcord/types';\nimport type { Kysely } from 'kysely';\nimport type { Core } from 'seedcord';\nimport type { LiteralUnion } from 'type-fest';\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 LiteralUnion<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, this);\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 { Pool, type PoolConfig } from 'pg';\n\nimport type { Logger } from '@seedcord/services';\n\n/**\n * Ensures the target Postgres database exists, creating it if missing.\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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError, SeedcordRangeError } from '@seedcord/errors/internal';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { FileMigrationProvider, Migrator, NO_MIGRATIONS } from 'kysely/migration';\n\nimport type {\n MigrationManagerContext,\n MigrationModule,\n MigrationOptions,\n StepMigrationOptions\n} from './types/KpgMigration';\nimport type {\n Migration,\n MigrationInfo,\n MigrationProvider,\n MigrationResult,\n MigrationResultSet\n} from 'kysely/migration';\nimport type { Stats } from 'node:fs';\n\n/**\n * Migration tooling for KyselyPg.\n *\n * @sealed\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.utils.item(`${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.utils.item(`${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;\n\n return typeof up === 'function' && typeof down === 'function';\n }\n}\n","import { traverseDirectory } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgService } from './KpgService';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { KyselyArtifact, KyselyPg } from './KyselyPg';\nimport type { KpgServices } from './types/KpgServices';\nimport type { Logger } from '@seedcord/services';\nimport type { Core } 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, unknown> = Object.create(null) as Record<string, unknown>;\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 // KpgServices is augmented per-consumer via declaration merging; the registry holds the\n // instances opaquely and exposes the generated map shape at this boundary.\n return this.services;\n }\n\n public register(key: string, instance: unknown): 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 (fullPath, rel, mod) => {\n for (const Service of Object.values(mod)) {\n if (this.isServiceClass(Service)) {\n this.initializeService(Service, rel);\n this.plugin.trackServiceFile(fullPath, Service);\n }\n }\n },\n this.logger\n );\n\n this.logger.utils.list(\n [`${chalk.magenta(Object.keys(this.services).length)} services`],\n chalk.bold.green('Loaded')\n );\n }\n\n public unregister(Service: KyselyServiceConstructor<Database>, artifacts?: KyselyArtifact): void {\n const key = artifacts?.key ?? (Reflect.getMetadata(PgServiceMetadataKey, Service) as string | undefined);\n if (key && this.services[key]) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- key is a runtime service name, not a static property\n delete this.services[key];\n }\n }\n\n public initializeService(Service: KyselyServiceConstructor<Database>, relativePath: string): void {\n const instance = new Service(this.plugin, this.core);\n this.logger.utils.registration(instance.constructor.name, relativePath);\n }\n\n public 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 { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Logger, ShutdownPhase } from '@seedcord/services';\nimport { keepDefined } from '@seedcord/utils';\nimport chalk from 'chalk';\nimport { Envapter } from 'envapt';\nimport { Kysely, PostgresDialect } from 'kysely';\nimport { Pool, type PoolConfig, type PoolClient } from 'pg';\nimport { HmrModuleHandler, Plugin } from 'seedcord';\n\nimport { PgServiceMetadataKey } from './decorators/RegisterKpgService';\nimport { KpgDatabaseBootstrapper } from './KpgDatabaseBootstrapper';\nimport { KpgMigrationManager } from './KpgMigrationManager';\nimport { KpgServiceRegistry } from './KpgServiceRegistry';\n\nimport type { KyselyServiceConstructor } from './KpgService';\nimport type { MigrationOptions, StepMigrationOptions } from './types/KpgMigration';\nimport type { KpgOptions } from './types/KpgOptions';\nimport type { KpgServices } from './types/KpgServices';\nimport type { HmrUpdateEvent } from '@seedcord/types/internal';\nimport type { MigrationInfo } from 'kysely/migration';\nimport type { Core } from 'seedcord';\n\nexport interface KyselyArtifact {\n key?: string;\n}\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 private servicesReady = false;\n\n /** Exposed Kysely instance once `init` completes. */\n declare public connection: Kysely<Database>;\n private pool: Pool | null = null;\n private onConnectHandler: ((client: PoolClient) => void) | 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 private readonly hmrHandler?: HmrModuleHandler<KyselyServiceConstructor<Database>, void, KyselyArtifact>;\n\n /**\n * Map of all services registered with the plugin, keyed by their decorator name.\n */\n public get services(): KpgServices {\n if (!this.servicesReady) {\n throw new SeedcordError(SeedcordErrorCode.PluginKpgServicesNotReady);\n }\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 if (!Envapter.isDevelopment) return; // HMR only in development\n\n const relPaths = this.options.migrations.path;\n super.registerCriticalFiles(Array.isArray(relPaths) ? relPaths : [relPaths]);\n\n this.hmrHandler = new HmrModuleHandler({\n handlersDir: this.options.dir,\n isHandler: this.serviceRegistry.isServiceClass.bind(this.serviceRegistry),\n registerHandler: this.serviceRegistry.initializeService.bind(this.serviceRegistry),\n unregisterHandler: this.serviceRegistry.unregister.bind(this.serviceRegistry),\n getArtifacts: this.getArtifacts.bind(this),\n logger: this.logger,\n name: 'KyselyPg'\n });\n }\n\n private getArtifacts(ctor: KyselyServiceConstructor<Database>): KyselyArtifact {\n const key = Reflect.getMetadata(PgServiceMetadataKey, ctor) as string | undefined;\n return key ? { key } : {};\n }\n\n /** @internal For use in dev mode */\n public override async onHmr(event: HmrUpdateEvent): Promise<void> {\n await this.hmrHandler?.handle(event);\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 this.servicesReady = true;\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 if (this.onConnectHandler) {\n pool.removeListener('connect', this.onConnectHandler);\n this.onConnectHandler = null;\n }\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 throw new SeedcordError(SeedcordErrorCode.PluginKpgDisconnectFailed, { cause: err });\n });\n this.logger.info(chalk.red.bold('Disconnected from Postgres'));\n }\n\n /**\n * Runs migrations using the supplied options.\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 registered with the manager 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: string, instance: unknown): void {\n this.serviceRegistry.register(key, instance);\n }\n\n /**\n * Tracks a service file with the HMR handler so dev reloads can swap it. No-op outside dev.\n *\n * @internal Lets {@link KpgServiceRegistry} reach the dev-only HMR handler without poking a\n * private field.\n */\n public trackServiceFile(filePath: string, ctor: KyselyServiceConstructor<Database>): void {\n this.hmrHandler?.trackHandler(filePath, ctor);\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 const handler = (client: PoolClient): void => {\n void (async () => {\n for (const sql of queuedStatements) {\n await client.query(sql);\n }\n })().catch((err) => this.logger.error('Failed to run onConnect SQL', err));\n };\n\n this.onConnectHandler = handler;\n pool.on('connect', handler);\n }\n\n private async testPoolConnection(pool: Pool): Promise<void> {\n const client = await pool.connect();\n client.release();\n }\n}\n","export * from './mongo';\nexport * from './kysely-pg';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@seedcord/plugins",
3
3
  "type": "module",
4
- "version": "0.7.0-next.0",
4
+ "version": "0.7.1-next.0",
5
5
  "description": "Official plugins for Seedcord Discord bot framework",
6
6
  "repository": {
7
7
  "type": "git",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "peerDependencies": {
31
31
  "kysely": "^0.29.2",
32
- "mongoose": "^9.7.0",
32
+ "mongoose": "^9.7.1",
33
33
  "pg": "^8.21.0",
34
34
  "reflect-metadata": "^0.2.2",
35
35
  "typescript": "^6.0.3"
@@ -47,21 +47,21 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "chalk": "^5.6.2",
50
- "envapt": "^6.0.0",
51
- "@seedcord/errors": "0.1.0-next.0",
52
- "@seedcord/services": "0.8.0-next.0",
53
- "@seedcord/types": "0.6.0-next.0",
54
- "@seedcord/utils": "0.6.0-next.0",
55
- "seedcord": "0.13.0-next.0"
50
+ "envapt": "^6.0.2",
51
+ "@seedcord/errors": "0.2.0-next.0",
52
+ "@seedcord/services": "0.8.1-next.0",
53
+ "@seedcord/types": "0.7.0-next.0",
54
+ "@seedcord/utils": "0.6.1-next.0",
55
+ "seedcord": "0.14.0-next.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/pg": "^8.20.0",
59
59
  "kysely": "^0.29.2",
60
- "mongoose": "^9.7.0",
60
+ "mongoose": "^9.7.1",
61
61
  "pg": "^8.21.0",
62
62
  "reflect-metadata": "^0.2.2",
63
63
  "type-fest": "^5.7.0",
64
- "@seedcord/eslint-config": "1.4.1-next.0",
64
+ "@seedcord/eslint-config": "1.4.2-next.0",
65
65
  "@seedcord/tsconfig": "2.0.0",
66
66
  "@seedcord/tsdown-config": "2.0.0"
67
67
  },