feat(product): Move mikro orm utils to the utils package (#4631)

Move utils to the utils package as much as possible

Co-authored-by: Shahed Nasser <27354907+shahednasser@users.noreply.github.com>
This commit is contained in:
Adrien de Peretti
2023-07-31 13:30:43 +02:00
committed by GitHub
parent 648eb106d6
commit 4073b73130
39 changed files with 523 additions and 375 deletions
@@ -0,0 +1,28 @@
import { ModuleServiceInitializeOptions } from "@medusajs/types"
export async function mikroOrmCreateConnection(
database: ModuleServiceInitializeOptions["database"],
entities: any[]
) {
const { MikroORM } = await import("@mikro-orm/postgresql")
const schema = database.schema || "public"
const orm = await MikroORM.init({
discovery: { disableDynamicFileAccess: true },
entities,
debug: database.debug ?? process.env.NODE_ENV?.startsWith("dev") ?? false,
baseDir: process.cwd(),
clientUrl: database.clientUrl,
schema,
driverOptions: database.driverOptions ?? {
connection: { ssl: true },
},
tsNode: process.env.APP_ENV === "development",
type: "postgresql",
migrations: {
path: __dirname + "/../migrations",
},
})
return orm
}
@@ -0,0 +1,197 @@
import { Context, DAL, RepositoryTransformOptions } from "@medusajs/types"
import { MedusaContext } from "../../decorators"
import { buildQuery, InjectTransactionManager } from "../../modules-sdk"
import {
mikroOrmSerializer,
mikroOrmUpdateDeletedAtRecursively,
transactionWrapper,
} from "../utils"
class MikroOrmBase<T = any> {
protected readonly manager_: any
protected constructor({ manager }) {
this.manager_ = manager
}
getFreshManager<TManager = unknown>(): TManager {
return (this.manager_.fork
? this.manager_.fork()
: this.manager_) as unknown as TManager
}
getActiveManager<TManager = unknown>(
@MedusaContext()
{ transactionManager, manager }: Context = {}
): TManager {
return (transactionManager ?? manager ?? this.manager_) as TManager
}
async transaction<TManager = unknown>(
task: (transactionManager: TManager) => Promise<any>,
options: {
isolationLevel?: string
enableNestedTransactions?: boolean
transaction?: TManager
} = {}
): Promise<any> {
// @ts-ignore
return await transactionWrapper.bind(this)(task, options)
}
async serialize<TOutput extends object | object[]>(
data: any,
options?: any
): Promise<TOutput> {
return await mikroOrmSerializer<TOutput>(data, options)
}
}
export abstract class MikroOrmAbstractBaseRepository<T = any>
extends MikroOrmBase
implements DAL.RepositoryService<T>
{
abstract find(options?: DAL.FindOptions<T>, context?: Context)
abstract findAndCount(
options?: DAL.FindOptions<T>,
context?: Context
): Promise<[T[], number]>
abstract create(data: unknown[], context?: Context): Promise<T[]>
update(data: unknown[], context?: Context): Promise<T[]> {
throw new Error("Method not implemented.")
}
abstract delete(ids: string[], context?: Context): Promise<void>
@InjectTransactionManager()
async softDelete(
ids: string[],
@MedusaContext()
{ transactionManager: manager }: Context = {}
): Promise<T[]> {
const entities = await this.find({ where: { id: { $in: ids } } as any })
const date = new Date()
await mikroOrmUpdateDeletedAtRecursively(manager, entities, date)
return entities
}
@InjectTransactionManager()
async restore(
ids: string[],
@MedusaContext()
{ transactionManager: manager }: Context = {}
): Promise<T[]> {
const query = buildQuery(
{ id: { $in: ids } },
{
withDeleted: true,
}
)
const entities = await this.find(query)
await mikroOrmUpdateDeletedAtRecursively(manager, entities, null)
return entities
}
}
export abstract class MikroOrmAbstractTreeRepositoryBase<T = any>
extends MikroOrmBase<T>
implements DAL.TreeRepositoryService<T>
{
protected constructor({ manager }) {
// @ts-ignore
super(...arguments)
}
abstract find(
options?: DAL.FindOptions<T>,
transformOptions?: RepositoryTransformOptions,
context?: Context
)
abstract findAndCount(
options?: DAL.FindOptions<T>,
transformOptions?: RepositoryTransformOptions,
context?: Context
): Promise<[T[], number]>
abstract create(data: unknown, context?: Context): Promise<T>
abstract delete(id: string, context?: Context): Promise<void>
}
/**
* Priviliged extends of the abstract classes unless most of the methods can't be implemented
* in your repository. This base repository is also used to provide a base repository
* injection if needed to be able to use the common methods without being related to an entity.
* In this case, none of the method will be implemented except the manager and transaction
* related ones.
*/
export class MikroOrmBaseRepository extends MikroOrmAbstractBaseRepository {
constructor({ manager }) {
// @ts-ignore
super(...arguments)
}
create(data: unknown[], context?: Context): Promise<any[]> {
throw new Error("Method not implemented.")
}
update(data: unknown[], context?: Context): Promise<any[]> {
throw new Error("Method not implemented.")
}
delete(ids: string[], context?: Context): Promise<void> {
throw new Error("Method not implemented.")
}
find(options?: DAL.FindOptions, context?: Context): Promise<any[]> {
throw new Error("Method not implemented.")
}
findAndCount(
options?: DAL.FindOptions,
context?: Context
): Promise<[any[], number]> {
throw new Error("Method not implemented.")
}
}
export class MikroOrmBaseTreeRepository extends MikroOrmAbstractTreeRepositoryBase {
constructor({ manager }) {
// @ts-ignore
super(...arguments)
}
find(
options?: DAL.FindOptions,
transformOptions?: RepositoryTransformOptions,
context?: Context
): Promise<any[]> {
throw new Error("Method not implemented.")
}
findAndCount(
options?: DAL.FindOptions,
transformOptions?: RepositoryTransformOptions,
context?: Context
): Promise<[any[], number]> {
throw new Error("Method not implemented.")
}
create(data: unknown, context?: Context): Promise<any> {
throw new Error("Method not implemented.")
}
delete(id: string, context?: Context): Promise<void> {
throw new Error("Method not implemented.")
}
}
@@ -0,0 +1,19 @@
export const SoftDeletableFilterKey = "softDeletable"
interface FilterArguments {
withDeleted?: boolean
}
export const mikroOrmSoftDeletableFilterOptions = {
name: SoftDeletableFilterKey,
cond: ({ withDeleted }: FilterArguments = {}) => {
if (withDeleted) {
return {}
}
return {
deleted_at: null,
}
},
default: true,
args: false,
}