import { BotonicEvent , EventTypes , User } from '@botonic/core' ; import { JsonDB } from 'node-json-db' ; import { Config } from 'node-json-db/dist/lib/JsonDBConfig' ; import { DataProvider } from './factory' ; export class LocalDevDataProvider implements DataProvider { private readonly DB_PATH = 'tmp/localDb' ; private readonly SEPARATOR = '/' ; private readonly paths = { USERS : '/users' , EVENTS : '/events' , CONNECTIONS : '/connections' , } ; db : JsonDB ; constructor ( url ? ) { const dbPath = url ? url . split ( '://' ) [ 1 ] : this . DB_PATH ; this . db = new JsonDB ( new Config ( dbPath , true , false , this . SEPARATOR ) ) ; } getUsers ( limit = 10 , offset = 0 ) { const path = this . paths . USERS ; this . db . reload ( ) ; const userList = this . db . getObject < Record < string , User > > ( path ) ; const users = Object . values ( userList ) ; const to = limit !== 0 ? offset + limit : undefined ; return users . slice ( offset , to ) ; } getUser ( userId ) { const path = this . createPath ( [ this . paths . USERS , userId ] ) ; this . db . reload ( ) ; return this . db . exists ( path ) ? this . db . getObject < User > ( path ) : undefined ; } getUserByWebsocketId ( websocketId ) { return this . getUserByField ( 'websocketId' , websocketId ) ; } getUserByField ( field , value ) { const path = this . paths . USERS ; this . db . reload ( ) ; const dbUser = this . db . exists ( path ) ? this . db . find < User > ( path , ( user ) => user [ field ] === value ) : undefined ; return dbUser ; } saveUser ( user ) { const path = this . createPath ( [ this . paths . USERS , user . id ] ) ; this . db . reload ( ) ; if ( ! this . db . exists ( path ) ) { this . db . push ( path , user ) ; } return user ; } updateUser ( user ) { const path = this . createPath ( [ this . paths . USERS , user . id ] ) ; this . db . reload ( ) ; if ( this . db . exists ( path ) ) { this . db . push ( path , user , true ) ; } return user ; } deleteUser ( id ) { const path = this . createPath ( [ this . paths . USERS , id ] ) ; this . db . reload ( ) ; const user = this . db . exists ( path ) ? this . db . getObject < User > ( path ) : undefined ; if ( user ) { this . db . delete ( path ) ; return user ; } return undefined ; } getEvents ( limit = 10 , offset = 0 ) { const path = this . paths . EVENTS ; this . db . reload ( ) ; const eventList = this . db . getObject < Record < string , BotonicEvent > > ( path ) ; const events = Object . values ( eventList ) ; const to = limit !== 0 ? offset + limit : undefined ; return events . slice ( offset , to ) ; } getEvent ( id ) { const path = this . createPath ( [ this . paths . EVENTS , id ] ) ; this . db . reload ( ) ; return this . db . exists ( path ) ? this . db . getObject < BotonicEvent > ( path ) : undefined ; } saveEvent ( event ) { const path = this . createPath ( [ this . paths . EVENTS , event . eventId ] ) ; this . db . reload ( ) ; if ( ! this . db . exists ( path ) ) { if ( [ EventTypes . CONNECTION , EventTypes . MESSAGE ] . includes ( event . eventType ) ) { this . db . push ( path , event ) ; } } return event ; } updateEvent ( event ) { const path = this . createPath ( [ this . paths . EVENTS , event . eventId ] ) ; this . db . reload ( ) ; if ( this . db . exists ( path ) ) { this . db . push ( path , event , true ) ; } return event ; } deleteEvent ( id ) { const path = this . createPath ( [ this . paths . EVENTS , id ] ) ; this . db . reload ( ) ; const event = this . db . exists ( path ) ? this . db . getObject < BotonicEvent > ( path ) : undefined ; if ( event ) { this . db . delete ( path ) ; return event ; } return undefined ; } addConnection ( websocketId ) { const path = this . createPath ( [ this . paths . CONNECTIONS , websocketId ] ) ; this . db . reload ( ) ; if ( ! this . db . exists ( path ) ) { this . db . push ( path , '' , false ) ; } } updateConnection ( websocketId , userId ) { const path = this . createPath ( [ this . paths . CONNECTIONS , websocketId ] ) ; this . db . reload ( ) ; if ( this . db . exists ( path ) ) { this . db . push ( path , userId , true ) ; } } deleteConnection ( websocketId ) { const path = this . createPath ( [ this . paths . CONNECTIONS , websocketId ] ) ; this . db . reload ( ) ; this . db . delete ( path ) ; } private createPath ( urlChunks ) { return urlChunks . join ( this . SEPARATOR ) ; } }