import redis , { ClientOpts , RedisClient } from 'redis' ; import { promisify } from 'util' ; import { Zone } from '@portaler/types' ; type ExpireTimes = 'EX' | 'PX' | 'NX' | 'XX' | 'KEEPTTL' | 'GET' ; export default class RedisConnector { client : RedisClient ; getAsync : ( key : string ) => Promise < any > ; setAsync : ( key : string , value : string , mode ? : ExpireTimes , expires ? : number ) => Promise < any > ; delAsync : ( key : string ) => Promise < any > ; constructor ( config ) { this . client = redis . createClient ( { ... config , retry_strategy : ( { error } ) => this . client . emit ( 'error' , error ) , } ) ; this . getAsync = promisify ( this . client . get ) . bind ( this . client ) ; this . setAsync = promisify ( this . client . set ) . bind ( this . client ) ; this . delAsync = promisify ( this . client . del ) . bind ( this . client ) ; } setUser = async ( token , userId , serverId ) => { const hasUser = await this . getUser ( `${ userId }:${ serverId }` ) ; if ( hasUser ) { await this . delUser ( hasUser , userId , serverId ) ; } return await Promise . all ( [ this . setAsync ( token , `${ userId }:${ serverId }` ) , this . setAsync ( `${ userId }:${ serverId }` , token ) , ] ) ; } ; getUser = async ( token ) : Promise < string > => await this . getAsync ( token ) ; getToken = async ( userId , serverId ) => await this . getAsync ( `${ userId }:${ serverId }` ) ; delUser = async ( token , userId , serverId ) => await Promise . all ( [ this . delAsync ( token ) , this . delAsync ( `${ userId }:${ serverId }` ) , ] ) ; delServer = async ( serverId , userIds ) => { const tokenList = await Promise . all ( userIds . map ( ( uid ) => this . getToken ( uid , serverId ) ) ) ; const delTokens = tokenList . map ( ( t ) => this . delAsync ( t ) ) ; const delUsers = userIds . map ( ( uid ) => this . delAsync ( `${ uid }:${ serverId }` ) ) ; const delServer = this . delAsync ( `server:${ serverId }` ) ; await Promise . all ( [ ... delTokens , ... delUsers , delServer ] ) ; } ; setZones = async ( zones ) => { await this . delAsync ( 'zones' ) ; return await this . setAsync ( 'zones' , JSON . stringify ( zones ) ) ; } ; getZones = async ( ) => await this . getAsync ( 'zones' ) ; setZone = async ( zone ) => await this . setAsync ( `zone:${ zone . id }` , JSON . stringify ( zone ) , 'EX' , 7200 ) ; getZone = async ( id ) => await this . getAsync ( `zone:${ id }` ) ; }