@angular/common 17.0.0-next.7 → 17.0.0-rc.0

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.
Files changed (63) hide show
  1. package/esm2022/http/public_api.mjs +1 -1
  2. package/esm2022/http/src/client.mjs +6 -4
  3. package/esm2022/http/src/errors.mjs +1 -1
  4. package/esm2022/http/src/fetch.mjs +4 -5
  5. package/esm2022/http/src/interceptor.mjs +27 -5
  6. package/esm2022/http/src/jsonp.mjs +6 -6
  7. package/esm2022/http/src/module.mjs +12 -12
  8. package/esm2022/http/src/provider.mjs +14 -2
  9. package/esm2022/http/src/request.mjs +3 -1
  10. package/esm2022/http/src/transfer_cache.mjs +73 -18
  11. package/esm2022/http/src/xhr.mjs +3 -3
  12. package/esm2022/http/src/xsrf.mjs +6 -6
  13. package/esm2022/http/testing/src/backend.mjs +3 -3
  14. package/esm2022/http/testing/src/module.mjs +4 -4
  15. package/esm2022/src/common_module.mjs +4 -4
  16. package/esm2022/src/directives/ng_class.mjs +3 -3
  17. package/esm2022/src/directives/ng_component_outlet.mjs +3 -3
  18. package/esm2022/src/directives/ng_for_of.mjs +3 -3
  19. package/esm2022/src/directives/ng_if.mjs +3 -3
  20. package/esm2022/src/directives/ng_optimized_image/index.mjs +3 -2
  21. package/esm2022/src/directives/ng_optimized_image/lcp_image_observer.mjs +3 -3
  22. package/esm2022/src/directives/ng_optimized_image/ng_optimized_image.mjs +6 -16
  23. package/esm2022/src/directives/ng_optimized_image/preconnect_link_checker.mjs +3 -3
  24. package/esm2022/src/directives/ng_optimized_image/preload-link-creator.mjs +3 -3
  25. package/esm2022/src/directives/ng_plural.mjs +6 -6
  26. package/esm2022/src/directives/ng_style.mjs +3 -3
  27. package/esm2022/src/directives/ng_switch.mjs +21 -12
  28. package/esm2022/src/directives/ng_switch_equality.mjs +13 -0
  29. package/esm2022/src/directives/ng_template_outlet.mjs +3 -3
  30. package/esm2022/src/errors.mjs +1 -1
  31. package/esm2022/src/i18n/localization.mjs +6 -6
  32. package/esm2022/src/location/hash_location_strategy.mjs +3 -3
  33. package/esm2022/src/location/location.mjs +3 -3
  34. package/esm2022/src/location/location_strategy.mjs +6 -6
  35. package/esm2022/src/location/platform_location.mjs +6 -6
  36. package/esm2022/src/pipes/async_pipe.mjs +3 -3
  37. package/esm2022/src/pipes/case_conversion_pipes.mjs +9 -9
  38. package/esm2022/src/pipes/date_pipe.mjs +3 -3
  39. package/esm2022/src/pipes/date_pipe_config.mjs +1 -1
  40. package/esm2022/src/pipes/i18n_plural_pipe.mjs +3 -3
  41. package/esm2022/src/pipes/i18n_select_pipe.mjs +3 -3
  42. package/esm2022/src/pipes/json_pipe.mjs +3 -3
  43. package/esm2022/src/pipes/keyvalue_pipe.mjs +3 -3
  44. package/esm2022/src/pipes/number_pipe.mjs +9 -9
  45. package/esm2022/src/pipes/slice_pipe.mjs +3 -3
  46. package/esm2022/src/version.mjs +1 -1
  47. package/esm2022/testing/src/location_mock.mjs +3 -3
  48. package/esm2022/testing/src/mock_location_strategy.mjs +3 -3
  49. package/esm2022/testing/src/mock_platform_location.mjs +3 -3
  50. package/esm2022/upgrade/src/location_upgrade_module.mjs +4 -4
  51. package/fesm2022/common.mjs +134 -131
  52. package/fesm2022/common.mjs.map +1 -1
  53. package/fesm2022/http/testing.mjs +8 -8
  54. package/fesm2022/http.mjs +147 -57
  55. package/fesm2022/http.mjs.map +1 -1
  56. package/fesm2022/testing.mjs +10 -10
  57. package/fesm2022/upgrade.mjs +5 -5
  58. package/http/index.d.ts +271 -6
  59. package/http/testing/index.d.ts +1 -1
  60. package/index.d.ts +7 -22
  61. package/package.json +3 -2
  62. package/testing/index.d.ts +1 -1
  63. package/upgrade/index.d.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v17.0.0-next.7
2
+ * @license Angular v17.0.0-rc.0
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.7", ngImport: i0, type: HttpClientTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
312
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientTestingBackend }); }
311
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
312
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientTestingBackend }); }
313
313
  }
314
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientTestingBackend, decorators: [{
314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", 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.7", ngImport: i0, type: HttpClientTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
340
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientTestingModule, imports: [HttpClientModule] }); }
341
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientTestingModule, providers: [
339
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientTestingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
340
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientTestingModule, imports: [HttpClientModule] }); }
341
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-rc.0", 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.7", ngImport: i0, type: HttpClientTestingModule, decorators: [{
345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", 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.7
2
+ * @license Angular v17.0.0-rc.0
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, PLATFORM_ID, makeEnvironmentProviders, NgModule, TransferState, makeStateKey, ɵENABLED_SSR_FEATURES, APP_BOOTSTRAP_LISTENER, ApplicationRef, ɵwhenStable } from '@angular/core';
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.7", ngImport: i0, type: HttpClient, deps: [{ token: HttpHandler }], target: i0.ɵɵFactoryTarget.Injectable }); }
1377
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClient }); }
1380
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", 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-rc.0", ngImport: i0, type: HttpClient }); }
1378
1382
  }
1379
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClient, decorators: [{
1383
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClient, decorators: [{
1380
1384
  type: Injectable
1381
1385
  }], ctorParameters: () => [{ type: HttpHandler }] });
1382
1386
 
@@ -1404,7 +1408,6 @@ function getResponseUrl$1(response) {
1404
1408
  * @see {@link HttpHandler}
1405
1409
  *
1406
1410
  * @publicApi
1407
- * @developerPreview
1408
1411
  */
1409
1412
  class FetchBackend {
1410
1413
  constructor() {
@@ -1581,10 +1584,10 @@ class FetchBackend {
1581
1584
  }
1582
1585
  return chunksAll;
1583
1586
  }
1584
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: FetchBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1585
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: FetchBackend }); }
1587
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: FetchBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1588
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: FetchBackend }); }
1586
1589
  }
1587
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: FetchBackend, decorators: [{
1590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: FetchBackend, decorators: [{
1588
1591
  type: Injectable
1589
1592
  }] });
1590
1593
  /**
@@ -1663,6 +1666,11 @@ function legacyInterceptorFnFactory() {
1663
1666
  return chain(req, handler).pipe(finalize(() => pendingTasks.remove(taskId)));
1664
1667
  };
1665
1668
  }
1669
+ let fetchBackendWarningDisplayed = false;
1670
+ /** Internal function to reset the flag in tests */
1671
+ function resetFetchBackendWarningFlag() {
1672
+ fetchBackendWarningDisplayed = false;
1673
+ }
1666
1674
  class HttpInterceptorHandler extends HttpHandler {
1667
1675
  constructor(backend, injector) {
1668
1676
  super();
@@ -1675,6 +1683,21 @@ class HttpInterceptorHandler extends HttpHandler {
1675
1683
  // is used.
1676
1684
  const primaryHttpBackend = inject(PRIMARY_HTTP_BACKEND, { optional: true });
1677
1685
  this.backend = primaryHttpBackend ?? backend;
1686
+ // We strongly recommend using fetch backend for HTTP calls when SSR is used
1687
+ // for an application. The logic below checks if that's the case and produces
1688
+ // a warning otherwise.
1689
+ if ((typeof ngDevMode === 'undefined' || ngDevMode) && !fetchBackendWarningDisplayed) {
1690
+ const isServer = isPlatformServer(injector.get(PLATFORM_ID));
1691
+ if (isServer && !(this.backend instanceof FetchBackend)) {
1692
+ fetchBackendWarningDisplayed = true;
1693
+ injector.get(ɵConsole).warn(ɵformatRuntimeError(2801 /* RuntimeErrorCode.NOT_USING_FETCH_BACKEND_IN_SSR */, 'Angular detected that `HttpClient` is not configured ' +
1694
+ 'to use `fetch` APIs. It\'s strongly recommended to ' +
1695
+ 'enable `fetch` for applications that use Server-Side Rendering ' +
1696
+ 'for better performance and compatibility. ' +
1697
+ 'To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` ' +
1698
+ 'call at the root of the application.'));
1699
+ }
1700
+ }
1678
1701
  }
1679
1702
  handle(initialRequest) {
1680
1703
  if (this.chain === null) {
@@ -1692,10 +1715,10 @@ class HttpInterceptorHandler extends HttpHandler {
1692
1715
  return this.chain(initialRequest, downstreamRequest => this.backend.handle(downstreamRequest))
1693
1716
  .pipe(finalize(() => this.pendingTasks.remove(taskId)));
1694
1717
  }
1695
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpInterceptorHandler, deps: [{ token: HttpBackend }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1696
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpInterceptorHandler }); }
1718
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpInterceptorHandler, deps: [{ token: HttpBackend }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1719
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpInterceptorHandler }); }
1697
1720
  }
1698
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpInterceptorHandler, decorators: [{
1721
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpInterceptorHandler, decorators: [{
1699
1722
  type: Injectable
1700
1723
  }], ctorParameters: () => [{ type: HttpBackend }, { type: i0.EnvironmentInjector }] });
1701
1724
 
@@ -1897,10 +1920,10 @@ class JsonpClientBackend {
1897
1920
  }
1898
1921
  foreignDocument.adoptNode(script);
1899
1922
  }
1900
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpClientBackend, deps: [{ token: JsonpCallbackContext }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1901
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpClientBackend }); }
1923
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpClientBackend, deps: [{ token: JsonpCallbackContext }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1924
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpClientBackend }); }
1902
1925
  }
1903
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpClientBackend, decorators: [{
1926
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpClientBackend, decorators: [{
1904
1927
  type: Injectable
1905
1928
  }], ctorParameters: () => [{ type: JsonpCallbackContext }, { type: undefined, decorators: [{
1906
1929
  type: Inject,
@@ -1938,10 +1961,10 @@ class JsonpInterceptor {
1938
1961
  intercept(initialRequest, next) {
1939
1962
  return this.injector.runInContext(() => jsonpInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
1940
1963
  }
1941
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1942
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpInterceptor }); }
1964
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
1965
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpInterceptor }); }
1943
1966
  }
1944
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: JsonpInterceptor, decorators: [{
1967
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: JsonpInterceptor, decorators: [{
1945
1968
  type: Injectable
1946
1969
  }], ctorParameters: () => [{ type: i0.EnvironmentInjector }] });
1947
1970
 
@@ -2220,10 +2243,10 @@ class HttpXhrBackend {
2220
2243
  });
2221
2244
  }));
2222
2245
  }
2223
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXhrBackend, deps: [{ token: i1.XhrFactory }], target: i0.ɵɵFactoryTarget.Injectable }); }
2224
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXhrBackend }); }
2246
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXhrBackend, deps: [{ token: i1.XhrFactory }], target: i0.ɵɵFactoryTarget.Injectable }); }
2247
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXhrBackend }); }
2225
2248
  }
2226
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXhrBackend, decorators: [{
2249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXhrBackend, decorators: [{
2227
2250
  type: Injectable
2228
2251
  }], ctorParameters: () => [{ type: i1.XhrFactory }] });
2229
2252
 
@@ -2272,10 +2295,10 @@ class HttpXsrfCookieExtractor {
2272
2295
  }
2273
2296
  return this.lastToken;
2274
2297
  }
2275
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfCookieExtractor, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: XSRF_COOKIE_NAME }], target: i0.ɵɵFactoryTarget.Injectable }); }
2276
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfCookieExtractor }); }
2298
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfCookieExtractor, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: XSRF_COOKIE_NAME }], target: i0.ɵɵFactoryTarget.Injectable }); }
2299
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfCookieExtractor }); }
2277
2300
  }
2278
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfCookieExtractor, decorators: [{
2301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfCookieExtractor, decorators: [{
2279
2302
  type: Injectable
2280
2303
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2281
2304
  type: Inject,
@@ -2315,10 +2338,10 @@ class HttpXsrfInterceptor {
2315
2338
  intercept(initialRequest, next) {
2316
2339
  return this.injector.runInContext(() => xsrfInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
2317
2340
  }
2318
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2319
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfInterceptor }); }
2341
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfInterceptor, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2342
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfInterceptor }); }
2320
2343
  }
2321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpXsrfInterceptor, decorators: [{
2344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpXsrfInterceptor, decorators: [{
2322
2345
  type: Injectable
2323
2346
  }], ctorParameters: () => [{ type: i0.EnvironmentInjector }] });
2324
2347
 
@@ -2351,6 +2374,19 @@ function makeHttpFeature(kind, providers) {
2351
2374
  * feature functions to `provideHttpClient`. For example, HTTP interceptors can be added using the
2352
2375
  * `withInterceptors(...)` feature.
2353
2376
  *
2377
+ * <div class="alert is-helpful">
2378
+ *
2379
+ * It's strongly recommended to enable
2380
+ * [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for applications that use
2381
+ * Server-Side Rendering for better performance and compatibility. To enable `fetch`, add
2382
+ * `withFetch()` feature to the `provideHttpClient()` call at the root of the application:
2383
+ *
2384
+ * ```
2385
+ * provideHttpClient(withFetch());
2386
+ * ```
2387
+ *
2388
+ * </div>
2389
+ *
2354
2390
  * @see {@link withInterceptors}
2355
2391
  * @see {@link withInterceptorsFromDi}
2356
2392
  * @see {@link withXsrfConfiguration}
@@ -2522,7 +2558,6 @@ function withRequestsMadeViaParent() {
2522
2558
  * Note: The Fetch API doesn't support progress report on uploads.
2523
2559
  *
2524
2560
  * @publicApi
2525
- * @developerPreview
2526
2561
  */
2527
2562
  function withFetch() {
2528
2563
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && typeof fetch !== 'function') {
@@ -2576,9 +2611,9 @@ class HttpClientXsrfModule {
2576
2611
  providers: withXsrfConfiguration(options).ɵproviders,
2577
2612
  };
2578
2613
  }
2579
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientXsrfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2580
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientXsrfModule }); }
2581
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientXsrfModule, providers: [
2614
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientXsrfModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2615
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientXsrfModule }); }
2616
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientXsrfModule, providers: [
2582
2617
  HttpXsrfInterceptor,
2583
2618
  { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
2584
2619
  { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor },
@@ -2589,7 +2624,7 @@ class HttpClientXsrfModule {
2589
2624
  { provide: XSRF_ENABLED, useValue: true },
2590
2625
  ] }); }
2591
2626
  }
2592
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientXsrfModule, decorators: [{
2627
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientXsrfModule, decorators: [{
2593
2628
  type: NgModule,
2594
2629
  args: [{
2595
2630
  providers: [
@@ -2614,13 +2649,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
2614
2649
  * @publicApi
2615
2650
  */
2616
2651
  class HttpClientModule {
2617
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2618
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientModule }); }
2619
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientModule, providers: [
2652
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2653
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientModule }); }
2654
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientModule, providers: [
2620
2655
  provideHttpClient(withInterceptorsFromDi()),
2621
2656
  ] }); }
2622
2657
  }
2623
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientModule, decorators: [{
2658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientModule, decorators: [{
2624
2659
  type: NgModule,
2625
2660
  args: [{
2626
2661
  /**
@@ -2641,13 +2676,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
2641
2676
  * @publicApi
2642
2677
  */
2643
2678
  class HttpClientJsonpModule {
2644
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientJsonpModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2645
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientJsonpModule }); }
2646
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientJsonpModule, providers: [
2679
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientJsonpModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2680
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientJsonpModule }); }
2681
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientJsonpModule, providers: [
2647
2682
  withJsonpSupport().ɵproviders,
2648
2683
  ] }); }
2649
2684
  }
2650
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7", ngImport: i0, type: HttpClientJsonpModule, decorators: [{
2685
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-rc.0", ngImport: i0, type: HttpClientJsonpModule, decorators: [{
2651
2686
  type: NgModule,
2652
2687
  args: [{
2653
2688
  providers: [
@@ -2656,23 +2691,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0-next.7",
2656
2691
  }]
2657
2692
  }] });
2658
2693
 
2659
- const CACHE_STATE = new InjectionToken(ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_STATE' : '');
2694
+ const CACHE_OPTIONS = new InjectionToken(ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_OPTIONS' : '');
2660
2695
  /**
2661
2696
  * A list of allowed HTTP methods to cache.
2662
2697
  */
2663
2698
  const ALLOWED_METHODS = ['GET', 'HEAD'];
2664
2699
  function transferCacheInterceptorFn(req, next) {
2665
- const { isCacheActive } = inject(CACHE_STATE);
2666
- // Stop using the cache if the application has stabilized, indicating initial rendering
2667
- // is complete.
2668
- if (!isCacheActive || !ALLOWED_METHODS.includes(req.method)) {
2669
- // Cache is no longer active or method is not HEAD or GET.
2670
- // Pass the request through.
2700
+ const { isCacheActive, ...globalOptions } = inject(CACHE_OPTIONS);
2701
+ const { transferCache: requestOptions, method: requestMethod } = req;
2702
+ // In the following situations we do not want to cache the request
2703
+ if (!isCacheActive ||
2704
+ // POST requests are allowed either globally or at request level
2705
+ (requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions) ||
2706
+ (requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod)) ||
2707
+ requestOptions === false || //
2708
+ (globalOptions.filter?.(req)) === false) {
2671
2709
  return next(req);
2672
2710
  }
2673
2711
  const transferState = inject(TransferState);
2674
2712
  const storeKey = makeCacheKey(req);
2675
2713
  const response = transferState.get(storeKey, null);
2714
+ let headersToInclude = globalOptions.includeHeaders;
2715
+ if (typeof requestOptions === 'object' && requestOptions.includeHeaders) {
2716
+ // Request-specific config takes precedence over the global config.
2717
+ headersToInclude = requestOptions.includeHeaders;
2718
+ }
2676
2719
  if (response) {
2677
2720
  // Request found in cache. Respond using it.
2678
2721
  let body = response.body;
@@ -2684,9 +2727,19 @@ function transferCacheInterceptorFn(req, next) {
2684
2727
  body = new Blob([response.body]);
2685
2728
  break;
2686
2729
  }
2730
+ // We want to warn users accessing a header provided from the cache
2731
+ // That HttpTransferCache alters the headers
2732
+ // The warning will be logged a single time by HttpHeaders instance
2733
+ let headers = new HttpHeaders(response.headers);
2734
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
2735
+ // Append extra logic in dev mode to produce a warning when a header
2736
+ // that was not transferred to the client is accessed in the code via `get`
2737
+ // and `has` calls.
2738
+ headers = appendMissingHeadersDetection(req.url, headers, headersToInclude ?? []);
2739
+ }
2687
2740
  return of(new HttpResponse({
2688
2741
  body,
2689
- headers: new HttpHeaders(response.headers),
2742
+ headers,
2690
2743
  status: response.status,
2691
2744
  statusText: response.statusText,
2692
2745
  url: response.url,
@@ -2697,7 +2750,7 @@ function transferCacheInterceptorFn(req, next) {
2697
2750
  if (event instanceof HttpResponse) {
2698
2751
  transferState.set(storeKey, {
2699
2752
  body: event.body,
2700
- headers: getHeadersMap(event.headers),
2753
+ headers: getFilteredHeaders(event.headers, headersToInclude),
2701
2754
  status: event.status,
2702
2755
  statusText: event.statusText,
2703
2756
  url: event.url || '',
@@ -2706,9 +2759,12 @@ function transferCacheInterceptorFn(req, next) {
2706
2759
  }
2707
2760
  }));
2708
2761
  }
2709
- function getHeadersMap(headers) {
2762
+ function getFilteredHeaders(headers, includeHeaders) {
2763
+ if (!includeHeaders) {
2764
+ return {};
2765
+ }
2710
2766
  const headersMap = {};
2711
- for (const key of headers.keys()) {
2767
+ for (const key of includeHeaders) {
2712
2768
  const values = headers.getAll(key);
2713
2769
  if (values !== null) {
2714
2770
  headersMap[key] = values;
@@ -2751,27 +2807,27 @@ function generateHash(value) {
2751
2807
  * load time.
2752
2808
  *
2753
2809
  */
2754
- function withHttpTransferCache() {
2810
+ function withHttpTransferCache(cacheOptions) {
2755
2811
  return [
2756
2812
  {
2757
- provide: CACHE_STATE,
2813
+ provide: CACHE_OPTIONS,
2758
2814
  useFactory: () => {
2759
2815
  inject(ɵENABLED_SSR_FEATURES).add('httpcache');
2760
- return { isCacheActive: true };
2816
+ return { isCacheActive: true, ...cacheOptions };
2761
2817
  }
2762
2818
  },
2763
2819
  {
2764
2820
  provide: HTTP_ROOT_INTERCEPTOR_FNS,
2765
2821
  useValue: transferCacheInterceptorFn,
2766
2822
  multi: true,
2767
- deps: [TransferState, CACHE_STATE]
2823
+ deps: [TransferState, CACHE_OPTIONS]
2768
2824
  },
2769
2825
  {
2770
2826
  provide: APP_BOOTSTRAP_LISTENER,
2771
2827
  multi: true,
2772
2828
  useFactory: () => {
2773
2829
  const appRef = inject(ApplicationRef);
2774
- const cacheState = inject(CACHE_STATE);
2830
+ const cacheState = inject(CACHE_OPTIONS);
2775
2831
  return () => {
2776
2832
  ɵwhenStable(appRef).then(() => {
2777
2833
  cacheState.isCacheActive = false;
@@ -2781,6 +2837,40 @@ function withHttpTransferCache() {
2781
2837
  }
2782
2838
  ];
2783
2839
  }
2840
+ /**
2841
+ * This function will add a proxy to an HttpHeader to intercept calls to get/has
2842
+ * and log a warning if the header entry requested has been removed
2843
+ */
2844
+ function appendMissingHeadersDetection(url, headers, headersToInclude) {
2845
+ const warningProduced = new Set();
2846
+ return new Proxy(headers, {
2847
+ get(target, prop) {
2848
+ const value = Reflect.get(target, prop);
2849
+ const methods = new Set(['get', 'has', 'getAll']);
2850
+ if (typeof value !== 'function' || !methods.has(prop)) {
2851
+ return value;
2852
+ }
2853
+ return (headerName) => {
2854
+ // We log when the key has been removed and a warning hasn't been produced for the header
2855
+ const key = (prop + ':' + headerName).toLowerCase(); // e.g. `get:cache-control`
2856
+ if (!headersToInclude.includes(headerName) && !warningProduced.has(key)) {
2857
+ warningProduced.add(key);
2858
+ const truncatedUrl = ɵtruncateMiddle(url);
2859
+ // TODO: create Error guide for this warning
2860
+ console.warn(ɵformatRuntimeError(2802 /* RuntimeErrorCode.HEADERS_ALTERED_BY_TRANSFER_CACHE */, `Angular detected that the \`${headerName}\` header is accessed, but the value of the header ` +
2861
+ `was not transferred from the server to the client by the HttpTransferCache. ` +
2862
+ `To include the value of the \`${headerName}\` header for the \`${truncatedUrl}\` request, ` +
2863
+ `use the \`includeHeaders\` list. The \`includeHeaders\` can be defined either ` +
2864
+ `on a request level by adding the \`transferCache\` parameter, or on an application ` +
2865
+ `level by adding the \`httpCacheTransfer.includeHeaders\` argument to the ` +
2866
+ `\`provideClientHydration()\` call. `));
2867
+ }
2868
+ // invoking the original method
2869
+ return value.apply(target, [headerName]);
2870
+ };
2871
+ }
2872
+ });
2873
+ }
2784
2874
 
2785
2875
  // This file is not used to build this module. It is only used during editing
2786
2876