diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cada398..0eadf4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v2.3.0 + +This release adds the possibility to filter HTTP requests that should not be handled by the interceptor by providing an array of HTTP headers to the component's ``filteredHeaders`` property. + ## v2.2.0 This release adds the possibility to filter HTTP requests that should not be handled by the interceptor by providing an array of HTTP methods to the component's ``filteredMethods`` property. diff --git a/README.md b/README.md index 71e24ed5..7f87a313 100644 --- a/README.md +++ b/README.md @@ -127,18 +127,23 @@ You can define your own loader component in place of the built-in ones. The need You can find some short examples [here](https://gist.github.com/mpalourdio/2c0bec03d610b24ff49db649fbb69a48) and [here](https://gist.github.com/mpalourdio/e05b4495de2abeeecfcf92d70e4ef93e). -## Requests filtering by URL or by HTTP method +## Requests filtering by URL, HTTP method or HTTP headers You can filter the http requests that shouldn't be caught by the interceptor by providing **an array of regex patterns**: ```xml ``` -You can also filter the http requests by providing **an array of HTTP methods** (case insensitive): +You can filter the http requests by providing **an array of HTTP methods** (case insensitive): ```xml ``` +You can also filter the http requests by providing **an array of HTTP headers** (case insensitive): +```xml + +``` + ## Manually show and hide the spinner You can manually show and hide the spinner component if needed. You must use the ``SpinnerVisibilityService`` for this purpose. diff --git a/package.json b/package.json index a7315ff2..66dd570a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ng-http-loader", - "version": "2.2.0", + "version": "2.3.0", "scripts": { "ng": "ng", "build": "ng build", diff --git a/src/lib/components/spinner/spinner.component.ts b/src/lib/components/spinner/spinner.component.ts index de871795..4d3c7029 100644 --- a/src/lib/components/spinner/spinner.component.ts +++ b/src/lib/components/spinner/spinner.component.ts @@ -34,6 +34,8 @@ export class SpinnerComponent implements OnDestroy, OnInit { @Input() public filteredMethods: string[] = []; @Input() + public filteredHeaders: string[] = []; + @Input() public debounceDelay = 0; @Input() public minDuration = 0; @@ -68,6 +70,11 @@ export class SpinnerComponent implements OnDestroy, OnInit { throw new TypeError('`filteredMethods` must be an array.'); } this.pendingInterceptorService.filteredMethods = this.filteredMethods; + + if (!(this.filteredHeaders instanceof Array)) { + throw new TypeError('`filteredHeaders` must be an array.'); + } + this.pendingInterceptorService.filteredHeaders = this.filteredHeaders; } ngOnDestroy(): void { diff --git a/src/lib/services/pending-interceptor.service.ts b/src/lib/services/pending-interceptor.service.ts index cfdcfe9a..0dcb799f 100644 --- a/src/lib/services/pending-interceptor.service.ts +++ b/src/lib/services/pending-interceptor.service.ts @@ -20,6 +20,7 @@ export class PendingInterceptorService implements HttpInterceptor { private _pendingRequestsStatus: ReplaySubject = new ReplaySubject(1); private _filteredUrlPatterns: RegExp[] = []; private _filteredMethods: string[] = []; + private _filteredHeaders: string[] = []; private _forceByPass: boolean; /** @deprecated Deprecated in favor of pendingRequestsStatus$ */ @@ -43,6 +44,10 @@ export class PendingInterceptorService implements HttpInterceptor { this._filteredMethods = httpMethods; } + set filteredHeaders(value: string[]) { + this._filteredHeaders = value; + } + set forceByPass(value: boolean) { this._forceByPass = value; } @@ -59,9 +64,16 @@ export class PendingInterceptorService implements HttpInterceptor { }); } + private shouldBypassHeader(req: HttpRequest): boolean { + return this._filteredHeaders.some(e => { + return req.headers.has(e); + }); + } + private shouldBypass(req: HttpRequest): boolean { return this.shouldBypassUrl(req.urlWithParams) || this.shouldBypassMethod(req) + || this.shouldBypassHeader(req) || this._forceByPass; } diff --git a/src/test/components/spinner/spinner.component.spec.ts b/src/test/components/spinner/spinner.component.spec.ts index 3b88fbd9..248e78b5 100644 --- a/src/test/components/spinner/spinner.component.spec.ts +++ b/src/test/components/spinner/spinner.component.spec.ts @@ -160,6 +160,23 @@ describe('SpinnerComponent', () => { } ))); + it('should not show the spinner if the request is filtered by HTTP header', fakeAsync(inject( + [HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => { + component.filteredHeaders.push('header-to-filter'); + fixture.detectChanges(); + + http.get('/fake', { + headers: { + 'header-to-filter': 'value' + } + }).subscribe(); + + tick(); + expect(component.isSpinnerVisible).toBeFalsy(); + httpMock.expectOne('/fake').flush({}); + } + ))); + it('should take care of query strings in filteredUrlPatterns', fakeAsync(inject( [HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => { component.filteredUrlPatterns.push('bar'); @@ -219,6 +236,30 @@ describe('SpinnerComponent', () => { } ))); + it('should correctly filter by HTTP header with several requests', fakeAsync(inject( + [HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => { + component.filteredHeaders.push('My-HeAdER'); + fixture.detectChanges(); + + http.get('/12345', { + headers: { + 'my-header': 'value' + } + }).subscribe(); + tick(); + expect(component.isSpinnerVisible).toBeFalsy(); + httpMock.expectOne('/12345').flush({}); + + http.get('/fake').subscribe(); + tick(); + expect(component.isSpinnerVisible).toBeTruthy(); + httpMock.expectOne('/fake').flush({}); + + tick(); + expect(component.isSpinnerVisible).toBeFalsy(); + } + ))); + it('should throw an error if filteredUrlPatterns is not an array', () => { component.filteredUrlPatterns = null; expect(() => fixture.detectChanges()).toThrow(new Error('`filteredUrlPatterns` must be an array.')); @@ -229,6 +270,11 @@ describe('SpinnerComponent', () => { expect(() => fixture.detectChanges()).toThrow(new Error('`filteredMethods` must be an array.')); }); + it('should throw an error if filteredHeaders is not an array', () => { + component.filteredHeaders = null; + expect(() => fixture.detectChanges()).toThrow(new Error('`filteredHeaders` must be an array.')); + }); + it('should show the spinner even if the component is created after the HTTP request is performed', fakeAsync(inject( [HttpClient, HttpTestingController], (http: HttpClient, httpMock: HttpTestingController) => { http.get('/fake').subscribe(); diff --git a/src/test/services/pending-interceptor.service.spec.ts b/src/test/services/pending-interceptor.service.spec.ts index 99f675ef..7d43b7a0 100644 --- a/src/test/services/pending-interceptor.service.spec.ts +++ b/src/test/services/pending-interceptor.service.spec.ts @@ -96,9 +96,6 @@ describe('PendingInterceptorService', () => { const testRequest = httpMock.expectOne('/fake'); testRequest.flush({}, { - 'headers': { - 'name': 'useless-header' - }, 'status': 404, 'statusText': statusText }); diff --git a/yarn.lock b/yarn.lock index fda25dda..1085fdd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -206,8 +206,8 @@ "@types/jasmine" "*" "@types/node@*": - version "10.3.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.1.tgz#51092fbacaed768a122a293814474fbf6e5e8b6d" + version "10.3.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.2.tgz#3840ec6c12556fdda6e0e6d036df853101d732a4" "@types/node@~8.9.4": version "8.9.5" @@ -372,6 +372,13 @@ ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" +ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + ajv@^5.0.0, ajv@^5.1.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" @@ -382,12 +389,12 @@ ajv@^5.0.0, ajv@^5.1.0: json-schema-traverse "^0.3.0" ajv@^6.1.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.0.tgz#4c8affdf80887d8f132c9c52ab8a2dc4d0b7b24c" + version "6.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.1.tgz#88ebc1263c7133937d108b80c5572e64e1d9322d" dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" + json-schema-traverse "^0.4.1" uri-js "^4.2.1" ajv@~6.4.0: @@ -638,11 +645,11 @@ atob@^2.1.1: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" autoprefixer@^8.0.0, autoprefixer@^8.4.1: - version "8.6.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-8.6.1.tgz#cb186e6c904cd54a4af7bda078fd27a1fddc7be5" + version "8.6.2" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-8.6.2.tgz#51d42ff13243820a582a53ecca20dedaeb7f2efd" dependencies: browserslist "^3.2.8" - caniuse-lite "^1.0.30000850" + caniuse-lite "^1.0.30000851" normalize-range "^0.1.2" num2fraction "^1.2.2" postcss "^6.0.22" @@ -1116,9 +1123,9 @@ camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000850: - version "1.0.30000850" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000850.tgz#e68a88db4ea598b4c33b8419f7385473e4802495" +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000851: + version "1.0.30000852" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000852.tgz#8b7510cec030cac7842e52beca2bf292af65f935" capture-stack-trace@^1.0.0: version "1.0.0" @@ -1308,14 +1315,14 @@ collection-visit@^1.0.0: object-visit "^1.0.0" color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" dependencies: - color-name "^1.1.1" + color-name "1.1.1" -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" colors@1.1.2: version "1.1.2" @@ -1350,8 +1357,8 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" compare-versions@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.2.1.tgz#a49eb7689d4caaf0b6db5220173fd279614000f7" + version "3.3.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" component-bind@1.0.0: version "1.0.0" @@ -2106,8 +2113,8 @@ escodegen@1.8.x: source-map "~0.2.0" escodegen@1.x.x: - version "1.9.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + version "1.10.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.10.0.tgz#f647395de22519fbd0d928ffcf1d17e0dec2603e" dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -2816,6 +2823,10 @@ handlebars@^4.0.1, handlebars@^4.0.3: optionalDependencies: uglify-js "^2.6" +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -2829,6 +2840,13 @@ har-validator@~2.0.6: is-my-json-valid "^2.12.4" pinkie-promise "^2.0.0" +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + har-validator@~5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" @@ -2913,8 +2931,8 @@ hash-base@^3.0.0: safe-buffer "^5.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" + version "1.1.4" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.4.tgz#8b50e1f35d51bd01e5ed9ece4dbe3549ccfa0a3c" dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.0" @@ -3111,8 +3129,8 @@ iconv-lite@0.4.23, iconv-lite@^0.4.4: safer-buffer ">= 2.1.2 < 3" ieee754@^1.1.4: - version "1.1.11" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.11.tgz#c16384ffe00f5b7835824e67b6f2bd44a5229455" + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" iferr@^0.1.5: version "0.1.5" @@ -3658,10 +3676,20 @@ json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + json-stringify-safe@5.0.x, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -4404,18 +4432,17 @@ node-forge@0.7.5: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" node-gyp@^3.3.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" + version "3.7.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.7.0.tgz#789478e8f6c45e277aa014f3e28f958f286f9203" dependencies: fstream "^1.0.0" glob "^7.0.3" graceful-fs "^4.1.2" - minimatch "^3.0.2" mkdirp "^0.5.0" nopt "2 || 3" npmlog "0 || 1 || 2 || 3 || 4" osenv "0" - request "2" + request ">=2.9.0 <2.82.0" rimraf "2" semver "~5.3.0" tar "^2.0.0" @@ -4994,6 +5021,10 @@ pend@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -5258,6 +5289,10 @@ qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -5533,31 +5568,6 @@ request-progress@^2.0.1: dependencies: throttleit "^1.0.0" -request@2, request@^2.0.0, request@^2.74.0, request@^2.79.0, request@^2.81.0, request@^2.83.0: - version "2.87.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - request@2.75.x: version "2.75.0" resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" @@ -5584,6 +5594,58 @@ request@2.75.x: tough-cookie "~2.3.0" tunnel-agent "~0.4.1" +"request@>=2.9.0 <2.82.0": + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@^2.0.0, request@^2.74.0, request@^2.79.0, request@^2.81.0, request@^2.83.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + request@~2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de"