@angular/common 17.0.0-next.7 → 17.0.0-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/http/public_api.mjs +1 -1
- package/esm2022/http/src/client.mjs +6 -4
- package/esm2022/http/src/errors.mjs +1 -1
- package/esm2022/http/src/fetch.mjs +3 -3
- package/esm2022/http/src/interceptor.mjs +27 -5
- package/esm2022/http/src/jsonp.mjs +6 -6
- package/esm2022/http/src/module.mjs +12 -12
- package/esm2022/http/src/provider.mjs +14 -1
- package/esm2022/http/src/request.mjs +3 -1
- package/esm2022/http/src/transfer_cache.mjs +73 -18
- package/esm2022/http/src/xhr.mjs +3 -3
- package/esm2022/http/src/xsrf.mjs +6 -6
- package/esm2022/http/testing/src/backend.mjs +3 -3
- package/esm2022/http/testing/src/module.mjs +4 -4
- package/esm2022/src/common_module.mjs +4 -4
- package/esm2022/src/directives/ng_class.mjs +3 -3
- package/esm2022/src/directives/ng_component_outlet.mjs +3 -3
- package/esm2022/src/directives/ng_for_of.mjs +3 -3
- package/esm2022/src/directives/ng_if.mjs +3 -3
- package/esm2022/src/directives/ng_optimized_image/index.mjs +3 -2
- package/esm2022/src/directives/ng_optimized_image/lcp_image_observer.mjs +3 -3
- package/esm2022/src/directives/ng_optimized_image/ng_optimized_image.mjs +6 -16
- package/esm2022/src/directives/ng_optimized_image/preconnect_link_checker.mjs +3 -3
- package/esm2022/src/directives/ng_optimized_image/preload-link-creator.mjs +3 -3
- package/esm2022/src/directives/ng_plural.mjs +6 -6
- package/esm2022/src/directives/ng_style.mjs +3 -3
- package/esm2022/src/directives/ng_switch.mjs +21 -12
- package/esm2022/src/directives/ng_switch_equality.mjs +13 -0
- package/esm2022/src/directives/ng_template_outlet.mjs +3 -3
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/i18n/localization.mjs +6 -6
- package/esm2022/src/location/hash_location_strategy.mjs +3 -3
- package/esm2022/src/location/location.mjs +3 -3
- package/esm2022/src/location/location_strategy.mjs +6 -6
- package/esm2022/src/location/platform_location.mjs +6 -6
- package/esm2022/src/pipes/async_pipe.mjs +3 -3
- package/esm2022/src/pipes/case_conversion_pipes.mjs +9 -9
- package/esm2022/src/pipes/date_pipe.mjs +3 -3
- package/esm2022/src/pipes/date_pipe_config.mjs +1 -1
- package/esm2022/src/pipes/i18n_plural_pipe.mjs +3 -3
- package/esm2022/src/pipes/i18n_select_pipe.mjs +3 -3
- package/esm2022/src/pipes/json_pipe.mjs +3 -3
- package/esm2022/src/pipes/keyvalue_pipe.mjs +3 -3
- package/esm2022/src/pipes/number_pipe.mjs +9 -9
- package/esm2022/src/pipes/slice_pipe.mjs +3 -3
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/location_mock.mjs +3 -3
- package/esm2022/testing/src/mock_location_strategy.mjs +3 -3
- package/esm2022/testing/src/mock_platform_location.mjs +3 -3
- package/esm2022/upgrade/src/location_upgrade_module.mjs +4 -4
- package/fesm2022/common.mjs +134 -131
- package/fesm2022/common.mjs.map +1 -1
- package/fesm2022/http/testing.mjs +8 -8
- package/fesm2022/http.mjs +147 -55
- package/fesm2022/http.mjs.map +1 -1
- package/fesm2022/testing.mjs +10 -10
- package/fesm2022/upgrade.mjs +5 -5
- package/http/index.d.ts +271 -4
- package/http/testing/index.d.ts +1 -1
- package/index.d.ts +7 -22
- package/package.json +3 -2
- package/testing/index.d.ts +1 -1
- package/upgrade/index.d.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.0.0-next.
|
|
2
|
+
* @license Angular v17.0.0-next.8
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -308,10 +308,10 @@ class HttpClientTestingBackend {
|
|
|
308
308
|
return `Match by function: ${matcher.name}`;
|
|
309
309
|
}
|
|
310
310
|
}
|
|
311
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
312
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
311
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
312
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingBackend }); }
|
|
313
313
|
}
|
|
314
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
314
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingBackend, decorators: [{
|
|
315
315
|
type: Injectable
|
|
316
316
|
}] });
|
|
317
317
|
function describeRequest(testRequest) {
|
|
@@ -336,13 +336,13 @@ function provideHttpClientTesting() {
|
|
|
336
336
|
* @publicApi
|
|
337
337
|
*/
|
|
338
338
|
class HttpClientTestingModule {
|
|
339
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
340
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.
|
|
341
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
339
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
340
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingModule, imports: [HttpClientModule] }); }
|
|
341
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingModule, providers: [
|
|
342
342
|
provideHttpClientTesting(),
|
|
343
343
|
], imports: [HttpClientModule] }); }
|
|
344
344
|
}
|
|
345
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientTestingModule, decorators: [{
|
|
346
346
|
type: NgModule,
|
|
347
347
|
args: [{
|
|
348
348
|
imports: [
|
package/fesm2022/http.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.0.0-next.
|
|
2
|
+
* @license Angular v17.0.0-next.8
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as i0 from '@angular/core';
|
|
8
|
-
import { Injectable, inject, NgZone, InjectionToken, ɵInitialRenderPendingTasks, Inject, ɵRuntimeError,
|
|
8
|
+
import { Injectable, inject, NgZone, InjectionToken, ɵInitialRenderPendingTasks, PLATFORM_ID, ɵConsole, ɵformatRuntimeError, Inject, ɵRuntimeError, makeEnvironmentProviders, NgModule, TransferState, makeStateKey, ɵENABLED_SSR_FEATURES, APP_BOOTSTRAP_LISTENER, ApplicationRef, ɵwhenStable, ɵtruncateMiddle } from '@angular/core';
|
|
9
9
|
import { of, Observable, from } from 'rxjs';
|
|
10
10
|
import { concatMap, filter, map, finalize, switchMap, tap } from 'rxjs/operators';
|
|
11
11
|
import * as i1 from '@angular/common';
|
|
12
|
-
import { DOCUMENT, ɵparseCookieValue } from '@angular/common';
|
|
12
|
+
import { isPlatformServer, DOCUMENT, ɵparseCookieValue } from '@angular/common';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Transforms an `HttpRequest` into a stream of `HttpEvent`s, one of which will likely be a
|
|
@@ -771,6 +771,8 @@ class HttpRequest {
|
|
|
771
771
|
if (!!options.params) {
|
|
772
772
|
this.params = options.params;
|
|
773
773
|
}
|
|
774
|
+
// We do want to assign transferCache even if it's falsy (false is valid value)
|
|
775
|
+
this.transferCache = options.transferCache;
|
|
774
776
|
}
|
|
775
777
|
// If no headers have been passed in, construct a new HttpHeaders instance.
|
|
776
778
|
if (!this.headers) {
|
|
@@ -1093,6 +1095,7 @@ function addBody(options, body) {
|
|
|
1093
1095
|
reportProgress: options.reportProgress,
|
|
1094
1096
|
responseType: options.responseType,
|
|
1095
1097
|
withCredentials: options.withCredentials,
|
|
1098
|
+
transferCache: options.transferCache,
|
|
1096
1099
|
};
|
|
1097
1100
|
}
|
|
1098
1101
|
/**
|
|
@@ -1219,6 +1222,7 @@ class HttpClient {
|
|
|
1219
1222
|
// By default, JSON is assumed to be returned for all calls.
|
|
1220
1223
|
responseType: options.responseType || 'json',
|
|
1221
1224
|
withCredentials: options.withCredentials,
|
|
1225
|
+
transferCache: options.transferCache,
|
|
1222
1226
|
});
|
|
1223
1227
|
}
|
|
1224
1228
|
// Start with an Observable.of() the initial request, and run the handler (which
|
|
@@ -1373,10 +1377,10 @@ class HttpClient {
|
|
|
1373
1377
|
put(url, body, options = {}) {
|
|
1374
1378
|
return this.request('PUT', url, addBody(options, body));
|
|
1375
1379
|
}
|
|
1376
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1377
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1380
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClient, deps: [{ token: HttpHandler }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1381
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClient }); }
|
|
1378
1382
|
}
|
|
1379
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClient, decorators: [{
|
|
1380
1384
|
type: Injectable
|
|
1381
1385
|
}], ctorParameters: () => [{ type: HttpHandler }] });
|
|
1382
1386
|
|
|
@@ -1581,10 +1585,10 @@ class FetchBackend {
|
|
|
1581
1585
|
}
|
|
1582
1586
|
return chunksAll;
|
|
1583
1587
|
}
|
|
1584
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1585
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1588
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: FetchBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1589
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: FetchBackend }); }
|
|
1586
1590
|
}
|
|
1587
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1591
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: FetchBackend, decorators: [{
|
|
1588
1592
|
type: Injectable
|
|
1589
1593
|
}] });
|
|
1590
1594
|
/**
|
|
@@ -1663,6 +1667,11 @@ function legacyInterceptorFnFactory() {
|
|
|
1663
1667
|
return chain(req, handler).pipe(finalize(() => pendingTasks.remove(taskId)));
|
|
1664
1668
|
};
|
|
1665
1669
|
}
|
|
1670
|
+
let fetchBackendWarningDisplayed = false;
|
|
1671
|
+
/** Internal function to reset the flag in tests */
|
|
1672
|
+
function resetFetchBackendWarningFlag() {
|
|
1673
|
+
fetchBackendWarningDisplayed = false;
|
|
1674
|
+
}
|
|
1666
1675
|
class HttpInterceptorHandler extends HttpHandler {
|
|
1667
1676
|
constructor(backend, injector) {
|
|
1668
1677
|
super();
|
|
@@ -1675,6 +1684,21 @@ class HttpInterceptorHandler extends HttpHandler {
|
|
|
1675
1684
|
// is used.
|
|
1676
1685
|
const primaryHttpBackend = inject(PRIMARY_HTTP_BACKEND, { optional: true });
|
|
1677
1686
|
this.backend = primaryHttpBackend ?? backend;
|
|
1687
|
+
// We strongly recommend using fetch backend for HTTP calls when SSR is used
|
|
1688
|
+
// for an application. The logic below checks if that's the case and produces
|
|
1689
|
+
// a warning otherwise.
|
|
1690
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) && !fetchBackendWarningDisplayed) {
|
|
1691
|
+
const isServer = isPlatformServer(injector.get(PLATFORM_ID));
|
|
1692
|
+
if (isServer && !(this.backend instanceof FetchBackend)) {
|
|
1693
|
+
fetchBackendWarningDisplayed = true;
|
|
1694
|
+
injector.get(ɵConsole).warn(ɵformatRuntimeError(2801 /* RuntimeErrorCode.NOT_USING_FETCH_BACKEND_IN_SSR */, 'Angular detected that `HttpClient` is not configured ' +
|
|
1695
|
+
'to use `fetch` APIs. It\'s strongly recommended to ' +
|
|
1696
|
+
'enable `fetch` for applications that use Server-Side Rendering ' +
|
|
1697
|
+
'for better performance and compatibility. ' +
|
|
1698
|
+
'To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` ' +
|
|
1699
|
+
'call at the root of the application.'));
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1678
1702
|
}
|
|
1679
1703
|
handle(initialRequest) {
|
|
1680
1704
|
if (this.chain === null) {
|
|
@@ -1692,10 +1716,10 @@ class HttpInterceptorHandler extends HttpHandler {
|
|
|
1692
1716
|
return this.chain(initialRequest, downstreamRequest => this.backend.handle(downstreamRequest))
|
|
1693
1717
|
.pipe(finalize(() => this.pendingTasks.remove(taskId)));
|
|
1694
1718
|
}
|
|
1695
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1696
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1719
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpInterceptorHandler, deps: [{ token: HttpBackend }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1720
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpInterceptorHandler }); }
|
|
1697
1721
|
}
|
|
1698
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1722
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpInterceptorHandler, decorators: [{
|
|
1699
1723
|
type: Injectable
|
|
1700
1724
|
}], ctorParameters: () => [{ type: HttpBackend }, { type: i0.EnvironmentInjector }] });
|
|
1701
1725
|
|
|
@@ -1897,10 +1921,10 @@ class JsonpClientBackend {
|
|
|
1897
1921
|
}
|
|
1898
1922
|
foreignDocument.adoptNode(script);
|
|
1899
1923
|
}
|
|
1900
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1901
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1924
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpClientBackend, deps: [{ token: JsonpCallbackContext }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1925
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpClientBackend }); }
|
|
1902
1926
|
}
|
|
1903
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1927
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpClientBackend, decorators: [{
|
|
1904
1928
|
type: Injectable
|
|
1905
1929
|
}], ctorParameters: () => [{ type: JsonpCallbackContext }, { type: undefined, decorators: [{
|
|
1906
1930
|
type: Inject,
|
|
@@ -1938,10 +1962,10 @@ class JsonpInterceptor {
|
|
|
1938
1962
|
intercept(initialRequest, next) {
|
|
1939
1963
|
return this.injector.runInContext(() => jsonpInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
|
|
1940
1964
|
}
|
|
1941
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1942
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1965
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1966
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpInterceptor }); }
|
|
1943
1967
|
}
|
|
1944
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
1968
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: JsonpInterceptor, decorators: [{
|
|
1945
1969
|
type: Injectable
|
|
1946
1970
|
}], ctorParameters: () => [{ type: i0.EnvironmentInjector }] });
|
|
1947
1971
|
|
|
@@ -2220,10 +2244,10 @@ class HttpXhrBackend {
|
|
|
2220
2244
|
});
|
|
2221
2245
|
}));
|
|
2222
2246
|
}
|
|
2223
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2224
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2247
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXhrBackend, deps: [{ token: i1.XhrFactory }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2248
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXhrBackend }); }
|
|
2225
2249
|
}
|
|
2226
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXhrBackend, decorators: [{
|
|
2227
2251
|
type: Injectable
|
|
2228
2252
|
}], ctorParameters: () => [{ type: i1.XhrFactory }] });
|
|
2229
2253
|
|
|
@@ -2272,10 +2296,10 @@ class HttpXsrfCookieExtractor {
|
|
|
2272
2296
|
}
|
|
2273
2297
|
return this.lastToken;
|
|
2274
2298
|
}
|
|
2275
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2276
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2299
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfCookieExtractor, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: XSRF_COOKIE_NAME }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2300
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfCookieExtractor }); }
|
|
2277
2301
|
}
|
|
2278
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2302
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfCookieExtractor, decorators: [{
|
|
2279
2303
|
type: Injectable
|
|
2280
2304
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
2281
2305
|
type: Inject,
|
|
@@ -2315,10 +2339,10 @@ class HttpXsrfInterceptor {
|
|
|
2315
2339
|
intercept(initialRequest, next) {
|
|
2316
2340
|
return this.injector.runInContext(() => xsrfInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
|
|
2317
2341
|
}
|
|
2318
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2319
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2342
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2343
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfInterceptor }); }
|
|
2320
2344
|
}
|
|
2321
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpXsrfInterceptor, decorators: [{
|
|
2322
2346
|
type: Injectable
|
|
2323
2347
|
}], ctorParameters: () => [{ type: i0.EnvironmentInjector }] });
|
|
2324
2348
|
|
|
@@ -2351,6 +2375,19 @@ function makeHttpFeature(kind, providers) {
|
|
|
2351
2375
|
* feature functions to `provideHttpClient`. For example, HTTP interceptors can be added using the
|
|
2352
2376
|
* `withInterceptors(...)` feature.
|
|
2353
2377
|
*
|
|
2378
|
+
* <div class="alert is-helpful">
|
|
2379
|
+
*
|
|
2380
|
+
* It's strongly recommended to enable
|
|
2381
|
+
* [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for applications that use
|
|
2382
|
+
* Server-Side Rendering for better performance and compatibility. To enable `fetch`, add
|
|
2383
|
+
* `withFetch()` feature to the `provideHttpClient()` call at the root of the application:
|
|
2384
|
+
*
|
|
2385
|
+
* ```
|
|
2386
|
+
* provideHttpClient(withFetch());
|
|
2387
|
+
* ```
|
|
2388
|
+
*
|
|
2389
|
+
* </div>
|
|
2390
|
+
*
|
|
2354
2391
|
* @see {@link withInterceptors}
|
|
2355
2392
|
* @see {@link withInterceptorsFromDi}
|
|
2356
2393
|
* @see {@link withXsrfConfiguration}
|
|
@@ -2576,9 +2613,9 @@ class HttpClientXsrfModule {
|
|
|
2576
2613
|
providers: withXsrfConfiguration(options).ɵproviders,
|
|
2577
2614
|
};
|
|
2578
2615
|
}
|
|
2579
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2580
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.
|
|
2581
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2616
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientXsrfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2617
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientXsrfModule }); }
|
|
2618
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientXsrfModule, providers: [
|
|
2582
2619
|
HttpXsrfInterceptor,
|
|
2583
2620
|
{ provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
|
|
2584
2621
|
{ provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
|
|
@@ -2589,7 +2626,7 @@ class HttpClientXsrfModule {
|
|
|
2589
2626
|
{ provide: XSRF_ENABLED, useValue: true },
|
|
2590
2627
|
] }); }
|
|
2591
2628
|
}
|
|
2592
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2629
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientXsrfModule, decorators: [{
|
|
2593
2630
|
type: NgModule,
|
|
2594
2631
|
args: [{
|
|
2595
2632
|
providers: [
|
|
@@ -2614,13 +2651,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
|
|
|
2614
2651
|
* @publicApi
|
|
2615
2652
|
*/
|
|
2616
2653
|
class HttpClientModule {
|
|
2617
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2618
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.
|
|
2619
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2654
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2655
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientModule }); }
|
|
2656
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientModule, providers: [
|
|
2620
2657
|
provideHttpClient(withInterceptorsFromDi()),
|
|
2621
2658
|
] }); }
|
|
2622
2659
|
}
|
|
2623
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2660
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientModule, decorators: [{
|
|
2624
2661
|
type: NgModule,
|
|
2625
2662
|
args: [{
|
|
2626
2663
|
/**
|
|
@@ -2641,13 +2678,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
|
|
|
2641
2678
|
* @publicApi
|
|
2642
2679
|
*/
|
|
2643
2680
|
class HttpClientJsonpModule {
|
|
2644
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2645
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.
|
|
2646
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2681
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientJsonpModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2682
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientJsonpModule }); }
|
|
2683
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientJsonpModule, providers: [
|
|
2647
2684
|
withJsonpSupport().ɵproviders,
|
|
2648
2685
|
] }); }
|
|
2649
2686
|
}
|
|
2650
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.
|
|
2687
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.8", ngImport: i0, type: HttpClientJsonpModule, decorators: [{
|
|
2651
2688
|
type: NgModule,
|
|
2652
2689
|
args: [{
|
|
2653
2690
|
providers: [
|
|
@@ -2656,23 +2693,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
|
|
|
2656
2693
|
}]
|
|
2657
2694
|
}] });
|
|
2658
2695
|
|
|
2659
|
-
const
|
|
2696
|
+
const CACHE_OPTIONS = new InjectionToken(ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_OPTIONS' : '');
|
|
2660
2697
|
/**
|
|
2661
2698
|
* A list of allowed HTTP methods to cache.
|
|
2662
2699
|
*/
|
|
2663
2700
|
const ALLOWED_METHODS = ['GET', 'HEAD'];
|
|
2664
2701
|
function transferCacheInterceptorFn(req, next) {
|
|
2665
|
-
const { isCacheActive } = inject(
|
|
2666
|
-
|
|
2667
|
-
//
|
|
2668
|
-
if (!isCacheActive ||
|
|
2669
|
-
//
|
|
2670
|
-
|
|
2702
|
+
const { isCacheActive, ...globalOptions } = inject(CACHE_OPTIONS);
|
|
2703
|
+
const { transferCache: requestOptions, method: requestMethod } = req;
|
|
2704
|
+
// In the following situations we do not want to cache the request
|
|
2705
|
+
if (!isCacheActive ||
|
|
2706
|
+
// POST requests are allowed either globally or at request level
|
|
2707
|
+
(requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions) ||
|
|
2708
|
+
(requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod)) ||
|
|
2709
|
+
requestOptions === false || //
|
|
2710
|
+
(globalOptions.filter?.(req)) === false) {
|
|
2671
2711
|
return next(req);
|
|
2672
2712
|
}
|
|
2673
2713
|
const transferState = inject(TransferState);
|
|
2674
2714
|
const storeKey = makeCacheKey(req);
|
|
2675
2715
|
const response = transferState.get(storeKey, null);
|
|
2716
|
+
let headersToInclude = globalOptions.includeHeaders;
|
|
2717
|
+
if (typeof requestOptions === 'object' && requestOptions.includeHeaders) {
|
|
2718
|
+
// Request-specific config takes precedence over the global config.
|
|
2719
|
+
headersToInclude = requestOptions.includeHeaders;
|
|
2720
|
+
}
|
|
2676
2721
|
if (response) {
|
|
2677
2722
|
// Request found in cache. Respond using it.
|
|
2678
2723
|
let body = response.body;
|
|
@@ -2684,9 +2729,19 @@ function transferCacheInterceptorFn(req, next) {
|
|
|
2684
2729
|
body = new Blob([response.body]);
|
|
2685
2730
|
break;
|
|
2686
2731
|
}
|
|
2732
|
+
// We want to warn users accessing a header provided from the cache
|
|
2733
|
+
// That HttpTransferCache alters the headers
|
|
2734
|
+
// The warning will be logged a single time by HttpHeaders instance
|
|
2735
|
+
let headers = new HttpHeaders(response.headers);
|
|
2736
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
2737
|
+
// Append extra logic in dev mode to produce a warning when a header
|
|
2738
|
+
// that was not transferred to the client is accessed in the code via `get`
|
|
2739
|
+
// and `has` calls.
|
|
2740
|
+
headers = appendMissingHeadersDetection(req.url, headers, headersToInclude ?? []);
|
|
2741
|
+
}
|
|
2687
2742
|
return of(new HttpResponse({
|
|
2688
2743
|
body,
|
|
2689
|
-
headers
|
|
2744
|
+
headers,
|
|
2690
2745
|
status: response.status,
|
|
2691
2746
|
statusText: response.statusText,
|
|
2692
2747
|
url: response.url,
|
|
@@ -2697,7 +2752,7 @@ function transferCacheInterceptorFn(req, next) {
|
|
|
2697
2752
|
if (event instanceof HttpResponse) {
|
|
2698
2753
|
transferState.set(storeKey, {
|
|
2699
2754
|
body: event.body,
|
|
2700
|
-
headers:
|
|
2755
|
+
headers: getFilteredHeaders(event.headers, headersToInclude),
|
|
2701
2756
|
status: event.status,
|
|
2702
2757
|
statusText: event.statusText,
|
|
2703
2758
|
url: event.url || '',
|
|
@@ -2706,9 +2761,12 @@ function transferCacheInterceptorFn(req, next) {
|
|
|
2706
2761
|
}
|
|
2707
2762
|
}));
|
|
2708
2763
|
}
|
|
2709
|
-
function
|
|
2764
|
+
function getFilteredHeaders(headers, includeHeaders) {
|
|
2765
|
+
if (!includeHeaders) {
|
|
2766
|
+
return {};
|
|
2767
|
+
}
|
|
2710
2768
|
const headersMap = {};
|
|
2711
|
-
for (const key of
|
|
2769
|
+
for (const key of includeHeaders) {
|
|
2712
2770
|
const values = headers.getAll(key);
|
|
2713
2771
|
if (values !== null) {
|
|
2714
2772
|
headersMap[key] = values;
|
|
@@ -2751,27 +2809,27 @@ function generateHash(value) {
|
|
|
2751
2809
|
* load time.
|
|
2752
2810
|
*
|
|
2753
2811
|
*/
|
|
2754
|
-
function withHttpTransferCache() {
|
|
2812
|
+
function withHttpTransferCache(cacheOptions) {
|
|
2755
2813
|
return [
|
|
2756
2814
|
{
|
|
2757
|
-
provide:
|
|
2815
|
+
provide: CACHE_OPTIONS,
|
|
2758
2816
|
useFactory: () => {
|
|
2759
2817
|
inject(ɵENABLED_SSR_FEATURES).add('httpcache');
|
|
2760
|
-
return { isCacheActive: true };
|
|
2818
|
+
return { isCacheActive: true, ...cacheOptions };
|
|
2761
2819
|
}
|
|
2762
2820
|
},
|
|
2763
2821
|
{
|
|
2764
2822
|
provide: HTTP_ROOT_INTERCEPTOR_FNS,
|
|
2765
2823
|
useValue: transferCacheInterceptorFn,
|
|
2766
2824
|
multi: true,
|
|
2767
|
-
deps: [TransferState,
|
|
2825
|
+
deps: [TransferState, CACHE_OPTIONS]
|
|
2768
2826
|
},
|
|
2769
2827
|
{
|
|
2770
2828
|
provide: APP_BOOTSTRAP_LISTENER,
|
|
2771
2829
|
multi: true,
|
|
2772
2830
|
useFactory: () => {
|
|
2773
2831
|
const appRef = inject(ApplicationRef);
|
|
2774
|
-
const cacheState = inject(
|
|
2832
|
+
const cacheState = inject(CACHE_OPTIONS);
|
|
2775
2833
|
return () => {
|
|
2776
2834
|
ɵwhenStable(appRef).then(() => {
|
|
2777
2835
|
cacheState.isCacheActive = false;
|
|
@@ -2781,6 +2839,40 @@ function withHttpTransferCache() {
|
|
|
2781
2839
|
}
|
|
2782
2840
|
];
|
|
2783
2841
|
}
|
|
2842
|
+
/**
|
|
2843
|
+
* This function will add a proxy to an HttpHeader to intercept calls to get/has
|
|
2844
|
+
* and log a warning if the header entry requested has been removed
|
|
2845
|
+
*/
|
|
2846
|
+
function appendMissingHeadersDetection(url, headers, headersToInclude) {
|
|
2847
|
+
const warningProduced = new Set();
|
|
2848
|
+
return new Proxy(headers, {
|
|
2849
|
+
get(target, prop) {
|
|
2850
|
+
const value = Reflect.get(target, prop);
|
|
2851
|
+
const methods = new Set(['get', 'has', 'getAll']);
|
|
2852
|
+
if (typeof value !== 'function' || !methods.has(prop)) {
|
|
2853
|
+
return value;
|
|
2854
|
+
}
|
|
2855
|
+
return (headerName) => {
|
|
2856
|
+
// We log when the key has been removed and a warning hasn't been produced for the header
|
|
2857
|
+
const key = (prop + ':' + headerName).toLowerCase(); // e.g. `get:cache-control`
|
|
2858
|
+
if (!headersToInclude.includes(headerName) && !warningProduced.has(key)) {
|
|
2859
|
+
warningProduced.add(key);
|
|
2860
|
+
const truncatedUrl = ɵtruncateMiddle(url);
|
|
2861
|
+
// TODO: create Error guide for this warning
|
|
2862
|
+
console.warn(ɵformatRuntimeError(2802 /* RuntimeErrorCode.HEADERS_ALTERED_BY_TRANSFER_CACHE */, `Angular detected that the \`${headerName}\` header is accessed, but the value of the header ` +
|
|
2863
|
+
`was not transferred from the server to the client by the HttpTransferCache. ` +
|
|
2864
|
+
`To include the value of the \`${headerName}\` header for the \`${truncatedUrl}\` request, ` +
|
|
2865
|
+
`use the \`includeHeaders\` list. The \`includeHeaders\` can be defined either ` +
|
|
2866
|
+
`on a request level by adding the \`transferCache\` parameter, or on an application ` +
|
|
2867
|
+
`level by adding the \`httpCacheTransfer.includeHeaders\` argument to the ` +
|
|
2868
|
+
`\`provideClientHydration()\` call. `));
|
|
2869
|
+
}
|
|
2870
|
+
// invoking the original method
|
|
2871
|
+
return value.apply(target, [headerName]);
|
|
2872
|
+
};
|
|
2873
|
+
}
|
|
2874
|
+
});
|
|
2875
|
+
}
|
|
2784
2876
|
|
|
2785
2877
|
// This file is not used to build this module. It is only used during editing
|
|
2786
2878
|
|