feat(types, product, utils, medusa): Include shared connection for modules (#4626)

This commit is contained in:
Adrien de Peretti
2023-08-08 17:10:34 +02:00
committed by GitHub
parent a2d7540e40
commit 3f3a84262c
26 changed files with 476 additions and 168 deletions

View File

@@ -2,3 +2,4 @@ export * from "./load-module-database-config"
export * from "./decorators"
export * from "./build-query"
export * from "./retrieve-entity"
export * from "./loaders/mikro-orm-connection-loader"

View File

@@ -47,9 +47,8 @@ function getDefaultDriverOptions(clientUrl: string) {
*/
export function loadDatabaseConfig(
moduleName: string,
options?:
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
options?: ModulesSdkTypes.ModuleServiceInitializeOptions,
silent: boolean = false
): ModulesSdkTypes.ModuleServiceInitializeOptions["database"] {
const clientUrl = getEnv("POSTGRES_URL", moduleName)
@@ -64,19 +63,20 @@ export function loadDatabaseConfig(
}
if (isModuleServiceInitializeOptions(options)) {
database.clientUrl = options.database.clientUrl ?? database.clientUrl
database.schema = options.database.schema ?? database.schema
database.clientUrl = options.database!.clientUrl ?? database.clientUrl
database.schema = options.database!.schema ?? database.schema
database.driverOptions =
options.database.driverOptions ??
options.database!.driverOptions ??
getDefaultDriverOptions(database.clientUrl)
database.debug = options.database.debug ?? database.debug
database.debug = options.database!.debug ?? database.debug
}
if (!database.clientUrl) {
if (!database.clientUrl && !silent) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
"No database clientUrl provided. Please provide the clientUrl through the PRODUCT_POSTGRES_URL or POSTGRES_URL environment variable or the options object in the initialize function."
)
}
return database
}

View File

@@ -0,0 +1,112 @@
import {
Logger,
MedusaContainer,
MODULE_RESOURCE_TYPE,
MODULE_SCOPE,
ModulesSdkTypes,
} from "@medusajs/types"
import { asValue } from "awilix"
import { PostgreSqlDriver, SqlEntityManager } from "@mikro-orm/postgresql"
import { ContainerRegistrationKeys, MedusaError } from "../../common"
import { loadDatabaseConfig } from "../load-module-database-config"
import { mikroOrmCreateConnection } from "../../dal"
export async function mikroOrmConnectionLoader({
container,
options,
moduleDeclaration,
entities,
}: {
entities: any[]
container: MedusaContainer
options?:
| ModulesSdkTypes.ModuleServiceInitializeOptions
| ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
moduleDeclaration?: ModulesSdkTypes.InternalModuleDeclaration
logger?: Logger
}) {
let manager = (
options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions
)?.manager
// Custom manager provided
if (manager) {
container.register({
manager: asValue(manager),
})
return
}
if (
moduleDeclaration?.scope === MODULE_SCOPE.INTERNAL &&
moduleDeclaration.resources === MODULE_RESOURCE_TYPE.SHARED
) {
return await loadShared({ container, entities })
}
/**
* Reuse an existing connection if it is passed in the options
*/
let dbConfig
const shouldSwallowError = !!(
options as ModulesSdkTypes.ModuleServiceInitializeOptions
)?.database.connection
dbConfig = {
...loadDatabaseConfig(
"product",
(options ?? {}) as ModulesSdkTypes.ModuleServiceInitializeOptions,
shouldSwallowError
),
connection: (options as ModulesSdkTypes.ModuleServiceInitializeOptions)
?.database.connection,
}
manager ??= await loadDefault({
database: dbConfig,
entities,
})
container.register({
manager: asValue(manager),
})
}
async function loadDefault({
database,
entities,
}): Promise<SqlEntityManager<PostgreSqlDriver>> {
if (!database) {
throw new MedusaError(
MedusaError.Types.INVALID_ARGUMENT,
`Database config is not present at module config "options.database"`
)
}
const orm = await mikroOrmCreateConnection(database, entities)
return orm.em.fork()
}
async function loadShared({ container, entities }) {
const sharedConnection = container.resolve(
ContainerRegistrationKeys.PG_CONNECTION,
{
allowUnregistered: true,
}
)
if (!sharedConnection) {
throw new Error(
"The module is setup to use a shared resources but no shared connection is present. A new connection will be created"
)
}
const manager = await loadDefault({
entities,
database: {
connection: sharedConnection,
},
})
container.register({
manager: asValue(manager),
})
}