import { CustomFieldEntry , AvailableGames , CloudSyncStatus , LastLaunchedVersion } from '../../types/interfaces' ; import config from './config' ; import * as I from './interfaces' ; import { PlayerExtension } from 'csgogsi-socket' ; const apiUrl = config . apiAddress ; interface DB { teams : I . Team [ ] ; players : I . Player [ ] ; } function arrayBufferToBase64 ( buffer ) { let binary = '' ; const bytes = [ ] . slice . call ( new Uint8Array ( buffer ) ) ; bytes . forEach ( b => ( binary += String . fromCharCode ( b ) ) ) ; return window . btoa ( binary ) ; } export const maxWins = ( type ) => { switch ( type ) { case 'bo1' : return 1 ; case 'bo3' : return 2 ; case 'bo5' : return 3 ; case 'bo7' : return 4 ; case 'bo9' : return 5 ; default : return 2 ; } } ; const apiHandler = ( url , method = 'GET' , body , credentials ) => { const options = { method , headers : { Accept : 'application/json' , 'Content-Type' : 'application/json' } , credentials : credentials ? 'include' : undefined } ; if ( body ) { options . body = JSON . stringify ( body ) ; } let data = null ; return fetch ( url , options ) . then ( res => { data = res ; return res . json ( ) . catch ( ( ) => data && data . status < 300 ) ; } ) ; } ; export function clone < T > ( obj ) { return JSON . parse ( JSON . stringify ( obj ) ) ; } export async function apiV2 < T > ( url , method = 'GET' , body ? ) { return apiHandler < T > ( `${ config . isDev ? apiUrl : '/' }api/${ url }` , method , body ) ; } export default { players : { get : ( ) => apiV2 < I . Player [ ] > ( 'players' ) , add : async ( player ) => await apiV2 ( 'players' , 'POST' , player ) , update : async ( id , player ) => await apiV2 ( `players/${ id }` , 'PATCH' , player ) , delete : async ( id ) => await apiV2 ( `players/${ typeof id === 'string' ? id : id . join ( ';' ) }` , 'DELETE' ) , getAvatar : async ( id ) => { fetch ( `${ apiUrl }api/players/avatar/${ id }` ) ; } , import : ( data ) => apiV2 ( 'players/import' , 'POST' , { data } ) , fields : { get : ( ) => apiV2 < CustomFieldEntry [ ] > ( 'players/fields' ) , update : ( fields ) => apiV2 < CustomFieldEntry [ ] > ( 'players/fields' , 'PATCH' , fields ) } , replaceUsernames : ( players ) => apiV2 ( 'replaceWithMirv' , 'POST' , { players } ) } , teams : { get : async ( ) => apiV2 < I . Team [ ] > ( 'teams' ) , add : async ( team ) => await apiV2 ( 'teams' , 'POST' , team ) , update : async ( id , team ) => await apiV2 ( `teams/${ id }` , 'PATCH' , team ) , delete : async ( id ) => await apiV2 ( `teams/${ typeof id === 'string' ? id : id . join ( ';' ) }` , 'DELETE' ) , import : ( data ) => apiV2 ( 'teams/import' , 'POST' , { data } ) , getLogo : async ( id ) => { const response = await fetch ( `${ apiUrl }api/teams/logo/${ id }` ) ; return response ; } , fields : { get : ( ) => apiV2 < CustomFieldEntry [ ] > ( 'teams/fields' ) , update : ( fields ) => apiV2 < CustomFieldEntry [ ] > ( 'teams/fields' , 'PATCH' , fields ) } } , arg : { connect : ( id ) => apiV2 ( 'arg' , 'POST' , { id } ) , disconnect : ( ) => apiV2 ( 'arg' , 'DELETE' ) , requestStatus : ( ) => apiV2 ( 'arg' ) , setDelay : ( delay ) => apiV2 ( 'arg/delay' , 'POST' , { delay } ) , setClips : ( saveClips ) => apiV2 ( 'arg/save' , 'POST' , { saveClips } ) , save : ( order ) => apiV2 ( 'arg/order' , 'POST' , order ) , get : ( ) : Promise < I . Item [ ] > => apiV2 ( 'arg/order' ) } , config : { get : async ( ) : Promise < I . ExtendedConfig > => await apiV2 ( 'config' ) , update : async ( config ) => await apiV2 ( 'config' , 'PATCH' , config ) , download : async ( target ) => { if ( config . isElectron ) { return await apiV2 ( `${ target }/download` ) ; } window . location . assign ( `${ config . isDev ? apiUrl : '/' }api/${ target }/download` ) ; } , getVersion : ( ) : Promise < { version : string ; } > => apiV2 ( 'version' ) , getLastVersion : ( ) : Promise < LastLaunchedVersion > => apiV2 ( 'version/last' ) , setLastVersion : ( version , releaseDate ) => apiV2 ( 'version/last' , 'POST' , { version , releaseDate } ) } , cameras : { get : ( ) : Promise < { availablePlayers : I . CameraRoomPlayer [ ] ; uuid : string ; password : string ; } > => apiV2 ( 'camera' ) , update : ( players , password , toggle ) => apiV2 ( toggle ? 'camera?&toggle=true' : 'camera' , 'POST' , { players , password } ) , regenerate : ( ) => apiV2 ( 'camera' , 'PATCH' ) } , cfgs : { check : async ( game ) : Promise < I . CFGGSIObject > => await apiV2 ( `cfg?game=${ game }` ) , create : async ( game ) : Promise < I . CFGGSIObject > => await apiV2 ( `cfg?game=${ game }` , 'PUT' ) } , gamestate : { check : async ( game ) : Promise < I . CFGGSIObject > => await apiV2 ( `gsi?game=${ game }` ) , create : async ( game ) : Promise < I . CFGGSIObject > => await apiV2 ( `gsi?game=${ game }` , 'PUT' ) } , game : { run : async ( config ) => await apiV2 ( `game/run` , 'POST' , config ) , runTest : ( ) => apiV2 ( 'test' , 'POST' ) , toggleLoop : ( ) => apiV2 ( 'test/loop' , 'POST' ) } , games : { getCurrent : ( ) : Promise < { game : AvailableGames ; init : boolean ; } > => apiV2 ( `games/current` ) , startServices : ( game ) : Promise < { result : CloudSyncStatus ; } > => apiV2 ( `games/start/${ game }` ) } , cloud : { upload : ( force = false ) => apiV2 ( force ? 'cloud/upload?&replace=force' : 'cloud/upload' , 'POST' ) , download : ( ) => apiV2 ( 'cloud/download' , 'POST' ) , size : ( ) : Promise < { size : number ; } > => apiV2 ( 'cloud/size' ) } , huds : { get : async ( ) : Promise < I . HUD [ ] > => await apiV2 ( 'huds' ) , start : async ( hudDir ) => await apiV2 ( `huds/${ hudDir }/start` , 'POST' ) , close : async ( hudDir ) => await apiV2 ( `huds/${ hudDir }/close` , 'POST' ) , openDirectory : async ( ) => await apiV2 ( `huds` , 'POST' ) , save : async ( hud , name ) => await apiV2 ( `huds/add` , 'POST' , { hud , name } ) , delete : async ( hudDir ) => await apiV2 ( `huds?hudDir=${ hudDir }` , 'DELETE' ) , deleteFromCloud : async ( uuid ) => await apiV2 ( `huds/delete/${ uuid }` , 'DELETE' ) , download : ( uuid ) : Promise < { result : I . HUD | null ; } > => apiV2 ( `huds/download/${ uuid }` ) , upload : ( hudDir ) : Promise < any > => apiV2 ( `huds/upload/${ hudDir }` , 'POST' ) } , machine : { get : async ( ) : Promise < { id : string ; } > => await apiV2 ( 'machine' ) } , match : { get : async ( ) : Promise < I . Match [ ] > => await apiV2 ( 'match?full' ) , set : async ( match ) : Promise < I . Match [ ] > => apiV2 ( 'match' , 'PATCH' , match ) , add : async ( match ) => apiV2 ( 'match' , 'POST' , match ) , update : async ( id , match ) => await apiV2 ( `match/${ id }` , 'PATCH' , match ) , delete : async ( id ) => await apiV2 ( `match/${ id }` , 'DELETE' ) , getMaps : async ( ) : Promise < string [ ] > => await apiV2 ( 'maps' ) } , tournaments : { get : async ( ) : Promise < I . Tournament [ ] > => await apiV2 ( 'tournaments' ) , add : ( tournament ) : Promise < I . Tournament > => apiV2 ( 'tournaments' , 'POST' , tournament ) , bind : ( tournamentId , matchId , matchupId ) => apiV2 ( `tournaments/${ tournamentId }` , 'POST' , { matchId , matchupId } ) , delete : ( tournamentId ) => apiV2 ( `tournaments/${ tournamentId }` , 'DELETE' ) , update : ( tournamentId , data ) => apiV2 ( `tournaments/${ tournamentId }` , 'PATCH' , data ) } , user : { login : ( username , password , token ) : Promise < any > => apiV2 ( 'auth' , 'POST' , { username , password , token } ) , logout : ( ) => apiV2 ( 'auth' , 'DELETE' ) , getCurrent : ( ) : Promise < I . Customer | { message : string ; success : boolean ; } > => apiV2 ( 'auth' ) } , ar : { get : async ( ) : Promise < I . ARModule [ ] > => await apiV2 ( 'ar' ) , save : async ( ar , name ) => await apiV2 ( `ar/add` , 'POST' , { ar , name } ) , openDirectory : async ( ) => await apiV2 ( `huds` , 'POST' ) } , files : { imgToBase64 : async ( url ) => { try { const response = await fetch ( url ) ; if ( response . status !== 200 ) { return null ; } const buffer = await response . arrayBuffer ( ) ; return arrayBufferToBase64 ( buffer ) ; } catch ( e ) { return null ; } } , sync : async ( db ) => await apiV2 < any > ( 'import' , 'POST' , db ) , syncCheck : async ( db ) => await apiV2 < any > ( 'import/verify' , 'POST' , db ) } , aco : { get : ( ) : Promise < I . MapConfig [ ] > => apiV2 ( 'aco' ) , set : ( config ) => apiV2 ( 'aco' , 'POST' , config ) } , bakkesmod : { check : async ( ) => await apiV2 < I . BakkesModStatusResponse > ( 'bakkesmod/check' ) , downloadMod : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/download/mod' ) , downloadModData : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/download/mod_data' ) , downloadSos : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/download/sos' ) , installModData : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/install/mod_data' ) , installSos : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/install/sos' ) , run : async ( ) => await apiV2 < I . BakkesModAPIResponse > ( 'bakkesmod/run' ) } , f1 : { get : ( ) => apiV2 < { installed : boolean ; configured : boolean ; } > ( 'f1/status' ) , install : ( ) => apiV2 ( 'f1/install' , 'POST' ) } } ;