fix(utils): Cascade soft deletion management (#9534)
* fix(utils): Cascade sOCoft deletion management * fix(utils): Cascade sOCoft deletion management
This commit is contained in:
committed by
GitHub
parent
1b82f7a814
commit
5a60a2a329
@@ -1,6 +1,7 @@
|
||||
import { Collection, EntityMetadata, FindOptions, wrap } from "@mikro-orm/core"
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
import { buildQuery } from "../../modules-sdk/build-query"
|
||||
import { isString } from "../../common/is-string"
|
||||
|
||||
function detectCircularDependency(
|
||||
manager: SqlEntityManager,
|
||||
@@ -23,7 +24,13 @@ function detectCircularDependency(
|
||||
for (const relation of relationsToCascade) {
|
||||
const branchVisited = new Set(Array.from(visited))
|
||||
|
||||
const isSelfCircularDependency = entityMetadata.class === relation.entity()
|
||||
const relationEntity =
|
||||
typeof relation.entity === "function"
|
||||
? relation.entity()
|
||||
: relation.entity
|
||||
const isSelfCircularDependency = isString(relationEntity)
|
||||
? entityMetadata.className === relationEntity
|
||||
: entityMetadata.class === relationEntity
|
||||
|
||||
if (!isSelfCircularDependency && branchVisited.has(relation.name)) {
|
||||
const dependencies = Array.from(visited)
|
||||
|
||||
@@ -2,11 +2,17 @@ import { MetadataStorage, MikroORM } from "@mikro-orm/core"
|
||||
import { model } from "../../entity-builder"
|
||||
import { toMikroOrmEntities } from "../../helpers/create-mikro-orm-entity"
|
||||
import { createDatabase, dropDatabase } from "pg-god"
|
||||
import { CustomTsMigrationGenerator, mikroOrmSerializer } from "../../../dal"
|
||||
import {
|
||||
CustomTsMigrationGenerator,
|
||||
mikroOrmSerializer,
|
||||
mikroOrmUpdateDeletedAtRecursively,
|
||||
SoftDeletableFilterKey,
|
||||
} from "../../../dal"
|
||||
import { EntityConstructor } from "@medusajs/types"
|
||||
import { pgGodCredentials } from "../utils"
|
||||
import { FileSystem } from "../../../common"
|
||||
import { join } from "path"
|
||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||
|
||||
export const fileSystem = new FileSystem(
|
||||
join(__dirname, "../../integration-tests-migrations-many-to-one")
|
||||
@@ -31,11 +37,15 @@ describe("manyToOne - belongTo", () => {
|
||||
user: model.belongsTo(() => user, { mappedBy: "teams" }),
|
||||
})
|
||||
|
||||
const user = model.define("user", {
|
||||
id: model.id().primaryKey(),
|
||||
username: model.text(),
|
||||
teams: model.hasMany(() => team, { mappedBy: "user" }),
|
||||
})
|
||||
const user = model
|
||||
.define("user", {
|
||||
id: model.id().primaryKey(),
|
||||
username: model.text(),
|
||||
teams: model.hasMany(() => team, { mappedBy: "user" }),
|
||||
})
|
||||
.cascades({
|
||||
delete: ["teams"],
|
||||
})
|
||||
|
||||
;[User, Team] = toMikroOrmEntities([user, team])
|
||||
|
||||
@@ -148,4 +158,115 @@ describe("manyToOne - belongTo", () => {
|
||||
],
|
||||
})
|
||||
})
|
||||
|
||||
it(`should handle soft delete cascade`, async () => {
|
||||
let manager = orm.em.fork()
|
||||
|
||||
const user1 = manager.create(User, {
|
||||
username: "User 1",
|
||||
})
|
||||
|
||||
await manager.persistAndFlush([user1])
|
||||
manager = orm.em.fork()
|
||||
|
||||
const team1 = manager.create(Team, {
|
||||
name: "Team 1",
|
||||
user_id: user1.id,
|
||||
})
|
||||
const team2 = manager.create(Team, {
|
||||
name: "Team 2",
|
||||
user_id: user1.id,
|
||||
})
|
||||
|
||||
await manager.persistAndFlush([team1, team2])
|
||||
manager = orm.em.fork()
|
||||
|
||||
let teams = await manager.find(
|
||||
Team,
|
||||
{},
|
||||
{
|
||||
populate: ["user"],
|
||||
}
|
||||
)
|
||||
|
||||
const serializedTeams = await mikroOrmSerializer<InstanceType<typeof Team>>(
|
||||
teams
|
||||
)
|
||||
expect(serializedTeams).toHaveLength(2)
|
||||
expect(serializedTeams).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
id: team1.id,
|
||||
name: "Team 1",
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
user_id: user1.id,
|
||||
user: {
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: team2.id,
|
||||
name: "Team 2",
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
user_id: user1.id,
|
||||
user: {
|
||||
id: user1.id,
|
||||
username: "User 1",
|
||||
created_at: expect.any(Date),
|
||||
updated_at: expect.any(Date),
|
||||
deleted_at: null,
|
||||
},
|
||||
},
|
||||
])
|
||||
)
|
||||
|
||||
manager = orm.em.fork()
|
||||
const userToDelete = await manager.findOne(User, {
|
||||
id: user1.id,
|
||||
})
|
||||
await mikroOrmUpdateDeletedAtRecursively(
|
||||
manager as SqlEntityManager,
|
||||
[userToDelete],
|
||||
new Date()
|
||||
)
|
||||
|
||||
teams = await manager.find(
|
||||
Team,
|
||||
{},
|
||||
{
|
||||
populate: ["user"],
|
||||
filters: {
|
||||
[SoftDeletableFilterKey]: {
|
||||
withDeleted: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
expect(teams).toHaveLength(2)
|
||||
expect(teams).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
deleted_at: expect.any(Date),
|
||||
user: expect.objectContaining({
|
||||
deleted_at: expect.any(Date),
|
||||
}),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
deleted_at: expect.any(Date),
|
||||
user: expect.objectContaining({
|
||||
deleted_at: expect.any(Date),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user