import _ from 'lodash' ; import mapProperty from './lib/mapProperty' ; import { createSelectQueryBuilder , whereBuilder } from './lib/queryBuilder' ; import type { IFindQuery , IFindWhereQuery , IBaseModel , Identifier , ModifyResponse , IModelConfig , IModelOptions } from '@fastify-resty/core' ; import type { JSONSchema7 } from 'json-schema' ; import type { ObjectType , Connection } from 'typeorm' ; export class BaseModel < E extends object = any > implements IBaseModel < E > { static connection : Connection ; constructor ( protected EntityClass , config ? ) { this . config = { id : 'id' , softDelete : false , ... ( config || { } ) } ; } config : IModelConfig ; get name ( ) { return this . EntityClass . name ; } get jsonSchema ( ) : Record < string , JSONSchema7 > { const { columns } = BaseModel . connection . getMetadata ( this . EntityClass ) ; return columns . reduce ( ( props , column ) => ( { ... props , [ column . propertyName ] : mapProperty ( column ) } ) , { } ) ; } async find ( query ? ) { return createSelectQueryBuilder < E > ( BaseModel . connection , this . EntityClass , query ) . getMany ( ) ; } async total ( query ? ) { const _queryBuilder = BaseModel . connection . getRepository ( this . EntityClass ) . createQueryBuilder ( 'entity' ) ; if ( query ) { whereBuilder ( _queryBuilder , query ) ; } return _queryBuilder . getCount ( ) ; } async create ( data ) { const result = await BaseModel . connection . createQueryBuilder ( ) . insert ( ) . into ( this . EntityClass ) . values ( data ) . execute ( ) ; return { identifiers : _ . map ( result . identifiers , this . config . id ) } ; } async patch ( query , raw ) { const data = _ . omit ( raw , this . config . id ) as E ; const _queryBuilder = BaseModel . connection . createQueryBuilder ( ) . update ( this . EntityClass ) . set ( data ) ; whereBuilder ( _queryBuilder , query ) ; return { affected : _ . get ( await _queryBuilder . execute ( ) , 'affected' ) } ; } async update ( query , raw ) { const data = BaseModel . connection . getMetadata ( this . EntityClass ) . columns . reduce ( ( data , column ) => { if ( column . isPrimary && raw [ column . propertyName ] === undefined ) { return data ; } if ( ( column . isCreateDate || column . isUpdateDate || column . isDeleteDate ) && raw [ column . propertyName ] === undefined ) { return { ... data , [ column . propertyName ] : new Date ( ) } ; } return { ... data , [ column . propertyName ] : raw [ column . propertyName ] } ; } , { } ) ; const _queryBuilder = BaseModel . connection . createQueryBuilder ( ) . update ( this . EntityClass ) . set ( data ) ; whereBuilder ( _queryBuilder , query ) ; return { affected : _ . get ( await _queryBuilder . execute ( ) , 'affected' ) } ; } async remove ( query ) { const _queryBuilder = BaseModel . connection . createQueryBuilder ( ) . delete ( ) . from ( this . EntityClass ) ; whereBuilder ( _queryBuilder , query ) ; return { affected : _ . get ( await _queryBuilder . execute ( ) , 'affected' ) } ; } }