require('isomorphic-fetch');

const isomorphicFetch = fetch;

{{> ./httpClient_common}}

function json(text:string){
    return JSON.parse(text, jsonReviver);
}

export interface FetchAPI { (url: string, init?: any): Promise<any>; }

export const DEFAULT_HEADERS: HeadersInit = {};

export class BaseApi {
	public static beforeRequest?: (method: AjaxMethod, localVarPath: string, queryParameters: any, bodyDict: any) => void;
	public static afterResponse?: (response: any) => void;
	constructor(protected fetch: FetchAPI = isomorphicFetch, protected basePath: string = BASE_PATH) {
	}
	/** Assert required */
	protected r(params: any, fieldNames: string[]) {
		for (const fieldName of fieldNames) {
			const value = params[fieldName];
			if (value === null || value === undefined) {
				throw new Error(`field: ${fieldName} required`);
			}
		}
	}
	protected async ajax(method: AjaxMethod, localVarPath: string, queryParameters: any, bodyDict: any): Promise<any> {
		const f = this.fetch;
		BaseApi.beforeRequest?.(method, localVarPath, queryParameters, bodyDict);
		const query = new URLSearchParams(queryParameters).toString();
		const pathAndQuery = query ? localVarPath + "?" + query : localVarPath;
		let fetchOptions: RequestInit = {
			method: method,
			headers: {
				"Content-Type": "application/json",
				...DEFAULT_HEADERS
			},
		};
		if (bodyDict) {
			fetchOptions.body = JSON.stringify(bodyDict);
		}
		const response = await f(this.basePath + pathAndQuery, fetchOptions);
		BaseApi.afterResponse?.(response);
		if (response.status >= 200 && response.status < 300) {
			return json((await response.text()) || 'null');
		}
		else {
			const json = await response.json();
			throw json;
		}
	}
}
