**What**
> [!NOTE]
> I can see this pr becoming huge, so I d like to get this partial one merged 👍
- Fixes shared connection usage (mikro orm compare the instance to its own package and therefore was resulting in not trully reusing the provided connection leading to exhausting the connection pool as multiple connections was created and end up not being all destroyed properly under the hood, discovered in my integration tests)
- Create shipping options method implementation
- DTO's definition and service interface update
- integration tests
- Re work of the indexes with new util update
- Test runner utils to remove a big chunk of the boilerplate of the packages integrations
FIXES CORE-1742
158 lines
3.5 KiB
TypeScript
158 lines
3.5 KiB
TypeScript
import { MikroORM, Options, SqlEntityManager } from "@mikro-orm/postgresql"
|
|
|
|
export function getDatabaseURL(dbName?: string): string {
|
|
const DB_HOST = process.env.DB_HOST ?? "localhost"
|
|
const DB_USERNAME = process.env.DB_USERNAME ?? ""
|
|
const DB_PASSWORD = process.env.DB_PASSWORD
|
|
const DB_NAME = dbName ?? process.env.DB_TEMP_NAME
|
|
|
|
return `postgres://${DB_USERNAME}${
|
|
DB_PASSWORD ? `:${DB_PASSWORD}` : ""
|
|
}@${DB_HOST}/${DB_NAME}`
|
|
}
|
|
|
|
export function getMikroOrmConfig({
|
|
mikroOrmEntities,
|
|
pathToMigrations,
|
|
clientUrl,
|
|
schema,
|
|
}: {
|
|
mikroOrmEntities: any[]
|
|
pathToMigrations?: string
|
|
clientUrl?: string
|
|
schema?: string
|
|
}): Options {
|
|
const DB_URL = clientUrl ?? getDatabaseURL()
|
|
|
|
return {
|
|
type: "postgresql",
|
|
clientUrl: DB_URL,
|
|
entities: Object.values(mikroOrmEntities),
|
|
schema: schema ?? process.env.MEDUSA_DB_SCHEMA,
|
|
debug: false,
|
|
migrations: {
|
|
pathTs: pathToMigrations,
|
|
silent: true,
|
|
},
|
|
}
|
|
}
|
|
|
|
export interface TestDatabase {
|
|
mikroOrmEntities: any[]
|
|
pathToMigrations?: string
|
|
schema?: string
|
|
clientUrl?: string
|
|
|
|
orm: MikroORM | null
|
|
manager: SqlEntityManager | null
|
|
|
|
setupDatabase(): Promise<void>
|
|
clearDatabase(): Promise<void>
|
|
getManager(): SqlEntityManager
|
|
forkManager(): SqlEntityManager
|
|
getOrm(): MikroORM
|
|
}
|
|
|
|
export function getMikroOrmWrapper({
|
|
mikroOrmEntities,
|
|
pathToMigrations,
|
|
clientUrl,
|
|
schema,
|
|
}: {
|
|
mikroOrmEntities: any[]
|
|
pathToMigrations?: string
|
|
clientUrl?: string
|
|
schema?: string
|
|
}): TestDatabase {
|
|
return {
|
|
mikroOrmEntities,
|
|
pathToMigrations,
|
|
clientUrl: clientUrl ?? getDatabaseURL(),
|
|
schema: schema ?? process.env.MEDUSA_DB_SCHEMA,
|
|
|
|
orm: null,
|
|
manager: null,
|
|
|
|
getManager() {
|
|
if (this.manager === null) {
|
|
throw new Error("manager entity not available")
|
|
}
|
|
|
|
return this.manager
|
|
},
|
|
|
|
forkManager() {
|
|
if (this.manager === null) {
|
|
throw new Error("manager entity not available")
|
|
}
|
|
|
|
return this.manager.fork()
|
|
},
|
|
|
|
getOrm() {
|
|
if (this.orm === null) {
|
|
throw new Error("orm entity not available")
|
|
}
|
|
|
|
return this.orm
|
|
},
|
|
|
|
async setupDatabase() {
|
|
const OrmConfig = getMikroOrmConfig({
|
|
mikroOrmEntities: this.mikroOrmEntities,
|
|
pathToMigrations: this.pathToMigrations,
|
|
clientUrl: this.clientUrl,
|
|
schema: this.schema,
|
|
})
|
|
|
|
// Initializing the ORM
|
|
this.orm = await MikroORM.init(OrmConfig)
|
|
|
|
this.manager = this.orm.em
|
|
|
|
try {
|
|
await this.orm.getSchemaGenerator().ensureDatabase()
|
|
} catch (err) {
|
|
console.log(err)
|
|
}
|
|
|
|
await this.manager?.execute(
|
|
`CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";`
|
|
)
|
|
|
|
const pendingMigrations = await this.orm
|
|
.getMigrator()
|
|
.getPendingMigrations()
|
|
|
|
if (pendingMigrations && pendingMigrations.length > 0) {
|
|
await this.orm
|
|
.getMigrator()
|
|
.up({ migrations: pendingMigrations.map((m) => m.name!) })
|
|
} else {
|
|
await this.orm.schema.refreshDatabase() // ensure db exists and is fresh
|
|
}
|
|
},
|
|
|
|
async clearDatabase() {
|
|
if (this.orm === null) {
|
|
throw new Error("ORM not configured")
|
|
}
|
|
|
|
await this.manager?.execute(
|
|
`DROP SCHEMA IF EXISTS "${this.schema ?? "public"}" CASCADE;`
|
|
)
|
|
|
|
await this.manager?.execute(
|
|
`CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";`
|
|
)
|
|
|
|
try {
|
|
await this.orm.close()
|
|
} catch {}
|
|
|
|
this.orm = null
|
|
this.manager = null
|
|
},
|
|
}
|
|
}
|