UNPKG

breeze-client

Version:

Breeze data management for JavaScript clients

195 lines (190 loc) 8.22 kB
import { HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http'; import { config, core } from 'breeze-client'; import { filter, map } from 'rxjs/operators'; /** Appends parameter to url, with appropriate delimiter */ function appendQueryStringParameter(url, parameter) { if (!parameter) return url; let separator = url.endsWith("?") ? "" : url.includes("?") ? "&" : "?"; return url + separator + parameter; } /** Encodes the object into query string parameters */ function encodeParams(obj) { let query = ''; let subValue, innerObj, fullSubName; for (let name in obj) { if (!obj.hasOwnProperty(name)) { continue; } let value = obj[name]; if (value instanceof Array) { for (let i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += encodeParams(innerObj) + '&'; } } else if (value && value.toISOString) { // a feature of Date-like things query += encodeURIComponent(name) + '=' + encodeURIComponent(value.toISOString()) + '&'; } else if (value instanceof Object) { for (let subName in value) { if (obj.hasOwnProperty(name)) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += encodeParams(innerObj) + '&'; } } } else if (value === null) { query += encodeURIComponent(name) + '=&'; } else if (value !== undefined) { query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } } return query.length ? query.substr(0, query.length - 1) : query; } class AjaxHttpClientAdapter { http; static adapterName = 'httpclient'; name = AjaxHttpClientAdapter.adapterName; defaultSettings = {}; requestInterceptor; constructor(http) { this.http = http; } static register(http, breezeConfig) { breezeConfig = breezeConfig || config; breezeConfig.registerAdapter("ajax", function () { return new AjaxHttpClientAdapter(http); }); return breezeConfig.initializeAdapterInstance("ajax", AjaxHttpClientAdapter.adapterName, true); } initialize() { } ajax(config) { if (!this.http) { throw new Error('Unable to locate angular http module for ajax adapter'); } // merge default DataSetAdapter Settings with config arg if (!core.isEmpty(this.defaultSettings)) { let compositeConfig = core.extend({}, this.defaultSettings); config = core.extend(compositeConfig, config); // extend is shallow; extend headers separately let headers = core.extend({}, this.defaultSettings['headers']); // copy default headers 1st config['headers'] = core.extend(headers, config.headers); } if (config.crossDomain) { throw new Error(this.name + ' does not support JSONP (crossDomain) requests'); } // Hack: Not sure how Angular handles writing 'search' parameters to the url. // so this approach takes over the url param writing completely. const parameters = core.isEmpty(config.params) ? null : encodeParams(config.params); const url = appendQueryStringParameter(config.url, parameters); let headers = new HttpHeaders(config.headers || {}); if (!headers.has('Content-Type')) { if (config.type !== 'GET' && config.type !== 'DELETE' && !!config.contentType) { headers = headers.set('Content-Type', config.contentType || 'application/json; charset=utf-8'); } } let body = config.data; let request = new HttpRequest((config.type || 'GET').toUpperCase(), url, body, { headers: headers, responseType: "text" }); let requestInfo = { adapter: this, request: request, dsaConfig: config, success: successFn, error: errorFn // adapter's error callback }; if (core.isFunction(this.requestInterceptor)) { this.requestInterceptor(requestInfo); if (this.requestInterceptor['oneTime']) { this.requestInterceptor = null; } } if (requestInfo.request) { // exists unless requestInterceptor killed it. const ffilter = filter((response) => response instanceof HttpResponse); const fmap = map(extractData); fmap(ffilter(this.http.request(requestInfo.request))) .forEach(requestInfo.success) .catch(requestInfo.error); } function extractData(event) { let response = event; let data; let dt = requestInfo.dsaConfig.dataType; // beware:`res.json` and `res.text` will be async some day if (dt && dt !== 'json') { data = response.body; } else { data = JSON.parse(response.body); } return { data, response }; } function successFn(arg) { if (arg.response.status < 200 || arg.response.status >= 300) { throw { data: arg.data, response: arg.response }; } let httpResponse = { config: requestInfo.request, data: arg.data, getHeaders: makeGetHeaders(arg.response.headers), status: arg.response.status }; httpResponse['ngConfig'] = requestInfo.request; httpResponse['statusText'] = arg.response.statusText; httpResponse['response'] = arg.response; config.success(httpResponse); } function errorFn(response) { if (response instanceof Error) { throw response; // program error; nothing we can do } else { let data; if (response.error instanceof HttpResponse) { data = response.error.body; } else if (response.error instanceof Error) { data = response.error.message; } else { data = response.error; } // Timeout appears as an error with status===0 and no data. if (response.status === 0 && data == null) { data = 'timeout'; } let errorMessage = response.status + ": " + response.statusText; if (data && typeof data === 'object') { data["message"] = data["message"] || errorMessage; // breeze looks at the message property } if (!data) { data = errorMessage; // Return the error message as data } let httpResponse = { config: requestInfo.request, data: data, getHeaders: makeGetHeaders(response.headers), status: response.status }; httpResponse['ngConfig'] = requestInfo.request; httpResponse['statusText'] = response.statusText; httpResponse['response'] = response; config.error(httpResponse); // send error to breeze error handler } } } } ///// Helpers //// function makeGetHeaders(headers) { return function getHeaders(headerName) { return headers.getAll(headerName).join('\r\n'); }; } /** * Generated bundle index. Do not edit. */ export { AjaxHttpClientAdapter }; //# sourceMappingURL=breeze-client-adapter-ajax-httpclient.mjs.map