import { GlobalConfig } from '@n8n/config'; import { Container } from '@n8n/di'; import type { ColumnOptions } from '@n8n/typeorm'; import { BeforeInsert, BeforeUpdate, Column, CreateDateColumn, PrimaryColumn, UpdateDateColumn, } from '@n8n/typeorm'; import { generateNanoId } from '@n8n/utils'; import type { Class } from 'n8n-core'; export const { type: dbType } = Container.get(GlobalConfig).database; const timestampSyntax = { sqlite: "STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')", postgresdb: 'CURRENT_TIMESTAMP(3)', }[dbType]; export const jsonColumnType = dbType === 'sqlite' ? 'simple-json' : 'json'; export const datetimeColumnType = dbType === 'postgresdb' ? 'timestamptz' : 'datetime'; const binaryColumnTypeMap = { sqlite: 'blob', postgresdb: 'bytea', } as const; const binaryColumnType = binaryColumnTypeMap[dbType]; export function JsonColumn(options?: Omit) { return Column({ ...options, type: jsonColumnType, }); } export function DateTimeColumn(options?: Omit) { return Column({ ...options, type: datetimeColumnType, }); } export function BinaryColumn(options?: Omit) { return Column({ ...options, type: binaryColumnType, }); } const tsColumnOptions: ColumnOptions = { precision: 3, default: () => timestampSyntax, type: datetimeColumnType, }; // eslint-disable-next-line @typescript-eslint/no-explicit-any function mixinStringId>(base: T) { class Derived extends base { @PrimaryColumn('varchar') id: string; @BeforeInsert() generateId() { if (!this.id) { this.id = generateNanoId(); } } } return Derived; } // eslint-disable-next-line @typescript-eslint/no-explicit-any function mixinUpdatedAt>(base: T) { class Derived extends base { @UpdateDateColumn(tsColumnOptions) updatedAt: Date; @BeforeUpdate() setUpdateDate(): void { this.updatedAt = new Date(); } } return Derived; } // eslint-disable-next-line @typescript-eslint/no-explicit-any function mixinCreatedAt>(base: T) { class Derived extends base { @CreateDateColumn(tsColumnOptions) createdAt: Date; } return Derived; } class BaseEntity {} export const WithStringId = mixinStringId(BaseEntity); export const WithCreatedAt = mixinCreatedAt(BaseEntity); export const WithUpdatedAt = mixinUpdatedAt(BaseEntity); export const WithTimestamps = mixinCreatedAt(mixinUpdatedAt(BaseEntity)); export const WithTimestampsAndStringId = mixinStringId(WithTimestamps);