refactor(core): Use mixins to delete redundant code between Entity classes (no-changelog) (#6616)
* db entities don't need an ID before they are inserted * don't define constructors on entity classes, use repository.create instead * use mixins to reduce duplicate code in db entity classes
This commit is contained in:
committed by
GitHub
parent
e6903a87b5
commit
dc2ba743eb
@@ -1,6 +1,13 @@
|
||||
import { BeforeUpdate, CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
||||
import {
|
||||
BeforeInsert,
|
||||
BeforeUpdate,
|
||||
CreateDateColumn,
|
||||
PrimaryColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { IsDate, IsOptional } from 'class-validator';
|
||||
import config from '@/config';
|
||||
import { generateNanoId } from '../utils/generators';
|
||||
|
||||
const dbType = config.getEnv('database.type');
|
||||
|
||||
@@ -14,26 +21,53 @@ const timestampSyntax = {
|
||||
export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json';
|
||||
export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime';
|
||||
|
||||
export abstract class AbstractEntity {
|
||||
@CreateDateColumn({
|
||||
precision: 3,
|
||||
default: () => timestampSyntax,
|
||||
})
|
||||
@IsOptional() // ignored by validation because set at DB level
|
||||
@IsDate()
|
||||
createdAt: Date;
|
||||
const tsColumnOptions = {
|
||||
precision: 3,
|
||||
default: () => timestampSyntax,
|
||||
};
|
||||
|
||||
@UpdateDateColumn({
|
||||
precision: 3,
|
||||
default: () => timestampSyntax,
|
||||
onUpdate: timestampSyntax,
|
||||
})
|
||||
@IsOptional() // ignored by validation because set at DB level
|
||||
@IsDate()
|
||||
updatedAt: Date;
|
||||
type Constructor<T> = new (...args: any[]) => T;
|
||||
|
||||
@BeforeUpdate()
|
||||
setUpdateDate(): void {
|
||||
this.updatedAt = new Date();
|
||||
function mixinStringId<T extends Constructor<{}>>(base: T) {
|
||||
class Derived extends base {
|
||||
@PrimaryColumn('varchar')
|
||||
id: string;
|
||||
|
||||
@BeforeInsert()
|
||||
generateId() {
|
||||
if (!this.id) {
|
||||
this.id = generateNanoId();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Derived;
|
||||
}
|
||||
|
||||
function mixinTimestamps<T extends Constructor<{}>>(base: T) {
|
||||
class Derived extends base {
|
||||
@CreateDateColumn(tsColumnOptions)
|
||||
@IsOptional() // ignored by validation because set at DB level
|
||||
@IsDate()
|
||||
createdAt: Date;
|
||||
|
||||
@UpdateDateColumn({
|
||||
...tsColumnOptions,
|
||||
onUpdate: timestampSyntax,
|
||||
})
|
||||
@IsOptional() // ignored by validation because set at DB level
|
||||
@IsDate()
|
||||
updatedAt: Date;
|
||||
|
||||
@BeforeUpdate()
|
||||
setUpdateDate(): void {
|
||||
this.updatedAt = new Date();
|
||||
}
|
||||
}
|
||||
return Derived;
|
||||
}
|
||||
|
||||
class BaseEntity {}
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
export const WithStringId = mixinStringId(BaseEntity);
|
||||
export const WithTimestamps = mixinTimestamps(BaseEntity);
|
||||
export const WithTimestampsAndStringId = mixinStringId(WithTimestamps);
|
||||
|
||||
Reference in New Issue
Block a user