Skip to content

Commit

Permalink
feat: Migrate customer module to DML (#10499)
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage authored Dec 11, 2024
1 parent d8a92db commit 16d27ea
Show file tree
Hide file tree
Showing 13 changed files with 430 additions and 482 deletions.
7 changes: 7 additions & 0 deletions .changeset/healthy-ears-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@medusajs/customer": patch
"@medusajs/types": patch
"@medusajs/utils": patch
---

Feat/customer dml
5 changes: 3 additions & 2 deletions packages/core/types/src/dml/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,13 @@ export type Infer<T> = T extends IDmlEntity<infer Schema, any>
* The actions to cascade from a given entity to its
* relationship.
*/
export type EntityCascades<Relationships> = {
export type EntityCascades<DeletableRelationships, DetachableRelationships> = {
/**
* The related models to delete when a record of this data model
* is deleted.
*/
delete?: Relationships
delete?: DeletableRelationships
detach?: DetachableRelationships
}

/**
Expand Down
80 changes: 80 additions & 0 deletions packages/core/utils/src/dml/__tests__/entity-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6231,6 +6231,86 @@ describe("Entity builder", () => {
})
})

test("should define onDelete cascade on pivot entity when applying detach cascade", () => {
const teamUser = model.define("teamUser", {
id: model.number(),
user: model.belongsTo(() => user, { mappedBy: "teams" }),
team: model.belongsTo(() => team, { mappedBy: "users" }),
})
const user = model
.define("user", {
id: model.number(),
username: model.text(),
teams: model.manyToMany(() => team, {
pivotEntity: () => teamUser,
}),
})
.cascades({
detach: ["teams"],
})

const team = model
.define("team", {
id: model.number(),
name: model.text(),
users: model.manyToMany(() => user, {
pivotEntity: () => teamUser,
}),
})
.cascades({
detach: ["users"],
})

type CascadeDetach = Parameters<(typeof team)["cascades"]>[0]["detach"]

expectTypeOf<CascadeDetach>().toEqualTypeOf<"users"[] | undefined>()

const [, , TeamUserEntity] = toMikroOrmEntities([user, team, teamUser])

const teamUserMetadata =
MetadataStorage.getMetadataFromDecorator(TeamUserEntity)
expect(teamUserMetadata.properties).toEqual(
expect.objectContaining({
user_id: {
reference: "scalar",
type: "User",
columnType: "text",
fieldName: "user_id",
nullable: false,
name: "user_id",
getter: false,
setter: false,
},
user: {
name: "user",
reference: "m:1",
entity: "User",
nullable: false,
persist: false,
onDelete: "cascade",
},
team_id: {
reference: "scalar",
type: "Team",
columnType: "text",
fieldName: "team_id",
nullable: false,
name: "team_id",
getter: false,
setter: false,
},
team: {
name: "team",
reference: "m:1",
entity: "Team",
nullable: false,
persist: false,
onDelete: "cascade",
},
})
)
})

test("throw error when unable to locate relationship via mappedBy", () => {
const team = model.define("team", {
id: model.number(),
Expand Down
7 changes: 4 additions & 3 deletions packages/core/utils/src/dml/entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class DmlEntity<
schema: Schema

readonly #tableName: string
#cascades: EntityCascades<string[]> = {}
#cascades: EntityCascades<string[], string[]> = {}
#indexes: EntityIndex<Schema>[] = []
#checks: CheckConstraint<Schema>[] = []

Expand Down Expand Up @@ -100,7 +100,7 @@ export class DmlEntity<
name: InferDmlEntityNameFromConfig<TConfig>
tableName: string
schema: DMLSchema
cascades: EntityCascades<string[]>
cascades: EntityCascades<string[], string[]>
indexes: EntityIndex<Schema>[]
checks: CheckConstraint<Schema>[]
} {
Expand Down Expand Up @@ -139,7 +139,8 @@ export class DmlEntity<
*/
cascades(
options: EntityCascades<
ExtractEntityRelations<Schema, "hasOne" | "hasOneWithFK" | "hasMany">
ExtractEntityRelations<Schema, "hasOne" | "hasOneWithFK" | "hasMany">,
ExtractEntityRelations<Schema, "manyToMany">
>
) {
const childToParentCascades = options.delete?.filter((relationship) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export function defineHasOneRelationship(
any
>,
{ relatedModelName }: { relatedModelName: string },
cascades: EntityCascades<string[]>
cascades: EntityCascades<string[], string[]>
) {
const shouldRemoveRelated = !!cascades.delete?.includes(relationship.name)
const { schema: relationSchema } = relatedEntity.parse()
Expand Down Expand Up @@ -179,7 +179,7 @@ export function defineHasOneWithFKRelationship(
MikroORMEntity: EntityConstructor<any>,
relationship: RelationshipMetadata,
{ relatedModelName }: { relatedModelName: string },
cascades: EntityCascades<string[]>
cascades: EntityCascades<string[], string[]>
) {
const foreignKeyName = camelToSnakeCase(`${relationship.name}Id`)
const shouldRemoveRelated = !!cascades.delete?.includes(relationship.name)
Expand Down Expand Up @@ -213,7 +213,7 @@ export function defineHasManyRelationship(
MikroORMEntity: EntityConstructor<any>,
relationship: RelationshipMetadata,
{ relatedModelName }: { relatedModelName: string },
cascades: EntityCascades<string[]>
cascades: EntityCascades<string[], string[]>
) {
const shouldRemoveRelated = !!cascades.delete?.includes(relationship.name)

Expand Down Expand Up @@ -259,7 +259,7 @@ export function defineBelongsToRelationship(
* define a onDelete: cascade when we are included in the delete
* list of parent cascade.
*/
const shouldCascade = relationCascades.delete?.includes(mappedBy)
const shouldCascade = !!relationCascades.delete?.includes(mappedBy)

/**
* Ensure the mapped by is defined as relationship on the other side
Expand Down Expand Up @@ -337,6 +337,9 @@ export function defineBelongsToRelationship(
DmlManyToMany.isManyToMany(otherSideRelation)
) {
const foreignKeyName = camelToSnakeCase(`${relationship.name}Id`)
const detachCascade =
!!relationship.mappedBy &&
relationCascades.detach?.includes(relationship.mappedBy)

if (DmlManyToMany.isManyToMany(otherSideRelation)) {
Property({
Expand All @@ -350,6 +353,7 @@ export function defineBelongsToRelationship(
entity: relatedModelName,
nullable: relationship.nullable,
persist: false,
onDelete: shouldCascade || detachCascade ? "cascade" : undefined,
})(MikroORMEntity.prototype, relationship.name)
} else {
ManyToOne({
Expand Down Expand Up @@ -660,7 +664,7 @@ export function defineRelationship(
MikroORMEntity: EntityConstructor<any>,
entity: DmlEntity<any, any>,
relationship: RelationshipMetadata,
cascades: EntityCascades<string[]>,
cascades: EntityCascades<string[], string[]>,
context: Context
) {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ moduleIntegrationTestRunner<ICustomerModuleService>({

expect(Object.keys(linkable)).toEqual([
"customerAddress",
"customerGroupCustomer",
"customerGroup",
"customer",
"customerGroup",
"customerGroupCustomer",
])

Object.keys(linkable).forEach((key) => {
Expand Down
Loading

0 comments on commit 16d27ea

Please sign in to comment.