diff --git a/packages/fixtures/src/MetadataStore.ts b/packages/fixtures/src/MetadataStore.ts index 903d724..8ad9870 100644 --- a/packages/fixtures/src/MetadataStore.ts +++ b/packages/fixtures/src/MetadataStore.ts @@ -5,7 +5,12 @@ import { PropertyMetadata, DefaultMetadataStore, } from 'class-fixtures-factory'; -import { MikroORM, Utils, EntityMetadata } from '@mikro-orm/core'; +import { + MikroORM, + Utils, + EntityMetadata, + ReferenceType, +} from '@mikro-orm/core'; export class MetadataStore extends BaseMetadataStore { private defaultStore = new DefaultMetadataStore(true); @@ -32,6 +37,12 @@ export class MetadataStore extends BaseMetadataStore { ); if (prop.primary) return null; if (prop.type === 'method') return null; + if (Array.isArray(prop.embedded)) { + const parent = meta.properties[prop.embedded[0]]; + if (parent.reference === ReferenceType.EMBEDDED && parent.object) { + return null; + } + } return { name: prop.name, type: defaultMetaProp?.typeFromDecorator diff --git a/packages/fixtures/test/entities/profile.entity.ts b/packages/fixtures/test/entities/profile.entity.ts new file mode 100644 index 0000000..fa76ceb --- /dev/null +++ b/packages/fixtures/test/entities/profile.entity.ts @@ -0,0 +1,8 @@ +import { Embeddable, Property } from '@mikro-orm/core'; + +@Embeddable() +export class Profile { + @Property() firstName!: string; + @Property() lastName!: string; + @Property() emailAddress!: string; +} diff --git a/packages/fixtures/test/entities/user.entity.ts b/packages/fixtures/test/entities/user.entity.ts new file mode 100644 index 0000000..2a36c6f --- /dev/null +++ b/packages/fixtures/test/entities/user.entity.ts @@ -0,0 +1,8 @@ +import { Embedded, Entity } from '@mikro-orm/core'; +import { BaseEntity } from './base.entity'; +import { Profile } from './profile.entity'; + +@Entity() +export class User extends BaseEntity { + @Embedded({ entity: () => Profile, object: true }) profile!: Profile; +} diff --git a/packages/fixtures/test/factory.test.ts b/packages/fixtures/test/factory.test.ts index f2a106e..3ca3695 100644 --- a/packages/fixtures/test/factory.test.ts +++ b/packages/fixtures/test/factory.test.ts @@ -7,6 +7,7 @@ import { FixtureFactory } from '../src/FixtureFactory'; import { WithSpecialType } from './entities/with-special-type.entity'; import { WithSpecialTypeFixed } from './entities/with-special-type-fixed.entity'; import { AuthorWithCustomization } from './entities/author-with-customization'; +import { User } from './entities/user.entity'; jest.setTimeout(20000); @@ -242,4 +243,33 @@ describe(`Factory`, () => { expect(author.address).toBeUndefined(); }); }); + + describe('@Embeddable({ object: true }) [for mongodb subdocuments]', () => { + let user: User; + + beforeAll(async () => { + // We can't be "connected" for this, as sqlite does not support embedded + // entities this way, but we can still access the metadata facilities of + // the EntityManager. + await orm.close(); + orm = await MikroORM.init(ormConfig, false); + factory = factory = new FixtureFactory(orm); + + user = factory.make(User).one(); + }); + + it('populates the embeddable entity', () => { + expect(user.profile).toBeDefined(); + expect(user.profile.firstName).toEqual(expect.any(String)); + expect(user.profile.lastName).toEqual(expect.any(String)); + expect(user.profile.emailAddress).toEqual(expect.any(String)); + }); + + it('does not populate "prefixed" properties', () => { + const possiblyPrefixed = user as any; + expect(possiblyPrefixed.profile_firstName).not.toBeDefined(); + expect(possiblyPrefixed.profile_lastName).not.toBeDefined(); + expect(possiblyPrefixed.profile_emailAddress).not.toBeDefined(); + }); + }); }); diff --git a/packages/fixtures/test/mikro-orm.config.ts b/packages/fixtures/test/mikro-orm.config.ts index d9b77ff..f1c814e 100644 --- a/packages/fixtures/test/mikro-orm.config.ts +++ b/packages/fixtures/test/mikro-orm.config.ts @@ -13,6 +13,8 @@ import { Book2, Address2, } from './entities/author-with-customization'; +import { Profile } from './entities/profile.entity'; +import { User } from './entities/user.entity'; export default { metadataProvider: TsMorphMetadataProvider, @@ -28,6 +30,8 @@ export default { AuthorWithCustomization, Book2, Address2, + User, + Profile, ], dbName: 'test.db', type: 'sqlite', diff --git a/packages/fixtures/test/temp/Profile.ts.json b/packages/fixtures/test/temp/Profile.ts.json new file mode 100644 index 0000000..69b631d --- /dev/null +++ b/packages/fixtures/test/temp/Profile.ts.json @@ -0,0 +1,69 @@ +{ + "data": { + "propertyOrder": {}, + "properties": { + "firstName": { + "name": "firstName", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + }, + "lastName": { + "name": "lastName", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + }, + "emailAddress": { + "name": "emailAddress", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + } + }, + "props": [ + { + "name": "firstName", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + }, + { + "name": "lastName", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + }, + { + "name": "emailAddress", + "reference": "scalar", + "getter": false, + "setter": false, + "type": "string" + } + ], + "primaryKeys": [], + "filters": {}, + "hooks": {}, + "indexes": [], + "uniques": [], + "className": "Profile", + "path": "./test/entities/profile.entity.ts", + "name": "Profile", + "embeddable": true, + "abstract": false, + "constructorParams": [], + "toJsonParams": [], + "useCache": true, + "relations": [], + "collection": "profile" + }, + "origin": "./test/entities/profile.entity.ts", + "hash": "250bb9ee472a9fd9864259db6090675e", + "version": "4.5.1" +} diff --git a/packages/fixtures/test/temp/User.ts.json b/packages/fixtures/test/temp/User.ts.json new file mode 100644 index 0000000..3fd1b6b --- /dev/null +++ b/packages/fixtures/test/temp/User.ts.json @@ -0,0 +1,41 @@ +{ + "data": { + "propertyOrder": {}, + "properties": { + "profile": { + "name": "profile", + "type": "Profile", + "reference": "embedded", + "object": true, + "prefix": true + } + }, + "props": [ + { + "name": "profile", + "type": "Profile", + "reference": "embedded", + "object": true, + "prefix": true + } + ], + "primaryKeys": [], + "filters": {}, + "hooks": {}, + "indexes": [], + "uniques": [], + "className": "User", + "path": "./test/entities/user.entity.ts", + "name": "User", + "abstract": false, + "constructorParams": [], + "toJsonParams": [], + "extends": "BaseEntity", + "useCache": true, + "relations": [], + "collection": "user" + }, + "origin": "./test/entities/user.entity.ts", + "hash": "9c16b52762f9d4c922a0faa76b82a775", + "version": "4.5.1" +}