UNPKG

ng-http-interceptor

Version:
533 lines (515 loc) 14.9 kB
import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/of'; import 'rxjs/add/observable/empty'; import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/mergeMap'; import { Injectable, NgModule } from '@angular/core'; import { ConnectionBackend, Headers, Http, HttpModule, RequestOptions, XHRBackend } from '@angular/http'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InterceptableStoreFactory { /** * @template D * @return {?} */ createStore() { return new InterceptableStore(); } } InterceptableStoreFactory.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InterceptableStoreFactory.ctorParameters = () => []; const DEFAULT_URL_STORE = '/'; class InterceptableStore { constructor() { this.storeMatcher = {}; this.stores = {}; this.activeStore = DEFAULT_URL_STORE; } /** * @return {?} */ get store() { return this._getStoreSafely(this.activeStore); } /** * @param {?} interceptor * @return {?} */ addInterceptor(interceptor) { this.store.push(interceptor); return this; } /** * @param {?} interceptor * @return {?} */ removeInterceptor(interceptor) { const /** @type {?} */ idx = this.store.indexOf(interceptor); if (idx === -1) { return this; } this.store.splice(idx, 1); return this; } /** * @param {?=} interceptors * @return {?} */ clearInterceptors(interceptors = []) { if (interceptors.length > 0) { interceptors.forEach(i => this.removeInterceptor(i)); } else { this.store.splice(0); } return this; } /** * @param {?=} url * @return {?} */ setActiveStore(url = DEFAULT_URL_STORE) { this.activeStore = String(url); if (url instanceof RegExp) { this.storeMatcher[this.activeStore] = url; } return this; } /** * @param {?=} key * @return {?} */ getStore(key = DEFAULT_URL_STORE) { return this._getStoreSafely(key); } /** * @param {?=} url * @return {?} */ getMatchedStores(url = DEFAULT_URL_STORE) { const /** @type {?} */ backedUrl = `/${url.replace('/', '\\/')}/`; // Use it for direct string matching return Object.keys(this.stores) .filter(k => k === url || k === backedUrl || (this.storeMatcher[k] && this.storeMatcher[k].test(url))) .filter((k, i, arr) => k !== DEFAULT_URL_STORE && arr.indexOf(k) === i) .map(k => this.getStore(k)) .reduce((stores, store) => [...stores, ...store], this.getStore(DEFAULT_URL_STORE)); } /** * @param {?} key * @return {?} */ _getStoreSafely(key) { return (this.stores[key] || (this.stores[key] = [])); } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class HttpInterceptorService { /** * @param {?} store */ constructor(store) { this.store = store; this._requestStore = this.store.createStore(); this._responseStore = this.store.createStore(); } /** * @param {?} res * @return {?} */ static wrapInObservable(res) { return res instanceof Observable ? res : Observable.of(res); } /** * @param {?=} url * @return {?} */ request(url = DEFAULT_URL_STORE) { return this._requestStore.setActiveStore(url); } /** * @param {?=} url * @return {?} */ response(url = DEFAULT_URL_STORE) { return this._responseStore.setActiveStore(url); } /** * @param {?} url * @param {?} method * @param {?} data * @param {?=} context * @return {?} */ _interceptRequest(url, method, data, context) { return this._requestStore.getMatchedStores(url).reduce((o, i) => o.flatMap(d => { if (!d) { return Observable.of(d); } return HttpInterceptorService.wrapInObservable(i(d, method, context)); }), Observable.of(data)); } /** * @param {?} url * @param {?} method * @param {?} response * @param {?=} context * @return {?} */ _interceptResponse(url, method, response, context) { return this._responseStore.getMatchedStores(url).reduce((o, i) => i(o, method, context), response); } } HttpInterceptorService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ HttpInterceptorService.ctorParameters = () => [ { type: InterceptableStoreFactory, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const SAFE_PROXY_TRAPS = ['get', 'set', 'apply']; /** * @param {?} ref * @return {?} */ function identityFactory_(ref) { return ref; } /** * @param {?} provide * @param {?} obj * @return {?} */ function identityFactory(provide, obj) { return { provide, useFactory: identityFactory_, deps: [obj] }; } /** * @param {?} handler * @return {?} */ function safeProxyHandler_(handler) { const /** @type {?} */ safeHandler = {}; SAFE_PROXY_TRAPS .filter(trap => typeof handler[trap] === 'function') .forEach(trap => safeHandler[trap] = handler[trap].bind(handler)); return safeHandler; } /** * @param {?} obj * @param {?} handler * @return {?} */ function safeProxy(obj, handler) { return new Proxy(obj, safeProxyHandler_(handler)); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InterceptableHttpProxyService { /** * @param {?} http * @param {?} httpInterceptorService */ constructor(http, httpInterceptorService) { this.http = http; this.httpInterceptorService = httpInterceptorService; } /** * @param {?} url * @return {?} */ static _extractUrl(url) { const /** @type {?} */ dirtyUrl = url[0]; return typeof dirtyUrl === 'object' && 'url' in dirtyUrl ? dirtyUrl.url : dirtyUrl; } /** * @param {?} target * @param {?} p * @param {?} receiver * @return {?} */ get(target, p, receiver) { InterceptableHttpProxyService._callStack.push(/** @type {?} */ (p)); return receiver; } /** * @param {?} target * @param {?} thisArg * @param {?=} argArray * @return {?} */ apply(target, thisArg, argArray) { const /** @type {?} */ method = InterceptableHttpProxyService._callStack.pop(); // Comply with strict null checks if (!method) { return Observable.empty(); } // create a object without prototype as the context object const /** @type {?} */ context = Object.create(null); return this.httpInterceptorService ._interceptRequest(InterceptableHttpProxyService._extractUrl(argArray), method, argArray, context) .switchMap(args => { // Check for request cancellation if (!args) { return Observable.empty(); } const /** @type {?} */ response = this.http[method].apply(this.http, args); return this.httpInterceptorService._interceptResponse(InterceptableHttpProxyService._extractUrl(args), method, response, context); }); } } InterceptableHttpProxyService._callStack = []; InterceptableHttpProxyService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InterceptableHttpProxyService.ctorParameters = () => [ { type: Http, }, { type: HttpInterceptorService, }, ]; const _proxyTarget = () => null; // Make sure all Http methods are known for Proxy Polyfill Object.keys(Http.prototype).forEach(method => _proxyTarget[method] = `Http.${method}`); /** * @param {?} http * @param {?} interceptor * @return {?} */ function _proxyFactory(http, interceptor) { return safeProxy(_proxyTarget, new InterceptableHttpProxyService(http, interceptor)); } /** * @param {?} backend * @param {?} options * @param {?} interceptor * @return {?} */ function proxyFactory(backend, options, interceptor) { return _proxyFactory(new Http(backend, options), interceptor); } const InterceptableHttpProxyProviders = [ { provide: Http, useFactory: proxyFactory, deps: [XHRBackend, RequestOptions, HttpInterceptorService] }, identityFactory(InterceptableHttpProxyService, Http), ]; const InterceptableHttpProxyNoOverrideProviders = [ { provide: InterceptableHttpProxyService, useFactory: _proxyFactory, deps: [Http, HttpInterceptorService] } ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class InterceptableHttp extends Http { /** * @param {?} _backend * @param {?} _defaultOptions */ constructor(_backend, _defaultOptions) { super(_backend, _defaultOptions); } } InterceptableHttp.decorators = [ { type: Injectable }, ]; /** @nocollapse */ InterceptableHttp.ctorParameters = () => [ { type: ConnectionBackend, }, { type: RequestOptions, }, ]; const InterceptableHttpProviders = [ identityFactory(InterceptableHttp, InterceptableHttpProxyService) ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ const SharedProviders = [ InterceptableStoreFactory, HttpInterceptorService, ...InterceptableHttpProviders ]; const HTTP_INTERCEPTOR_PROVIDER = [ ...SharedProviders, ...InterceptableHttpProxyProviders ]; const HTTP_INTERCEPTOR_NO_OVERRIDE_PROVIDER = [ ...SharedProviders, ...InterceptableHttpProxyNoOverrideProviders ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * \@module * \@description * Library provides Http Interceptor Service for Angular 2 application * By default overrides angular's Http service * To keep original Http service use with {\@see HttpInterceptorModule.noOverrideHttp()} */ class HttpInterceptorModule { /** * Keeps original Http service and adds InterceptableHttp service * Requests made by Http service will not be intercepted - only those made by InterceptableHttp * @return {?} */ static noOverrideHttp() { return { ngModule: HttpInterceptorNoOverrideModule }; } } HttpInterceptorModule.decorators = [ { type: NgModule, args: [{ imports: [HttpModule], providers: [HTTP_INTERCEPTOR_PROVIDER] },] }, ]; /** @nocollapse */ HttpInterceptorModule.ctorParameters = () => []; class HttpInterceptorNoOverrideModule { } HttpInterceptorNoOverrideModule.decorators = [ { type: NgModule, args: [{ imports: [HttpModule], providers: [HTTP_INTERCEPTOR_NO_OVERRIDE_PROVIDER] },] }, ]; /** @nocollapse */ HttpInterceptorNoOverrideModule.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * \@description * Gets index of {\@link RequestOptions} in http data array for specified `method`. * @param {?} method - Http method * @return {?} */ function getHttpOptionsIdx(method) { switch (method) { case 'post': case 'put': case 'patch': return 2; default: return 1; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * \@description * Gets http {\@link RequestOptions} from data array. * If no options found and `alwaysOriginal = false` - returns new {\@link RequestOptions}. * @param {?} data - Array of http data * @param {?} method - Http method * @param {?=} alwaysOriginal - `false` by default * @return {?} */ function getHttpOptions(data, method, alwaysOriginal = false) { return alwaysOriginal ? data[getHttpOptionsIdx(method)] : data[getHttpOptionsIdx(method)] || new RequestOptions(); } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * \@description * Gets {\@link RequestOptions} and it's index location in data array. * If no options found and `alwaysOriginal = false` - creates new {\@link RequestOptions}. * @param {?} data - Array of http data * @param {?} method - Http method * @param {?=} alwaysOriginal - `false` by default * @return {?} */ function getHttpOptionsAndIdx(data, method, alwaysOriginal = false) { return { options: /** @type {?} */ (getHttpOptions(data, method, alwaysOriginal)), idx: getHttpOptionsIdx(method) }; } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * \@description * Gets {\@link Headers} from data array. * If no {\@link RequestOptions} found - creates it and updates original data array. * If no {\@link Headers} found - creates it and sets to {\@link RequestOptions}. * @param {?} data - Array of http data * @param {?} method - Http method * @return {?} */ function getHttpHeadersOrInit(data, method) { const { options, idx } = getHttpOptionsAndIdx(data, method); let /** @type {?} */ headers = options.headers; // Create and update Headers if (!options.headers) { headers = new Headers(); options.headers = headers; } // Set Options back data[idx] = options; return headers; } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @module * @description * Library provides Http Interceptor Service for Angular 2 application * By default overrides angular's Http service * To keep original Http service use with {@see HttpInterceptorModule.noOverrideHttp()} */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Generated bundle index. Do not edit. */ export { HttpInterceptorModule, HttpInterceptorNoOverrideModule, InterceptableHttp, InterceptableHttpProviders, HttpInterceptorService, getHttpOptions, getHttpOptionsIdx, getHttpOptionsAndIdx, getHttpHeadersOrInit, InterceptableHttpProxyNoOverrideProviders as ɵm, InterceptableHttpProxyProviders as ɵl, InterceptableHttpProxyService as ɵh, _proxyFactory as ɵj, _proxyTarget as ɵi, proxyFactory as ɵk, InterceptableStoreFactory as ɵc, HTTP_INTERCEPTOR_NO_OVERRIDE_PROVIDER as ɵb, HTTP_INTERCEPTOR_PROVIDER as ɵa, identityFactory as ɵe, identityFactory_ as ɵd, safeProxy as ɵg, safeProxyHandler_ as ɵf };