-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
66 changed files
with
4,718 additions
and
4,466 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,36 @@ | ||
import {APIError, APIUnauthorizedError, APIForbiddenError} from '../errors'; | ||
|
||
export const retryOnError = (fn, errClass=Error) => fn().catch(error => { | ||
if (error.constructor === errClass) { | ||
return fn(); | ||
} | ||
return Promise.reject(error); | ||
}); | ||
|
||
const ignoreSyntax = (error) => error.constructor.name === 'SyntaxError' ? '' : error; | ||
export const ensureJSON = (response) => response.json().catch(ignoreSyntax); | ||
|
||
export const ensureSuccessOr = (errorMsg) => | ||
(response) => { | ||
|
||
if (response.status >= 200 && response.status < 300) { | ||
return Promise.resolve(response); | ||
} else if (response.status === 403) { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new APIForbiddenError(errorMsg, responseBody))); | ||
} else if (response.status === 401) { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new APIUnauthorizedError(responseBody))); | ||
} else { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new APIError(errorMsg, responseBody))); | ||
} | ||
}; | ||
import * as fromErrors from '../errors'; | ||
|
||
export const retryOnError = (fn, errClass=Error) => fn().catch(error => { | ||
if (error.constructor === errClass) { | ||
return fn(); | ||
} | ||
return Promise.reject(error); | ||
}); | ||
|
||
const ignoreSyntax = (error) => error.constructor.name === 'SyntaxError' ? '' : error; | ||
export const ensureJSON = (response) => response.json().catch(ignoreSyntax); | ||
|
||
export const ensureSuccessOr = (errorMsg) => | ||
(response) => { | ||
|
||
if (response.status >= 200 && response.status < 300) { | ||
return Promise.resolve(response); | ||
} else if (response.status === 403) { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new fromErrors.APIForbiddenError(errorMsg, responseBody))); | ||
} else if (response.status === 401) { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new fromErrors.APIUnauthorizedError(responseBody))); | ||
} else if (response.status === 400) { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new fromErrors.APIValidationError(responseBody))) | ||
} | ||
else { | ||
return response.json() | ||
.catch(ignoreSyntax) | ||
.then(responseBody => Promise.reject(new fromErrors.APIError(responseBody))); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,81 @@ | ||
import { API_ROOT } from './config'; | ||
import { loadState } from '../persistence'; | ||
import { ensureJSON, ensureSuccessOr } from './helpers'; | ||
|
||
const getDefaultHeaders = () => { | ||
const persistedState = loadState(); | ||
const headers = new Headers(); | ||
headers.append('Content-Type', 'application/json'); | ||
if (persistedState && persistedState.hasOwnProperty('auth')) { | ||
headers.append('Authorization', `Token ${persistedState.auth.token}`); | ||
} | ||
return headers; | ||
}; | ||
|
||
const api = { | ||
requests: { | ||
get(url, params, error_msg='Failed to retrieve data from server') { | ||
let target = url; | ||
if (params && Object.keys(params).length > 0) { | ||
const queryParams = Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&'); | ||
target = `${url}?${queryParams}`; | ||
} | ||
const request = new Request(target, { | ||
method: 'GET', | ||
headers: getDefaultHeaders(), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
post(url, body, error_msg='Failed to send data to server') { | ||
const request = new Request(url, { | ||
method: 'POST', | ||
headers: getDefaultHeaders(), | ||
body: JSON.stringify(body), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
patch(url, body, error_msg='Failed to send data to server') { | ||
const request = new Request(url, { | ||
method: 'PATCH', | ||
headers: getDefaultHeaders(), | ||
body: JSON.stringify(body), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
['delete'](url, error_msg='Failed to delete data on server') { // eslint-disable-line no-useless-computed-key | ||
const request = new Request(url, { | ||
method: 'DELETE', | ||
headers: getDefaultHeaders(), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)); | ||
}, | ||
}, | ||
urls: { | ||
playerList: () => `${API_ROOT}/players/`, | ||
playerEntity: (player_id) => `${API_ROOT}/players/${player_id}/`, | ||
playerEntityInvite: (player_id) => `${API_ROOT}/players/${player_id}/invite/`, | ||
teamList: () => `${API_ROOT}/teams/`, | ||
teamListJoined: () => `${API_ROOT}/teams/joined/`, | ||
teamJoin: () => `${API_ROOT}/teams/join/`, | ||
teamEntity: (team_id) => `${API_ROOT}/teams/${team_id}/`, | ||
teamAccept: () => `${API_ROOT}/teams/accept/`, | ||
teamInvite: (team_id) => `${API_ROOT}/teams/${team_id}/invite/`, | ||
teamMemberList: (team_id) => `${API_ROOT}/teams/${team_id}/members/`, | ||
teamMemberEntity: (team_id, member_id) => `${API_ROOT}/teams/${team_id}/members/${member_id}/`, | ||
teamMatchList: (team_id) => `${API_ROOT}/teams/${team_id}/matches/`, | ||
teamMatchEntity: (team_id, match_id) => `${API_ROOT}/teams/${team_id}/matches/${match_id}/`, | ||
teamMatchPoints: (team_id) => `${API_ROOT}/teams/${team_id}/matches/points/`, | ||
profile: () => `${API_ROOT}/rest-auth/user/`, | ||
logout: () => `${API_ROOT}/rest-auth/logout/` | ||
} | ||
}; | ||
|
||
|
||
export default api; | ||
import { API_ROOT } from './config'; | ||
import { loadState } from '../persistence'; | ||
import { ensureJSON, ensureSuccessOr } from './helpers'; | ||
|
||
const getDefaultHeaders = () => { | ||
const persistedState = loadState(); | ||
const headers = new Headers(); | ||
headers.append('Content-Type', 'application/json'); | ||
if (persistedState && persistedState.hasOwnProperty('auth')) { | ||
headers.append('Authorization', `Token ${persistedState.auth.token}`); | ||
} | ||
return headers; | ||
}; | ||
|
||
const api = { | ||
requests: { | ||
get(url, params, error_msg='Failed to retrieve data from server') { | ||
let target = url; | ||
if (params && Object.keys(params).length > 0) { | ||
const queryParams = Object.entries(params).map(([key, value]) => `${key}=${value}`).join('&'); | ||
target = `${url}?${queryParams}`; | ||
} | ||
const request = new Request(target, { | ||
method: 'GET', | ||
headers: getDefaultHeaders(), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
post(url, body, error_msg='Failed to send data to server') { | ||
const request = new Request(url, { | ||
method: 'POST', | ||
headers: getDefaultHeaders(), | ||
body: JSON.stringify(body), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
patch(url, body, error_msg='Failed to send data to server') { | ||
const request = new Request(url, { | ||
method: 'PATCH', | ||
headers: getDefaultHeaders(), | ||
body: JSON.stringify(body), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)) | ||
.then(ensureJSON); | ||
}, | ||
['delete'](url, error_msg='Failed to delete data on server') { // eslint-disable-line no-useless-computed-key | ||
const request = new Request(url, { | ||
method: 'DELETE', | ||
headers: getDefaultHeaders(), | ||
}); | ||
return fetch(request) | ||
.then(ensureSuccessOr(error_msg)); | ||
}, | ||
}, | ||
urls: { | ||
playerList: () => `${API_ROOT}/players/`, | ||
playerEntity: (player_id) => `${API_ROOT}/players/${player_id}/`, | ||
playerEntityInvite: (player_id) => `${API_ROOT}/players/${player_id}/invite/`, | ||
teamList: () => `${API_ROOT}/teams/`, | ||
teamListJoined: () => `${API_ROOT}/teams/joined/`, | ||
teamJoin: () => `${API_ROOT}/teams/join/`, | ||
teamEntity: (team_id) => `${API_ROOT}/teams/${team_id}/`, | ||
teamAccept: () => `${API_ROOT}/teams/accept/`, | ||
teamInvite: (team_id) => `${API_ROOT}/teams/${team_id}/invite/`, | ||
teamMemberList: (team_id) => `${API_ROOT}/teams/${team_id}/members/`, | ||
teamMemberEntity: (team_id, member_id) => `${API_ROOT}/teams/${team_id}/members/${member_id}/`, | ||
teamMatchList: (team_id) => `${API_ROOT}/teams/${team_id}/matches/`, | ||
teamMatchEntity: (team_id, match_id) => `${API_ROOT}/teams/${team_id}/matches/${match_id}/`, | ||
teamMatchPoints: (team_id) => `${API_ROOT}/teams/${team_id}/matches/points/`, | ||
profile: () => `${API_ROOT}/rest-auth/user/`, | ||
logout: () => `${API_ROOT}/rest-auth/logout/` | ||
} | ||
}; | ||
|
||
|
||
export default api; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,41 @@ | ||
import ExtendableError from 'es6-error'; | ||
|
||
export class APIError extends ExtendableError { | ||
constructor(message, response) { | ||
const msg = response.hasOwnProperty('shouldDisplay') && response.shouldDisplay ? response.message : message; | ||
super(msg); | ||
this.serverResponse = response; | ||
} | ||
|
||
toDebugString() { | ||
return JSON.stringify(this.serverResponse, null, 2); | ||
} | ||
} | ||
|
||
export class APIUnauthorizedError extends APIError { | ||
constructor(serverResponse) { | ||
super('Session has expired.', serverResponse); | ||
} | ||
} | ||
|
||
export class APIForbiddenError extends APIError { | ||
constructor(serverResponse) { | ||
super('Access denied', serverResponse); | ||
} | ||
} | ||
import ExtendableError from 'es6-error'; | ||
|
||
export class APIError extends ExtendableError { | ||
constructor(message, response) { | ||
const msg = response.hasOwnProperty('shouldDisplay') && response.shouldDisplay ? response.message : message; | ||
super(msg); | ||
this.serverResponse = response; | ||
} | ||
|
||
toDebugString() { | ||
return JSON.stringify(this.serverResponse, null, 2); | ||
} | ||
} | ||
|
||
export class APIUnauthorizedError extends APIError { | ||
constructor(serverResponse) { | ||
super('Session has expired.', serverResponse); | ||
} | ||
} | ||
|
||
export class APIForbiddenError extends APIError { | ||
constructor(serverResponse) { | ||
super('Access denied', serverResponse); | ||
} | ||
} | ||
|
||
|
||
export class APIValidationError extends ExtendableError { | ||
constructor(serverResponse) { | ||
if (serverResponse.hasOwnProperty('non_field_errors')) { | ||
super(serverResponse.non_field_errors.join(', ')); | ||
} else { | ||
super('Failed to validate data'); | ||
} | ||
this.serverResponse = serverResponse; | ||
} | ||
|
||
toDebugString() { | ||
return JSON.stringify(this.serverResponse, null, 2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.