chore: Hide repository creation if they are not custom + add upsert support by default (#6127)

This commit is contained in:
Adrien de Peretti
2024-01-19 15:09:38 +01:00
committed by GitHub
parent 8a8a7183b8
commit 5e655dd59b
124 changed files with 1516 additions and 2559 deletions
@@ -2,6 +2,7 @@ import {
Context,
DAL,
FilterQuery as InternalFilterQuery,
RepositoryService,
RepositoryTransformOptions,
} from "@medusajs/types"
import {
@@ -16,9 +17,9 @@ import {
EntityName,
FilterQuery as MikroFilterQuery,
} from "@mikro-orm/core/typings"
import { MedusaError, isString } from "../../common"
import { isString, MedusaError } from "../../common"
import { MedusaContext } from "../../decorators"
import { InjectTransactionManager, buildQuery } from "../../modules-sdk"
import { buildQuery, InjectTransactionManager } from "../../modules-sdk"
import {
getSoftDeletedCascadedEntitiesIdsMappedBy,
transactionWrapper,
@@ -104,6 +105,10 @@ export class MikroOrmBaseRepository<
throw new Error("Method not implemented.")
}
upsert(data: unknown[], context: Context = {}): Promise<T[]> {
throw new Error("Method not implemented.")
}
@InjectTransactionManager()
async softDelete(
idsOrFilter: string[] | InternalFilterQuery,
@@ -228,7 +233,10 @@ export function mikroOrmBaseRepositoryFactory<
[K in DtoBasedMutationMethods]?: any
}
>(entity: EntityClass<T> | EntitySchema<T>) {
class MikroOrmAbstractBaseRepository_ extends MikroOrmBaseRepository<T> {
class MikroOrmAbstractBaseRepository_
extends MikroOrmBaseRepository<T>
implements RepositoryService<T, TDTOs>
{
// @ts-ignore
constructor(...args: any[]) {
// @ts-ignore
@@ -411,6 +419,83 @@ export function mikroOrmBaseRepositoryFactory<
findOptions_.options as MikroOptions<T>
)
}
async upsert(
data: (TDTOs["create"] | TDTOs["update"])[],
context: Context = {}
): Promise<T[]> {
// TODO: Move this logic to the service packages/utils/src/modules-sdk/abstract-service-factory.ts
const manager = this.getActiveManager<EntityManager>(context)
const primaryKeys =
MikroOrmAbstractBaseRepository_.retrievePrimaryKeys(entity)
let primaryKeysCriteria: { [key: string]: any }[] = []
if (primaryKeys.length === 1) {
primaryKeysCriteria.push({
[primaryKeys[0]]: data.map((d) => d[primaryKeys[0]]),
})
} else {
primaryKeysCriteria = data.map((d) => ({
$and: primaryKeys.map((key) => ({ [key]: d[key] })),
}))
}
const allEntities = await Promise.all(
primaryKeysCriteria.map(
async (criteria) =>
await this.find({ where: criteria } as DAL.FindOptions<T>, context)
)
)
const existingEntities = allEntities.flat()
const existingEntitiesMap = new Map<string, T>()
existingEntities.forEach((entity) => {
if (entity) {
const key =
MikroOrmAbstractBaseRepository_.buildUniqueCompositeKeyValue(
primaryKeys,
entity
)
existingEntitiesMap.set(key, entity)
}
})
const upsertedEntities: T[] = []
const createdEntities: T[] = []
const updatedEntities: T[] = []
data.forEach((data_) => {
// In case the data provided are just strings, then we build an object with the primary key as the key and the data as the valuecd -
const key =
MikroOrmAbstractBaseRepository_.buildUniqueCompositeKeyValue(
primaryKeys,
data_
)
const existingEntity = existingEntitiesMap.get(key)
if (existingEntity) {
const updatedType = manager.assign(existingEntity, data_)
updatedEntities.push(updatedType)
} else {
const newEntity = manager.create(entity, data_)
createdEntities.push(newEntity)
}
})
if (createdEntities.length) {
manager.persist(createdEntities)
upsertedEntities.push(...createdEntities)
}
if (updatedEntities.length) {
manager.persist(updatedEntities)
upsertedEntities.push(...updatedEntities)
}
return upsertedEntities
}
}
return MikroOrmAbstractBaseRepository_
+3
View File
@@ -1,5 +1,6 @@
import { Context, DAL, RepositoryTransformOptions } from "@medusajs/types"
import { MedusaContext } from "../decorators"
import { transactionWrapper } from "./utils"
class AbstractBase<T = any> {
protected readonly manager_: any
@@ -49,6 +50,8 @@ export abstract class AbstractBaseRepository<T = any>
abstract delete(ids: string[], context?: Context): Promise<void>
abstract upsert(data: unknown[], context?: Context): Promise<T[]>
abstract softDelete(
ids: string[],
context?: Context