samuelneff / sequelize-auto-ts

Generate Sequelize definition statements and compatible TypeScript definitions from a database schema
MIT License
79 stars 20 forks source link

A different approach. #3

Closed alitaheri closed 8 years ago

alitaheri commented 8 years ago

Hi,

I really liked what you did here. But there is a killer limitation... associations! What I want to propose is to merge this project with the sequelize itself so that type definitions can be generated directly on the models defined with sequelize.define. This way all namings (where field and property have different names) all associations, all scopes can be so easily generated like it is with sequelize.sync. If that is ok with you I wish to start woking on this.

I want to document these type definitions on their website as well. I'm also updating the type definitions of DefinitelyTyped to support Association Mixins as well.

Those definitions + this project merged + type def syncing + documentation = enterprise scale typesafety with high maintainability and automation :heart_eyes:

alitaheri commented 8 years ago

Or if you wish to keep this a separate we could make an api which takes the sequelize instance and enumerate all the models and associations. That works too. Maybe even better :grin:

samuelneff commented 8 years ago

Ali,

I'm glad this project is helpful for you. I'm happy to take suggestions and make changes. I don't quite understand what you're asking for fully, but also see that parts of what you're asking for I believe are in direct opposition to what this project is intended to do.

Originally I made this project for my own internal use and thus did not document it fully. I'm amazed and proud that others have found it useful, especially considering the poor documentation. When I find time I'll document it fully; of critical importance that's missing is the philosophy behind why I do things the way I do which I'm sure can seem very unusual at first glance.

To address your first and primary issue, I'll have to say I don't understand how associations are a limitation. The project supports associations by creating type definitions that include associations (for example, given User and Role which are associated with each user having one role, the User interface will have a role property and the Roles interface will have a users property. Also the definitions created for sequelize will include the appropriate hasMany and belongsTo definitions. If two tables have a many-to-many relationship then the appropriate hasMany with through definitions are declared, as long as the "through" table begins with Xref.

If there is something needed with associations that I'm not seeing, I'm certainly open to suggestions and requests. Please include a clear example of the database structure you're referring to and the TyepScript code you'd like to see generated.

Regarding the DefinitelyTyped project itself, I have not and do not intend to load the sequelize.d.ts definitions to DefinitelyTyped because these definitions are not all that helpful by themselves. They're intended to work very closely with the sequelize-types.ts that gets generated, which are specific to an individual database and thus would be entirely inappropriate to be hosted on DefinitelyTyped.

As for integration with Sequelize itself, I don't think that would ever happen since Sequelize is not a TypeScript project. I also don't see the advantage.

Lastly regarding sync, that goes against one of the fundamental opinions of this project (which I readily admit is very opinionated, it was originally created for my own use, and I have strong opinions about my projects). The key driving factor is that I personally believe in database-first not code-first, which is what Sequelize and most modern ORMs encourage.

The purpose of sequelize-auto-ts besides just providing types is to generate the Sequelize model definitions for you in sequelize-models.ts. Once you define your database, sequelize-auto-ts will read the database and generate types, identifier constants, and model definitions. An upcoming addition will also include a model-factory to easily support multiple (identical) databases in one project.

If one were to want to do code-first development with a project such as this, then I personally would have programmed it such that it read the type interfaces (code) and then generated the models from that (definitions) and used Sequelize to sync. That is certainly possible, it just goes against my personal beliefs and the theories behind this project.

Note I don't want to imply code-first is wrong--it's neither wrong nor right. It's just a different approach and my personal opinion (which is a minority opinion) is that database-first is superior.

That said, if you do want to use this project to support code-first, it would not be hard at all. Most of the code will remain the same, with the only difference being the schema.ts file. This is what reads the database schema and generates the in-memory definitions of tables and fields. If you were to write another module to support reading from sequelize models instead, everything else would still work fine. You would still use the table/field/etc definitions from schema.ts and just create a custom read implementation that read from the Sequelize model definitions then triggered the callback with the fully constructed Schema instance.

Thanks for your interest,

Sam

alitaheri commented 8 years ago

Thank you for the time you took to write this.

To address your first and primary issue, I'll have to say I don't understand how associations are a limitation.

What I meant was the type definitions not the support sequelize has for them. For that reason I'm working on the type definitions to address this. I mean like this.

Lastly regarding sync...

Well you do have a point there. I guess I will have to spend some time on my free time to read your code and try to adept it in a way that can both ways. I'd say it's the ideal approach. Database-first and code-first both have their use-cases and should both be respected. I'll see if I can find the time to work on it.

I guess I will try my best to add an api that takes in a sequelize instance and generates types from it. Using a modified schema.ts file.

samuelneff commented 8 years ago

OK, feel free to ask if you have any questions.

Note that you shouldn't need to modify schema.ts to do what you want. You'll be better off creating a new one and the using the interfaces exposed by schema.ts. Then modify sequelize-auto-ts to allow a choice between database-first or code-first, and modify cli to allow specifying that choice on a command line (and if you want to go a step further, modify grunt-sequelize-auto-ts separate project to add this option). I'm happy to help with the integration parts when you get that point.

alitaheri commented 8 years ago

Oh, I misunderstood the first time. thank you

P.S. I first have to fix their api and design the mixin types before I can do anything else.