diff --git a/src/util/CancelablePromise.tsx b/src/util/CancelablePromise.tsx index 1fa2d12..2bda5bf 100644 --- a/src/util/CancelablePromise.tsx +++ b/src/util/CancelablePromise.tsx @@ -31,6 +31,13 @@ export interface CancelableOptions { interval: number; } +/** + * The error thrown when the {@link CancelablePromise} is canceled + */ +export interface CanceledError { + isCanceled: true; +} + /** * Make a promise cancelable and repeatable * diff --git a/src/util/__tests__/http.test.tsx b/src/util/__tests__/http.test.tsx index da78b12..d1469dd 100644 --- a/src/util/__tests__/http.test.tsx +++ b/src/util/__tests__/http.test.tsx @@ -15,6 +15,7 @@ import HttpClient, { } from "../http"; import api from "../api"; import { Config } from "../../config"; +import { CanceledError } from "../CancelablePromise"; const originalReload = window.location.reload; @@ -114,9 +115,8 @@ describe("convertJSON", () => { }); it("should reject with input if canceled", async () => { - const cancelError = { - isCanceled: true, - test: true + const cancelError: CanceledError = { + isCanceled: true }; await expect(convertJSON(cancelError)).rejects.toEqual(cancelError); diff --git a/src/util/http.tsx b/src/util/http.tsx index c601505..3c0df75 100644 --- a/src/util/http.tsx +++ b/src/util/http.tsx @@ -11,6 +11,7 @@ import api from "./api"; import { Config } from "../config"; import { TimeRange } from "../components/common/context/TimeRangeContext"; +import { CanceledError } from "./CancelablePromise"; /** * A class which provides HTTP functions. Each function parses the response and @@ -27,6 +28,7 @@ export default class HttpClient { * @returns A promise with the data or error returned */ get = (url: string, options: RequestInit = {}): Promise => { + // @ts-ignore return fetch(this.urlFor(url), { credentials: this.credentialType(), ...options @@ -45,6 +47,7 @@ export default class HttpClient { * @returns A promise with the data or error returned */ post = (url: string, data: object): Promise => { + // @ts-ignore return fetch(this.urlFor(url), { method: "POST", body: JSON.stringify(data), @@ -65,6 +68,7 @@ export default class HttpClient { * @returns A promise with the data or error returned */ put = (url: string, data: object): Promise => { + // @ts-ignore return fetch(this.urlFor(url), { method: "PUT", body: JSON.stringify(data), @@ -84,6 +88,7 @@ export default class HttpClient { * @returns A promise with the data or error returned */ delete = (url: string): Promise => { + // @ts-ignore return fetch(this.urlFor(url), { method: "DELETE", credentials: this.credentialType() @@ -121,10 +126,10 @@ export default class HttpClient { * If the user is logged in, check if the user's session has lapsed. * If so, log them out and refresh the page. * - * @param response the Response from fetch - * @return {Promise} if logged in, the response, otherwise a canceled promise + * @param response The Response from fetch + * @return If logged in, the response, otherwise a canceled promise */ -export const checkIfLoggedOut = (response: Response) => { +export const checkIfLoggedOut = (response: Response): Promise => { if (api.loggedIn && response.status === 401) { // Clear the user's old session and refresh the page document.cookie = @@ -144,22 +149,24 @@ export const checkIfLoggedOut = (response: Response) => { * @param data a Response or Error * @returns {*} a promise with the parsed JSON, or the error */ -export const convertJSON = (data: any): Promise => { - if (data.isCanceled || data instanceof Error) { +export const convertJSON = ( + data: Response | Error | CanceledError +): Promise => { + if ((data as CanceledError).isCanceled || data instanceof Error) { return Promise.reject(data); } - return data.json(); + return (data as Response).json(); }; /** * Check for an error returned by the API * * @param data the parsed JSON body of the response - * @returns {*} a resolving promise with the data if no error, otherwise a + * @returns A resolving promise with the data if no error, otherwise a * rejecting promise with the error */ -export const checkForErrors = (data: any): Promise => { +export const checkForErrors = (data: T): Promise => { if (data.error) { return Promise.reject(data.error); } @@ -171,13 +178,16 @@ export const checkForErrors = (data: any): Promise => { * Convert an object into GET parameters. The object must be flat (only * key-value pairs). * - * @param params the parameters object - * @returns {string} the parameters converted into GET parameter form + * @param params The parameters object + * @returns The parameters converted into GET parameter form */ -export const paramsToString = (params: any) => - Object.keys(params) +export const paramsToString = (params: { + [key: string]: string | number; +}): string => { + return Object.keys(params) .map(key => key + "=" + params[key]) .join("&"); +}; /** * Convert a time range into GET parameters @@ -185,8 +195,9 @@ export const paramsToString = (params: any) => * @param range The time range to convert * @return The time range as GET parameters */ -export const timeRangeToParams = (range: TimeRange) => - paramsToString({ +export const timeRangeToParams = (range: TimeRange) => { + return paramsToString({ from: range.from.unix(), until: range.until.unix() }); +};