UNPKG

@medusajs/test-utils

Version:
214 lines • 8.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dbTestUtilFactory = void 0; exports.getDatabaseURL = getDatabaseURL; exports.getMikroOrmConfig = getMikroOrmConfig; exports.getMikroOrmWrapper = getMikroOrmWrapper; const postgresql_1 = require("@mikro-orm/postgresql"); const pg_god_1 = require("pg-god"); const logger_1 = require("@medusajs/framework/logger"); const medusa_test_runner_utils_1 = require("./medusa-test-runner-utils"); const DB_HOST = process.env.DB_HOST ?? "localhost"; const DB_USERNAME = process.env.DB_USERNAME ?? ""; const DB_PASSWORD = process.env.DB_PASSWORD ?? ""; const pgGodCredentials = { user: DB_USERNAME, password: DB_PASSWORD, host: DB_HOST, }; function getDatabaseURL(dbName) { const DB_HOST = process.env.DB_HOST ?? "localhost"; const DB_USERNAME = process.env.DB_USERNAME ?? "postgres"; 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}`; } function getMikroOrmConfig({ mikroOrmEntities, pathToMigrations, clientUrl, schema, }) { const DB_URL = clientUrl ?? getDatabaseURL(); return (0, postgresql_1.defineConfig)({ clientUrl: DB_URL, entities: Object.values(mikroOrmEntities), schema: schema ?? process.env.MEDUSA_DB_SCHEMA, debug: false, pool: { min: 2, }, migrations: { pathTs: pathToMigrations, silent: true, }, }); } function getMikroOrmWrapper({ mikroOrmEntities, pathToMigrations, clientUrl, schema, }) { 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, }); try { this.orm = await postgresql_1.MikroORM.init(OrmConfig); this.manager = this.orm.em; try { await this.orm.getSchemaGenerator().ensureDatabase(); } catch (err) { logger_1.logger.error("Error ensuring database:", err); throw 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(); } } catch (error) { if (this.orm) { try { await this.orm.close(); } catch (closeError) { logger_1.logger.error("Error closing ORM:", closeError); } } this.orm = null; this.manager = null; throw error; } }, async clearDatabase() { if (this.orm === null) { throw new Error("ORM not configured"); } try { await this.manager?.execute(`DROP SCHEMA IF EXISTS "${this.schema ?? "public"}" CASCADE;`); await this.manager?.execute(`CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";`); const closePromise = this.orm.close(); await (0, medusa_test_runner_utils_1.execOrTimeout)(closePromise); } catch (error) { logger_1.logger.error("Error clearing database:", error); try { await this.orm?.close(); } catch (closeError) { logger_1.logger.error("Error during forced ORM close:", closeError); } throw error; } finally { this.orm = null; this.manager = null; } }, }; } const dbTestUtilFactory = () => ({ pgConnection_: null, create: async function (dbName) { try { await (0, pg_god_1.createDatabase)({ databaseName: dbName, errorIfExist: false }, pgGodCredentials); } catch (error) { logger_1.logger.error("Error creating database:", error); throw error; } }, teardown: async function ({ schema } = {}) { if (!this.pgConnection_) { return; } try { const runRawQuery = this.pgConnection_.raw.bind(this.pgConnection_); schema ??= "public"; await runRawQuery(`SET session_replication_role = 'replica';`); const { rows: tableNames } = await runRawQuery(`SELECT table_name FROM information_schema.tables WHERE table_schema = '${schema}';`); const skipIndexPartitionPrefix = "cat_"; const mainPartitionTables = ["index_data", "index_relation"]; let hasIndexTables = false; for (const { table_name } of tableNames) { if (mainPartitionTables.includes(table_name)) { hasIndexTables = true; } if (table_name.startsWith(skipIndexPartitionPrefix) || mainPartitionTables.includes(table_name)) { continue; } await runRawQuery(`DELETE FROM ${schema}."${table_name}";`); } if (hasIndexTables) { await runRawQuery(`TRUNCATE TABLE ${schema}.index_data;`); await runRawQuery(`TRUNCATE TABLE ${schema}.index_relation;`); } await runRawQuery(`SET session_replication_role = 'origin';`); } catch (error) { logger_1.logger.error("Error during database teardown:", error); throw error; } }, shutdown: async function (dbName) { try { const cleanupPromises = []; if (this.pgConnection_?.context) { cleanupPromises.push((0, medusa_test_runner_utils_1.execOrTimeout)(this.pgConnection_.context.destroy())); } if (this.pgConnection_) { cleanupPromises.push((0, medusa_test_runner_utils_1.execOrTimeout)(this.pgConnection_.destroy())); } await Promise.all(cleanupPromises); return await (0, pg_god_1.dropDatabase)({ databaseName: dbName, errorIfNonExist: false }, pgGodCredentials); } catch (error) { logger_1.logger.error("Error during database shutdown:", error); try { await this.pgConnection_?.context?.destroy(); await this.pgConnection_?.destroy(); } catch (cleanupError) { logger_1.logger.error("Error during forced cleanup:", cleanupError); } throw error; } finally { this.pgConnection_ = null; } }, }); exports.dbTestUtilFactory = dbTestUtilFactory; //# sourceMappingURL=database.js.map