import { utils } from "realm-utils" ; import { FuseDB } from "./FuseDB" ; import { Model } from "./Model" ; import { ensureDatabaseCorrectValues } from "./Utils" ; import { FieldType } from "./decorators/FIeld" ; import { FieldValidator } from "./validators/FieldValidator" ; interface FieldValidationProperties { props : any ; } export class Schema { public name : string ; private cls : any ; private validators = new Map < string , { props : any ; validator : FieldValidator ; } [ ] > ( ) ; private collection : { [ key ] : boolean | string | FieldType ; } ; public static validators = new Map < string , FieldValidator > ( ) ; constructor ( public proto ) { if ( proto . $collection ) { this . name = proto . $collection ; } else { this . name = proto . constructor . name ; } this . cls = proto . constructor ; this . collection = { _id : true , } ; } public add ( name , type ? ) { if ( ! this . contains ( name ) ) { this . collection [ name ] = type || true ; } } public addValidator ( field , props , validator ) { let info = this . validators . get ( field ) ; if ( ! info ) { info = [ ] ; this . validators . set ( field , info ) ; } info . push ( { props : props , validator : validator , } ) ; } public validate ( instance ) { const values = { } ; if ( instance [ "_id" ] ) { values . _id = instance [ "_id" ] ; } const errors = { } ; for ( let key in this . collection ) { if ( key !== "_id" ) { let value = instance [ key ] ; const validators = this . validators . get ( key ) ; let errored = false ; if ( this . validators . get ( key ) ) { for ( const item of validators ) { try { item . validator . validate ( key , item . props , value ) ; } catch ( e ) { errored = true ; errors [ key ] = e . message || `Uknown error message while validating "${ key }" property` ; } } } } } if ( Object . keys ( errors ) . length ) { throw { $fields : errors } ; } } public toDatabase ( instance , extraValidationRequired ? ) { if ( extraValidationRequired ) { this . validate ( instance ) ; } const values = { } ; if ( instance [ "_id" ] ) { values . _id = instance [ "_id" ] ; } for ( let key in this . collection ) { if ( key !== "_id" ) { let value = instance [ key ] ; values [ key ] = ensureDatabaseCorrectValues ( value ) ; } } return values ; } public createInstance ( values ) { return new this . cls ( values ) ; } public mapValues ( values ) { let items = [ ] ; for ( let item of values ) { const instance = this . createInstance ( item ) ; if ( instance [ "onFetched" ] ) { instance [ "onFetched" ] ( item ) ; } items . push ( instance ) ; } return items ; } public getValues ( instance ) { const values = { } ; for ( let key in this . collection ) { if ( instance [ key ] !== undefined ) { values [ key ] = instance [ key ] ; } } return values ; } public contains ( name ) { return this . collection [ name ] !== undefined ; } public getCollection ( ) { return this . collection ; } }