chore(): Improve cascade soft deletetion/restoration and update (#11618)

**What**
- Fix soft deletion and restoration emitted events
- Improve soft deleted/restore algorithm
- Fix big number field handling null value during partial hydration from mikro orm
This commit is contained in:
Adrien de Peretti
2025-02-26 19:01:36 +01:00
committed by GitHub
parent caf83cf78c
commit d254b2ddba
9 changed files with 337 additions and 202 deletions

View File

@@ -259,7 +259,7 @@ export function MedusaInternalService<
const primaryKeys = AbstractService_.retrievePrimaryKeys(model)
const inputArray = Array.isArray(input) ? input : [input]
const toUpdateData: { entity; update }[] = []
const toUpdateData: { entity: TEntity; update: Partial<TEntity> }[] = []
// Only used when we receive data and no selector
const keySelectorForDataOnly: any = {
@@ -353,10 +353,17 @@ export function MedusaInternalService<
// Manage metadata if needed
toUpdateData.forEach(({ entity, update }) => {
if (isPresent(update.metadata)) {
entity.metadata = update.metadata = mergeMetadata(
entity.metadata ?? {},
update.metadata
const update_ = update as (typeof toUpdateData)[number]["update"] & {
metadata: Record<string, unknown>
}
const entity_ = entity as InferEntityType<TEntity> & {
metadata?: Record<string, unknown>
}
if (isPresent(update_.metadata)) {
entity_.metadata = update_.metadata = mergeMetadata(
entity_.metadata ?? {},
update_.metadata
)
}
})

View File

@@ -137,6 +137,37 @@ export function MedusaService<
? ModelConfigurationsToConfigTemplate<TModels>
: ModelsConfig
> {
function emitSoftDeleteRestoreEvents(
this: AbstractModuleService_,
klassPrototype: any,
cascadedModelsMap: Record<string, string[]>,
action: string,
sharedContext: Context
) {
const joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
const emittedEntities = new Set<string>()
Object.entries(cascadedModelsMap).forEach(([linkableKey, ids]) => {
const entity = joinerConfig.linkableKeys?.[linkableKey]!
if (entity && !emittedEntities.has(entity)) {
emittedEntities.add(entity)
const linkableKeyEntity = camelToSnakeCase(entity).toLowerCase()
klassPrototype.aggregatedEvents.bind(this)({
action: action,
object: linkableKeyEntity,
data: { id: ids },
context: sharedContext,
})
}
})
}
const buildAndAssignMethodImpl = function (
klassPrototype: any,
method: string,
@@ -321,27 +352,11 @@ export function MedusaService<
)
if (mappedCascadedModelsMap) {
const joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
Object.entries(mappedCascadedModelsMap).forEach(
([linkableKey, ids]) => {
const entity = joinerConfig.linkableKeys?.[linkableKey]!
if (entity) {
const linkableKeyEntity =
camelToSnakeCase(entity).toLowerCase()
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.DELETED,
object: linkableKeyEntity,
data: { id: ids },
context: sharedContext,
})
}
}
emitSoftDeleteRestoreEvents.bind(this)(
klassPrototype,
mappedCascadedModelsMap,
CommonEvents.DELETED,
sharedContext
)
}
@@ -378,26 +393,11 @@ export function MedusaService<
)
if (mappedCascadedModelsMap) {
const joinerConfig = (
typeof this.__joinerConfig === "function"
? this.__joinerConfig()
: this.__joinerConfig
) as ModuleJoinerConfig
Object.entries(mappedCascadedModelsMap).forEach(
([linkableKey, ids]) => {
const entity = joinerConfig.linkableKeys?.[linkableKey]!
if (entity) {
const linkableKeyEntity =
camelToSnakeCase(entity).toLowerCase()
klassPrototype.aggregatedEvents.bind(this)({
action: CommonEvents.CREATED,
object: linkableKeyEntity,
data: { id: ids },
context: sharedContext,
})
}
}
emitSoftDeleteRestoreEvents.bind(this)(
klassPrototype,
mappedCascadedModelsMap,
CommonEvents.CREATED,
sharedContext
)
}