From 637e3672f28e9526ca9feaec1e631ae4e05560e5 Mon Sep 17 00:00:00 2001 From: Victor Korzunin Date: Mon, 6 Sep 2021 00:49:57 +0200 Subject: [PATCH] feat: generate relation associations --- .plop/Model.ts.hbs | 51 ++++++++++++++++--------- prisma/models/Post.ts | 39 ++++++++++++------- prisma/models/User.ts | 88 ++++++++++++++++++++++++------------------- src/index.ts | 8 ++++ 4 files changed, 116 insertions(+), 70 deletions(-) diff --git a/.plop/Model.ts.hbs b/.plop/Model.ts.hbs index 09619eb..e9f4b04 100644 --- a/.plop/Model.ts.hbs +++ b/.plop/Model.ts.hbs @@ -1,24 +1,39 @@ -import {Optional, Sequelize, ModelAttributes, Model, DataTypes} from 'sequelize'; +import { Sequelize, Model, DataTypes, ModelCtor } from 'sequelize'; export const {{model.name}}Factory = (sequelize: Sequelize) => { - const {{model.name}} = sequelize.define('{{model.name}}', { - {{#each scalarFields}} - {{name}}: { - type: {{#if isList}}DataTypes.ARRAY(DataTypes.{{type}}){{else}}DataTypes.{{type}}{{/if}},{{#if (eq allowNull false)}} - allowNull: {{allowNull}},{{/if}}{{#if isId}} - primaryKey: {{isId}},{{/if}}{{#if isAutoincrement}} - autoIncrement: {{isAutoincrement}},{{/if}}{{#if isUnique}} - unique: {{isUnique}},{{/if}} + class {{model.name}} extends Model { + {{#if relationFields}} + static associate(models: Record>) { + {{#each relationFields}} + this.belongsTo(models.{{name}}, { targetKey: '{{targetKey}}', foreignKey: '{{foreignKey}}' }); + {{/each}} + } + {{/if}} + } + + {{model.name}}.init( + { + {{#each scalarFields}} + {{name}}: { + type: {{#if isList}}DataTypes.ARRAY(DataTypes.{{type}}){{else}}DataTypes.{{type}}{{/if}},{{#if (eq allowNull false)}} + allowNull: {{allowNull}},{{/if}}{{#if isId}} + primaryKey: {{isId}},{{/if}}{{#if isAutoincrement}} + autoIncrement: {{isAutoincrement}},{{/if}}{{#if isUnique}} + unique: {{isUnique}},{{/if}} + }, + {{/each}} }, - {{/each}} - }, { - tableName: '{{#if model.dbName}}{{model.dbName}}{{else}}{{model.name}}{{/if}}', - timestamps: {{or (or hasCreatedAt hasUpdatedAt) hasDeletedAt}},{{#if (or (or hasCreatedAt hasUpdatedAt) hasDeletedAt)}}{{#if (eq hasCreatedAt false)}} - createdAt: false,{{/if}}{{#if (eq hasUpdatedAt false)}} - updatedAt: false,{{/if}}{{!-- {{#if (eq hasDeletedAt false)}} - deletedAt: false,{{/if}} --}}{{#if hasDeletedAt}} - paranoid: true,{{/if}}{{/if}} - }); + { + sequelize, + modelName: '{{model.name}}', + tableName: '{{#if model.dbName}}{{model.dbName}}{{else}}{{model.name}}{{/if}}', + timestamps: {{or (or hasCreatedAt hasUpdatedAt) hasDeletedAt}},{{#if (or (or hasCreatedAt hasUpdatedAt) hasDeletedAt)}}{{#if (eq hasCreatedAt false)}} + createdAt: false,{{/if}}{{#if (eq hasUpdatedAt false)}} + updatedAt: false,{{/if}}{{!-- {{#if (eq hasDeletedAt false)}} + deletedAt: false,{{/if}} --}}{{#if hasDeletedAt}} + paranoid: true,{{/if}}{{/if}} + } + ); return {{model.name}}; }; diff --git a/prisma/models/Post.ts b/prisma/models/Post.ts index 6d9db12..f0db6d5 100644 --- a/prisma/models/Post.ts +++ b/prisma/models/Post.ts @@ -1,20 +1,31 @@ -import {Optional, Sequelize, ModelAttributes, Model, DataTypes} from 'sequelize'; +import { Sequelize, Model, DataTypes, ModelCtor } from 'sequelize'; export const PostFactory = (sequelize: Sequelize) => { - const Post = sequelize.define('Post', { - id: { - type: DataTypes.INTEGER, - allowNull: false, - primaryKey: true, - autoIncrement: true, - }, - userId: { - type: DataTypes.INTEGER, + class Post extends Model { + static associate(models: Record>) { + this.belongsTo(models.User, { targetKey: 'id', foreignKey: 'userId' }); + } + } + + Post.init( + { + id: { + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + userId: { + type: DataTypes.INTEGER, + }, }, - }, { - tableName: 'Posts', - timestamps: false, - }); + { + sequelize, + modelName: 'Post', + tableName: 'Posts', + timestamps: false, + } + ); return Post; }; diff --git a/prisma/models/User.ts b/prisma/models/User.ts index 3942255..54965e2 100644 --- a/prisma/models/User.ts +++ b/prisma/models/User.ts @@ -1,43 +1,55 @@ -import {Optional, Sequelize, ModelAttributes, Model, DataTypes} from 'sequelize'; +import { Sequelize, Model, DataTypes, ModelCtor } from 'sequelize'; export const UserFactory = (sequelize: Sequelize) => { - const User = sequelize.define('User', { - id: { - type: DataTypes.INTEGER, - allowNull: false, - primaryKey: true, - autoIncrement: true, - }, - email: { - type: DataTypes.STRING, - allowNull: false, - unique: true, - }, - weight: { - type: DataTypes.FLOAT, - }, - is18: { - type: DataTypes.BOOLEAN, - }, - name: { - type: DataTypes.STRING, - }, - successorId: { - type: DataTypes.INTEGER, - }, - keywords: { - type: DataTypes.ARRAY(DataTypes.STRING), - allowNull: false, - }, - biography: { - type: DataTypes.JSONB, - allowNull: false, - }, - }, { - tableName: 'User', - timestamps: true, - updatedAt: false, - }); + class User extends Model { + static associate(models: Record>) { + this.belongsTo(models.User, { targetKey: 'id', foreignKey: 'successorId' }); + this.belongsTo(models.User, { targetKey: '', foreignKey: '' }); + } + } + + User.init( + { + id: { + type: DataTypes.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + email: { + type: DataTypes.STRING, + allowNull: false, + unique: true, + }, + weight: { + type: DataTypes.FLOAT, + }, + is18: { + type: DataTypes.BOOLEAN, + }, + name: { + type: DataTypes.STRING, + }, + successorId: { + type: DataTypes.INTEGER, + }, + keywords: { + type: DataTypes.ARRAY(DataTypes.STRING), + allowNull: false, + }, + biography: { + type: DataTypes.JSONB, + allowNull: false, + }, + }, + { + sequelize, + modelName: 'User', + tableName: 'User', + timestamps: true, + updatedAt: false, + } + ); return User; }; diff --git a/src/index.ts b/src/index.ts index 956c004..4d38c0e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -74,6 +74,14 @@ generatorHandler({ isAutoincrement: field.hasDefaultValue && typeof field.default === 'object' && field.default.name === 'autoincrement', })), + relationFields: model.fields + .filter((field) => field.kind === 'object') + .filter((field) => !field.isList) + .map((field) => ({ + name: field.type, + targetKey: field.relationToFields![0], + foreignKey: field.relationFromFields[0], + })), hasCreatedAt: attributes.includes('createdAt'), hasUpdatedAt: attributes.includes('updatedAt'), hasDeletedAt: attributes.includes('deletedAt'),