diff --git a/packages/core/utils/src/dml/__tests__/entity-builder.spec.ts b/packages/core/utils/src/dml/__tests__/entity-builder.spec.ts index c62142fa51..a0b858e1f9 100644 --- a/packages/core/utils/src/dml/__tests__/entity-builder.spec.ts +++ b/packages/core/utils/src/dml/__tests__/entity-builder.spec.ts @@ -24,11 +24,22 @@ describe("Entity builder", () => { id: number username: string email: string + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -57,6 +68,15 @@ describe("Entity builder", () => { getter: false, setter: false, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -74,11 +94,22 @@ describe("Entity builder", () => { id: number username: string email: string + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -108,6 +139,15 @@ describe("Entity builder", () => { getter: false, setter: false, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -125,11 +165,22 @@ describe("Entity builder", () => { id: number username: string | null email: string + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -158,6 +209,15 @@ describe("Entity builder", () => { getter: false, setter: false, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -177,12 +237,23 @@ describe("Entity builder", () => { username: string email: string role: "moderator" | "admin" | "guest" + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -218,7 +289,17 @@ describe("Entity builder", () => { nullable: false, name: "role", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) + expect(metaData.properties["role"].items()).toEqual([ "moderator", "admin", @@ -242,12 +323,23 @@ describe("Entity builder", () => { username: string email: string role: "moderator" | "admin" | "guest" + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -284,6 +376,15 @@ describe("Entity builder", () => { nullable: false, name: "role", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) expect(metaData.properties["role"].items()).toEqual([ "moderator", @@ -308,12 +409,23 @@ describe("Entity builder", () => { username: string email: string role: "moderator" | "admin" | "guest" | null + deleted_at: Date | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) expect(metaData.className).toEqual("User") expect(metaData.path).toEqual("User") + + expect(metaData.filters).toEqual({ + softDeletable: { + name: "softDeletable", + cond: expect.any(Function), + default: true, + args: false, + }, + }) + expect(metaData.properties).toEqual({ id: { reference: "scalar", @@ -349,6 +461,15 @@ describe("Entity builder", () => { nullable: true, name: "role", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) expect(metaData.properties["role"].items()).toEqual([ "moderator", @@ -377,7 +498,12 @@ describe("Entity builder", () => { expectTypeOf(new User()).toMatchTypeOf<{ id: number username: string - email: EntityConstructor<{ email: string; isVerified: boolean }> + deleted_at: Date | null + email: EntityConstructor<{ + email: string + isVerified: boolean + deleted_at: Date | null + }> }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) @@ -409,6 +535,15 @@ describe("Entity builder", () => { nullable: false, mappedBy: "user", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -431,7 +566,12 @@ describe("Entity builder", () => { expectTypeOf(new User()).toMatchTypeOf<{ id: number username: string - emails: EntityConstructor<{ email: string; isVerified: boolean }> | null + deleted_at: Date | null + emails: EntityConstructor<{ + email: string + isVerified: boolean + deleted_at: Date | null + }> | null }>() const metaData = MetadataStorage.getMetadataFromDecorator(User) @@ -463,6 +603,15 @@ describe("Entity builder", () => { nullable: true, mappedBy: "user", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -516,6 +665,15 @@ describe("Entity builder", () => { nullable: false, mappedBy: "owner", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -574,6 +732,15 @@ describe("Entity builder", () => { mappedBy: "user", cascade: ["perist", "soft-remove"], }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const Email = entityBuilder(email) @@ -599,6 +766,15 @@ describe("Entity builder", () => { getter: false, setter: false, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -665,6 +841,15 @@ describe("Entity builder", () => { mappedBy: "user", cascade: ["perist", "soft-remove"], }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const Email = entityBuilder(email) @@ -699,6 +884,15 @@ describe("Entity builder", () => { owner: true, reference: "1:1", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) }) @@ -754,6 +948,15 @@ describe("Entity builder", () => { orphanRemoval: true, mappedBy: "user", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -810,6 +1013,15 @@ describe("Entity builder", () => { mappedBy: "the_user", orphanRemoval: true, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -868,6 +1080,15 @@ describe("Entity builder", () => { mappedBy: "user", cascade: ["perist", "soft-remove"], }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -928,6 +1149,15 @@ describe("Entity builder", () => { mappedBy: "user", cascade: ["perist", "soft-remove"], }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email) @@ -968,6 +1198,15 @@ describe("Entity builder", () => { reference: "m:1", onDelete: "cascade", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) }) @@ -995,12 +1234,15 @@ describe("Entity builder", () => { expectTypeOf(new User()).toMatchTypeOf<{ id: number username: string + deleted_at: Date | null email: EntityConstructor<{ email: string isVerified: boolean + deleted_at: Date | null user: EntityConstructor<{ id: number username: string + deleted_at: Date | null }> }> }>() @@ -1008,12 +1250,15 @@ describe("Entity builder", () => { expectTypeOf(new Email()).toMatchTypeOf<{ email: string isVerified: boolean + deleted_at: Date | null user: EntityConstructor<{ id: number username: string + deleted_at: Date | null email: EntityConstructor<{ email: string isVerified: boolean + deleted_at: Date | null }> }> }>() @@ -1047,6 +1292,15 @@ describe("Entity builder", () => { nullable: false, mappedBy: "user", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email) @@ -1079,6 +1333,15 @@ describe("Entity builder", () => { owner: true, mappedBy: "email", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1156,6 +1419,15 @@ describe("Entity builder", () => { nullable: false, mappedBy: "user", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email) @@ -1188,6 +1460,15 @@ describe("Entity builder", () => { owner: true, mappedBy: "email", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1265,6 +1546,15 @@ describe("Entity builder", () => { mappedBy: "user", orphanRemoval: true, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email) @@ -1304,6 +1594,15 @@ describe("Entity builder", () => { nullable: false, reference: "m:1", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1381,6 +1680,15 @@ describe("Entity builder", () => { mappedBy: "user", orphanRemoval: true, }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const emailMetaData = MetadataStorage.getMetadataFromDecorator(Email) @@ -1420,6 +1728,15 @@ describe("Entity builder", () => { nullable: true, reference: "m:1", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1563,6 +1880,15 @@ describe("Entity builder", () => { entity: "Team", pivotTable: "team_users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team) @@ -1593,6 +1919,15 @@ describe("Entity builder", () => { entity: "User", pivotTable: "team_users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1669,6 +2004,15 @@ describe("Entity builder", () => { pivotTable: "team_users", mappedBy: "users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team) @@ -1699,6 +2043,15 @@ describe("Entity builder", () => { entity: "User", pivotTable: "team_users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1814,6 +2167,15 @@ describe("Entity builder", () => { pivotTable: "team_users", mappedBy: "users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team) @@ -1849,6 +2211,15 @@ describe("Entity builder", () => { */ inversedBy: "teams", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -1929,6 +2300,15 @@ describe("Entity builder", () => { */ inversedBy: "users", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team) @@ -1960,6 +2340,15 @@ describe("Entity builder", () => { pivotTable: "team_users", mappedBy: "teams", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) @@ -2065,6 +2454,15 @@ describe("Entity builder", () => { pivotTable: "team_users", inversedBy: "activeTeamsUsers", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) const teamMetaData = MetadataStorage.getMetadataFromDecorator(Team) @@ -2103,6 +2501,15 @@ describe("Entity builder", () => { pivotTable: "team_users", mappedBy: "activeTeams", }, + deleted_at: { + reference: "scalar", + type: "date", + columnType: "timestamptz", + name: "deleted_at", + nullable: true, + getter: false, + setter: false, + }, }) }) }) diff --git a/packages/core/utils/src/dml/entity-builder.ts b/packages/core/utils/src/dml/entity-builder.ts index dc154e5b92..09ef93679c 100644 --- a/packages/core/utils/src/dml/entity-builder.ts +++ b/packages/core/utils/src/dml/entity-builder.ts @@ -10,6 +10,7 @@ import { BelongsTo } from "./relations/belongs-to" import { DateTimeSchema } from "./schema/date-time" import { ManyToMany } from "./relations/many-to-many" import type { RelationshipOptions, RelationshipType, SchemaType } from "./types" +import { NullableModifier } from "./schema/nullable" /** * Entity builder exposes the API to create an entity and define its @@ -23,7 +24,14 @@ export class EntityBuilder { define< Schema extends Record | RelationshipType> >(name: string, schema: Schema) { - return new DmlEntity(name, schema) + return new DmlEntity< + Schema & { + deleted_at: NullableModifier + } + >(name, { + ...schema, + deleted_at: new DateTimeSchema().nullable(), + }) } /** diff --git a/packages/core/utils/src/dml/helpers/create-mikro-orm-entity.ts b/packages/core/utils/src/dml/helpers/create-mikro-orm-entity.ts index 50b7b3e235..323505a02f 100644 --- a/packages/core/utils/src/dml/helpers/create-mikro-orm-entity.ts +++ b/packages/core/utils/src/dml/helpers/create-mikro-orm-entity.ts @@ -6,6 +6,7 @@ import { OneToOne, ManyToMany, ManyToOne, + Filter, } from "@mikro-orm/core" import { DmlEntity } from "../entity" import { camelToSnakeCase, pluralize } from "../../common" @@ -20,6 +21,7 @@ import type { EntityConstructor, RelationshipMetadata, } from "../types" +import { DALUtils } from "../../bundles" import { HasOne } from "../relations/has-one" import { HasMany } from "../relations/has-many" import { ManyToMany as DmlManyToMany } from "../relations/many-to-many" @@ -427,6 +429,8 @@ export function createMikrORMEntity() { /** * Converting class to a MikroORM entity */ - return Entity({ tableName })(MikroORMEntity) as Infer + return Entity({ tableName })( + Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)(MikroORMEntity) + ) as Infer } }