require('es6-promise').polyfill(); require('isomorphic-fetch'); export interface Identifyable { id: any; } export interface IFetchConfig { protocol: string; ip: string; port?: number; api?: string; } export interface IFetchBase { delete(item: T): Promise; find(id: any): Promise; findAll(suffix?: string): Promise; get(queryParams?: string): Promise; head(item: T): Promise; post(item: T): Promise; put(item: T): Promise; } export abstract class FetchBase implements IFetchBase { protected endpoint: string = ''; protected requestMode: RequestMode = 'cors'; constructor(private config: IFetchConfig) {} head(item: T): Promise { return fetch(this.getUrl(item), this.headOptions()) .then(this.handleHeadFetchResponse) .catch(this.rejectErrorPromise); } findAll(suffix?: string): Promise { return fetch(`${this.getUrl()}${suffix}`, this.getOptions()) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } find(id: any): Promise { return fetch(this.getUrl({ id }), this.getOptions()) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } get(queryParams?: string): Promise { return fetch(this.getUrl(void 0, queryParams), this.getOptions()) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } put(item: T): Promise { return fetch(this.getUrl(item), this.putOptions(item)) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } post(item: T): Promise { return fetch(this.getUrl(item), this.postOptions(item)) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } delete(item: T): Promise { return fetch(this.getUrl(item), this.deleteOptions()) .then(this.handleFetchResponse) .then((json: any) => this.jsonResponse(json)) .catch(this.rejectErrorPromise); } getUrl(resource?: T, queryParams?: string): string { let { protocol, ip, port } = this.config; if (!protocol) { protocol = 'http'; } if (!ip) { ip = 'localhost'; } let portString = ''; if (port != null && port > 0) { portString += `:${port}`; } let url = `${protocol}://${ip}${portString}`; url += this.config.api ? `/${this.config.api}` : ''; url += this.endpoint ? `/${this.endpoint}` : ''; let resourceId = ''; if (resource != null && resource.id != null) { resourceId = resource.id.toString(); } if (resourceId.length > 0 && resourceId != '0') { url += `/${resourceId}`; } if (queryParams != null && queryParams.length > 0) { url += queryParams; } return url; } protected rejectErrorPromise(reason: Error) { return Promise.reject(reason); } protected jsonResponse(json) { return Promise.resolve(json); } protected handleFetchResponse(response: Response) { if (!response.ok) { return Promise.reject(new Error(response.statusText)); } return response.json(); } protected handleHeadFetchResponse(response: Response) { if (!response.ok) { return Promise.reject(new Error(response.statusText)); } return Promise.resolve(response.headers); } protected headOptions(): RequestInit { return this.getRequestInit('HEAD'); } protected getOptions(): RequestInit { return this.getRequestInit('GET'); } protected postOptions(item: T): RequestInit { return this.getRequestInit('POST', JSON.stringify(item)); } protected putOptions(item: T): RequestInit { return this.getRequestInit('PUT', JSON.stringify(item)); } protected deleteOptions(): RequestInit { return this.getRequestInit('DELETE'); } protected getRequestInit(method: string, body?: string): RequestInit { return { body, method, mode: this.requestMode, headers: { 'Content-Type': 'application/json' } }; } }