UNPKG

cv-dialog-sdk

Version:

Catavolt Dialog Javascript API

197 lines (173 loc) 8.13 kB
import { BlobClientResponse } from '../client/BlobClientResponse'; import { Client } from '../client/Client'; import {ClientListener} from "../client/ClientListener"; import { JsonClientResponse } from '../client/JsonClientResponse'; import { ReadableStreamClientResponse } from '../client/StreamingClientResponse'; import { TextClientResponse } from '../client/TextClientResponse'; import { VoidClientResponse } from '../client/VoidClientResponse'; import { StreamProducer } from '../io/StreamProducer'; import {CvLocale, Log, StringDictionary} from '../util'; export type FetchMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; export class FetchClient implements Client { private _lastActivity: Date = new Date(); private _locale:CvLocale; private _clientListener:ClientListener; public isAnyUserInBriefcaseMode(tenantId: string): Promise<boolean> { return Promise.resolve(false); } public isUserInBriefcaseMode(userInfo:{}):Promise<boolean> { return Promise.resolve(false); } public addClientListener(clientListener: ClientListener, locale:CvLocale) { this._clientListener = clientListener; this._locale = locale; } public removeClientListener(clientListener: ClientListener) { this._clientListener = null; } public getBlob(baseUrl: string, resourcePath?: string): Promise<BlobClientResponse> { const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'GET').then((response: Response) => { return response.blob().then(blob => new BlobClientResponse(blob, response.status)); }); } public getText(baseUrl: string, resourcePath?: string): Promise<TextClientResponse> { const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'GET').then((response: Response) => { return response.text().then(text => new TextClientResponse(text, response.status)); }); } public openStream(baseUrl: string, resourcePath?: string): Promise<StreamProducer> { const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'GET').then((response: Response) => { return Promise.resolve(new ReadableStreamClientResponse(response.body, response.status)); }); } public postMultipart(baseUrl: string, resourcePath: string, formData: FormData): Promise<VoidClientResponse> { const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'POST', formData).then((response: Response) => { return new VoidClientResponse(response.status); }); } public getJson( baseUrl: string, resourcePath?: string, queryParams?: StringDictionary ): Promise<JsonClientResponse> { const headers = { Accept: 'application/json' }; const queryString = this.encodeQueryParams(queryParams); const url = resourcePath ? `${baseUrl}/${resourcePath}${queryString}` : `${baseUrl}${queryString}`; return this.processRequest(url, 'GET', null, headers).then((response: Response) => { return this.assertJsonContentType(response.headers.get('content-type')).then(() => { return response.json().then(json => new JsonClientResponse(json, response.status)); }); }); } get lastActivity(): Date { return this._lastActivity; } public postJson(baseUrl: string, resourcePath: string, jsonBody?: StringDictionary): Promise<JsonClientResponse> { const headers = { Accept: 'application/json', 'Content-Type': 'application/json;charset=UTF-8' }; const body = jsonBody && JSON.stringify(jsonBody); const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'POST', body, headers).then((response: Response) => { return this.assertJsonContentType(response.headers.get('content-type')).then(() => { return response.json().then(json => new JsonClientResponse(json, response.status)); }); }); } public putJson(baseUrl: string, resourcePath: string, jsonBody?: StringDictionary): Promise<JsonClientResponse> { const headers = { Accept: 'application/json', 'Content-Type': 'application/json;charset=UTF-8' }; const body = jsonBody && JSON.stringify(jsonBody); const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'PUT', body, headers).then((response: Response) => { return this.assertJsonContentType(response.headers.get('content-type')).then(() => { return response.json().then(json => new JsonClientResponse(json, response.status)); }); }); } public deleteJson(baseUrl: string, resourcePath: string): Promise<JsonClientResponse> { const headers = { Accept: 'application/json' }; const url = resourcePath ? `${baseUrl}/${resourcePath}` : baseUrl; return this.processRequest(url, 'DELETE', null, headers).then((response: Response) => { return this.assertJsonContentType(response.headers.get('content-type')).then(() => { return response.json().then(json => new JsonClientResponse(json, response.status)); }); }); } public fetch( url: string, method: FetchMethod, body?: any, headers?: { [index: string]: string }, fetchOpts?: {} ): Promise<Response> { return this.processRequest(url, method, body, headers, fetchOpts); } private assertJsonContentType(contentType: string): Promise<void> { return new Promise((resolve, reject) => { if (this.isJsonContentType(contentType)) { resolve(); } else { reject(new Error(`Expected 'application/json', got ${contentType}`)); } }); } private encodeQueryParams(queryParams: StringDictionary): string { let result = ''; if (queryParams) { for (const name in queryParams) { if (queryParams.hasOwnProperty(name)) { result += `${encodeURIComponent(name)}=${encodeURIComponent(queryParams[name])}&`; } } } return result.length > 0 ? `?${result.slice(0, -1)}` : result; } private isJsonContentType(contentType: string): boolean { return contentType && contentType.includes('application/json'); } private processRequest( url: string, method: FetchMethod, body?: any, headers?: { [index: string]: string }, fetchOpts?: {} ): Promise<Response> { return new Promise((resolve, reject) => { const requestHeaders: Headers = new Headers(headers); const init: RequestInit = { method, mode: 'cors' }; if (body) { init.body = body; } if (headers) { init.headers = new Headers(headers); } if (fetchOpts) { Object.assign(init, fetchOpts); } if (!['GET', 'POST', 'PUT', 'DELETE'].some(v => method === v)) { reject(new Error(`FetchClient::processRequest: Unsupported method: ${method}`)); } else { const start = Date.now(); Log.debug(`Fetch request: ${method} ${url} [body]:${body ? body : 'none'}`); fetch(url, init) .then(response => { this._lastActivity = new Date(); Log.debug(`Fetch request took: ${ Date.now() - start } ms`); resolve(response); }) .catch(error => { this._lastActivity = new Date(); reject(error); }); } }); } }