Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] false-positive success when using named export on seeder file #119

Open
micalevisk opened this issue Mar 9, 2021 · 10 comments
Open
Assignees
Labels
on hold External action is required to work on this

Comments

@micalevisk
Copy link

micalevisk commented Mar 9, 2021

Basically, when the seeder file has some export const foo = 'bar'-ish statement, the run method is not invoked and the output is this:

🌱  TypeORM Seeding v1.6.1
βœ” ORM Config loaded
βœ” Factories are imported
βœ” Seeders are imported
β ‹ Connecting to the databaseINFO: All classes found using provided glob pattern xxx
INFO: All classes found using provided glob pattern xxx
βœ” Database connected
πŸ‘  Finished Seeding

I think that typeorm-seeding CLI should ignore these statements regardless of whether it is right or not to have them in a seeder file.


I've notice that this behavior is due to seedFileObject[keys[0]]

export const importSeed = async (filePath: string): Promise<SeederConstructor> => {
const seedFileObject: { [key: string]: SeederConstructor } = await import(filePath)
const keys = Object.keys(seedFileObject)
return seedFileObject[keys[0]]
}

because this will return the foo variable instead of the seeder class. I've thought that return seedFileObject.default was enough but @hirsch88 already use this in the past with require (on 84df811)

Maybe this should work but I'm not sure:

export const importSeed = async (filePath: string): Promise<SeederConstructor> => {
  const seedFileObject: { [key: string]: SeederConstructor } = await import(filePath)
  return seedFileObject.default
}
@jorgebodega
Copy link
Collaborator

Hi! Sorry for late response. I think it could be better to detect the seeder by some kind or regexp or maybe by using file name.

Feel free to dissent with me, open to more ideas

@jorgebodega jorgebodega self-assigned this Oct 7, 2021
@micalevisk
Copy link
Author

To me, using export default to identify the seeder class is pretty good. But I don't know what are the odds of relying on default property

@jorgebodega
Copy link
Collaborator

I have no problem to use default export, but usually I try to avoid that. This link explain very well why.

But what I said, I have no problem with this if we are consistent, but could be a breaking change for someone that is using non-default exports.

@RaphaelWoude opinions here, pls πŸ™

@jorgebodega jorgebodega added the on hold External action is required to work on this label Oct 11, 2021
@micalevisk
Copy link
Author

This link explain very well why.

@jorgebodega got it.

For now, you could add some note on README regarding this limitation. Something like: "Seeder files must not contain any other export statement besides the one that exports the seeder class (due to this issue)" right?

@jorgebodega
Copy link
Collaborator

jorgebodega commented Oct 11, 2021

Yes, that could work temporary while we still work on this. I will keep this issue open to use it as a reference.

Thanks for your help!

@RaphaelWoude
Copy link
Collaborator

I think we should just use the modern module syntax. I have had a ton of problems before with export default. The link you provided pretty much sums it up.

@jorgebodega
Copy link
Collaborator

For me, the best way to do this is by using non default export and use instanceof to check every import as a Seeder, that is an interface.

/**
* Seed are the class to create some data. Those seed are run by the cli.
*/
export interface Seeder {
run(factory: Factory, connection: Connection): Promise<void>
}

@micalevisk
Copy link
Author

micalevisk commented Oct 11, 2021

then this interface becomes

abstract class Seeder {
  abstract run(factory: any, connection: any): Promise<void> 
}

and now users should move class Foo implements Seeder to class Foo extends Seeder? This approach looks good to me. This could be a problem if someone has been using
Class Foo implements Seeder extends Bar tho, since they cannot extends from both Seeder and Bar

@jorgebodega
Copy link
Collaborator

jorgebodega commented Oct 11, 2021

For me mikro-orm seeding is a very good example on how to do this. But is unreleased yet.

I'm pretty sure we should create a project and start working on next version, maybe a 2.x version, because there will be breaking changes for sure.

@micalevisk
Copy link
Author

cool!

What if there are multiple seeder class exported? I don't know how Mikro ORM handle this. My suggestion is: to prevent misuages, typeorm-seeding will throw an error if more than one seeder class is found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
on hold External action is required to work on this
Projects
None yet
Development

No branches or pull requests

3 participants