typeorm-factory
typeorm-factory copied to clipboard
[Enhancement Suggestion] Pass instance to Function `attrs`
Imagine I have a UserProfile entity that depends on an account being created asynchronously with an IDP. The best (maybe only?) way to do that is to use the functional attrs. The code may look like this:
const TEST_ACCOUNT_PASSWORD = "test1234";
export default class UserProfileFactory extends Factory<UserProfile> {
protected attrs(): FactorizedAttrs<UserProfile> {
const isMale = Math.random() > 0.5;
const firstName = faker.person.firstName(isMale ? "male" : "female");
const lastName = faker.person.lastName(isMale ? "male" : "female");
const email = faker.internet.email({ firstName, lastName });
return {
id: async () => {
const user = await idp.createUser({
email, // faker value
password: TEST_ACCOUNT_PASSWORD,
});
return user.uid;
},
email, // overridden value
firstName,
lastName,
};
}
protected dataSource: DataSource = dataSource;
protected entity: Constructable<UserProfile> = UserProfile;
}
This actually works perfectly when using something like userProfileFactory.create(10). However, when the instance needs attributes to be overridden, (e.g. userProfileFactory.create(10, {email: "[email protected]")) the email value persisted to the database is different than the one written to the IDP.
My recommendation is to pass the entity instance back to the function so the instance values can be accessed from the Function attrs.
...
id: async (instance) => {
const user = await idp.createUser({
email: instance.email,
password: TEST_ACCOUNT_PASSWORD,
});
return user.uid;
},
...
This should be a fairly straight-forward change and I'd be comfortable making a PR for it. Please let me know if you'd be open to that.
Hello!
Thanks for the idea and the code, but what is the difference between this and EagerInstanceAttribute/LazyInstanceAttribute?
Good question. I had the same thought initially before creating the issue, but the problem is the {Eager,Lazy}InstanceAttribute doesn't support asynchronous code.