devextreme-angular
Version:
Angular UI and visualization components based on DevExtreme widgets
262 lines (257 loc) • 10.6 kB
JavaScript
import * as i0 from '@angular/core';
import { createNgModuleRef, NgModule } from '@angular/core';
import { HttpEventType, HttpParams, HttpClient, HttpClientModule } from '@angular/common/http';
import devextremeAjax from 'devextreme/core/utils/ajax';
import { Subject, throwError } from 'rxjs';
import { takeUntil, timeoutWith } from 'rxjs/operators';
import { Deferred } from 'devextreme/core/utils/deferred';
import { isDefined } from 'devextreme/core/utils/type';
import { getWindow } from 'devextreme/core/utils/window';
import { getMethod, getRequestHeaders as getRequestHeaders$1, getAcceptHeader, getJsonpCallbackName, evalCrossDomainScript, evalScript, isCrossDomain, getRequestOptions } from 'devextreme/core/utils/ajax_utils';
/*!
* devextreme-angular
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file in the root of the project for details.
*
* https://github.com/DevExpress/devextreme-angular
*/
/* eslint-disable @typescript-eslint/no-floating-promises */
const PARSER_ERROR = 'parsererror';
const SUCCESS = 'success';
const ERROR = 'error';
const NO_CONTENT = 'nocontent';
const TIMEOUT = 'timeout';
const STATUS_ABORT = 0;
const CONTENT_TYPE = 'Content-Type';
const URLENCODED = 'application/x-www-form-urlencoded';
function assignResponseProps(xhrSurrogate, response) {
const getResponseHeader = (name) => response.headers.get(name);
function makeResponseText() {
const body = 'error' in response ? response.error : response.body;
if (typeof body !== 'string' || String(getResponseHeader(CONTENT_TYPE)).startsWith('application/json')) {
return JSON.stringify(body);
}
return body;
}
Object.assign(xhrSurrogate, {
status: response.status,
statusText: response.statusText,
getResponseHeader,
responseText: makeResponseText(),
});
return xhrSurrogate;
}
function isGetMethod(options) {
return getMethod(options) === 'GET';
}
function isCacheNeed(options) {
if (options.cache === undefined) {
return !(isUsedScript(options) || isUsedJSONP(options));
}
return options.cache;
}
function isUsedScript(options) {
return options.dataType === 'script';
}
function isUsedJSONP(options) {
return options.dataType === 'jsonp';
}
function getRequestHeaders(options) {
const headers = getRequestHeaders$1(options);
const { upload } = options;
if (!headers.Accept) {
headers.Accept = getAcceptHeader(options);
}
if (!upload && !isGetMethod(options) && !headers[CONTENT_TYPE]) {
headers[CONTENT_TYPE] = options.contentType || `${URLENCODED};charset=utf-8`;
}
return Object.keys(headers).reduce((acc, key) => {
if (isDefined(headers[key])) {
acc[key] = headers[key];
}
return acc;
}, {});
}
function rejectIfAborted(deferred, xhrSurrogate, callback) {
if (xhrSurrogate.aborted) {
deferred.reject({ status: STATUS_ABORT, statusText: 'aborted', ok: false });
callback?.();
}
}
function getJsonpParameters(options) {
const patchedOptions = { ...options };
const callbackName = getJsonpCallbackName(patchedOptions);
return { callbackName, data: patchedOptions.data };
}
function addJsonpCallback(callbackName, deferred, xhrSurrogate) {
getWindow()[callbackName] = (data) => deferred.resolve(data, SUCCESS, xhrSurrogate);
}
function sendRequestByScript(url, deferred, xhrSurrogate) {
evalCrossDomainScript(url).then(() => deferred.resolve(null, SUCCESS, xhrSurrogate), () => deferred.reject(xhrSurrogate, ERROR));
}
function getRequestCallbacks(options, deferred, xhrSurrogate) {
return {
next(response) {
if (isUsedJSONP(options)) {
return options.crossDomain
? deferred.resolve(response, 'success', assignResponseProps(xhrSurrogate, response))
: evalScript(response.body);
}
if (isUsedScript(options)) {
evalScript(response.body);
}
return deferred.resolve(response.body, response.body ? 'success' : NO_CONTENT, assignResponseProps(xhrSurrogate, response));
},
error(error) {
error = error && typeof error === 'object' ? error : { error };
let errorStatus = error?.statusText === TIMEOUT ? TIMEOUT : 'error';
errorStatus = options.dataType === 'json' && error?.message?.includes?.('parsing')
? PARSER_ERROR
: errorStatus;
return deferred.reject(assignResponseProps(xhrSurrogate, { status: 400, ...error }), errorStatus, error);
},
complete() {
rejectIfAborted(deferred, xhrSurrogate);
},
};
}
function getUploadCallbacks(options, deferred, xhrSurrogate) {
let total = 0;
let isUploadStarted = false;
return {
next: (event) => {
if (!isUploadStarted
&& [HttpEventType.UploadProgress, HttpEventType.Sent].includes(event.type)) {
options.upload.onloadstart?.(event);
isUploadStarted = true;
}
if (event.type === HttpEventType.UploadProgress) {
total += event.loaded;
options.upload.onprogress?.({ ...event, total });
}
else if (event.type === HttpEventType.Response) {
xhrSurrogate.status = event.status;
xhrSurrogate.statusText = event.statusText;
xhrSurrogate.response = event;
const result = options?.dataType === 'json' && typeof event.body === 'object'
? event.body
: xhrSurrogate;
return deferred.resolve(result, SUCCESS);
}
return null;
},
error(error) {
error = error && typeof error === 'object' ? error : { error };
return deferred.reject(assignResponseProps(xhrSurrogate, { status: 400, ...error }), error.status, error);
},
complete() {
rejectIfAborted(deferred, xhrSurrogate, () => {
options.upload?.onabort?.(xhrSurrogate);
});
},
};
}
const sendRequestFactory = (httpClient) => (options) => {
const abort$ = new Subject();
const deferred = Deferred();
const result = deferred.promise();
const isGet = isGetMethod(options);
const isJSONP = isUsedJSONP(options);
const isScript = isUsedScript(options);
options.crossDomain = isCrossDomain(options.url);
options.cache = isCacheNeed(options);
const headers = getRequestHeaders(options);
const xhrSurrogate = {
type: 'XMLHttpRequestSurrogate',
aborted: false,
abort() {
this.aborted = true;
abort$.next();
},
};
result.abort = () => xhrSurrogate.abort();
if (!options.crossDomain && isJSONP) {
const { callbackName, data } = getJsonpParameters(options);
options.data = { ...options.data, ...data };
addJsonpCallback(callbackName, deferred, xhrSurrogate);
}
const { url, parameters: data } = getRequestOptions(options, headers);
const { upload, beforeSend, xhrFields } = options;
beforeSend?.(xhrSurrogate);
if (options.crossDomain && isScript && !xhrSurrogate.aborted) {
sendRequestByScript(url, deferred, xhrSurrogate);
return result;
}
if (options.cache === false && isGet && data) {
data._ = Date.now() + 1;
}
const makeBody = () => (!upload && typeof data === 'object' && headers[CONTENT_TYPE].indexOf(URLENCODED) === 0
? Object.keys(data).reduce((httpParams, key) => httpParams.set(key, data[key]), new HttpParams()).toString()
: data);
const body = isGet ? undefined : makeBody();
const params = isGet ? data : undefined;
const request = options.crossDomain && isJSONP
? httpClient.jsonp(url, options.jsonp || 'callback')
: httpClient.request(getMethod(options), url, {
params,
body,
headers,
reportProgress: true,
withCredentials: xhrFields?.withCredentials,
observe: upload ? 'events' : 'response',
responseType: options.responseType || (isScript || isJSONP ? 'text' : options.dataType),
});
const subscriptionCallbacks = upload
? getUploadCallbacks
: getRequestCallbacks;
request.pipe.apply(request, [
takeUntil(abort$),
...options.timeout
? [timeoutWith(options.timeout, throwError({ statusText: TIMEOUT, status: 0, ok: false }))]
: [],
]).subscribe(subscriptionCallbacks(options, deferred, xhrSurrogate));
return result;
};
/*!
* devextreme-angular
* Version: 24.2.6
* Build date: Mon Mar 17 2025
*
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file in the root of the project for details.
*
* https://github.com/DevExpress/devextreme-angular
*/
class DxHttpModule {
constructor(injector) {
let httpClient = injector.get(HttpClient, null);
if (!httpClient) {
const moduleRef = createNgModuleRef(HttpClientModule, injector);
httpClient = moduleRef.injector.get(HttpClient);
}
devextremeAjax.inject({ sendRequest: sendRequestFactory(httpClient) });
}
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxHttpModule, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule });
/** @nocollapse */ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: DxHttpModule });
/** @nocollapse */ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxHttpModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DxHttpModule, decorators: [{
type: NgModule,
args: [{
exports: [],
imports: [],
providers: [],
}]
}], ctorParameters: () => [{ type: i0.Injector }] });
/**
* Generated bundle index. Do not edit.
*/
export { DxHttpModule };
//# sourceMappingURL=devextreme-angular-http.mjs.map