@angular/router 14.1.0-next.3 → 14.1.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 (41) hide show
  1. package/esm2020/src/apply_redirects.mjs +14 -8
  2. package/esm2020/src/components/empty_outlet.mjs +3 -3
  3. package/esm2020/src/create_url_tree.mjs +6 -4
  4. package/esm2020/src/directives/router_link.mjs +6 -6
  5. package/esm2020/src/directives/router_link_active.mjs +3 -3
  6. package/esm2020/src/directives/router_outlet.mjs +10 -9
  7. package/esm2020/src/errors.mjs +2 -0
  8. package/esm2020/src/events.mjs +22 -4
  9. package/esm2020/src/index.mjs +1 -1
  10. package/esm2020/src/models.mjs +1 -1
  11. package/esm2020/src/navigation_canceling_error.mjs +32 -0
  12. package/esm2020/src/operators/check_guards.mjs +16 -49
  13. package/esm2020/src/operators/prioritized_guard_value.mjs +22 -27
  14. package/esm2020/src/operators/recognize.mjs +1 -1
  15. package/esm2020/src/page_title_strategy.mjs +11 -5
  16. package/esm2020/src/recognize.mjs +4 -3
  17. package/esm2020/src/router.mjs +88 -85
  18. package/esm2020/src/router_config_loader.mjs +3 -3
  19. package/esm2020/src/router_module.mjs +52 -18
  20. package/esm2020/src/router_preloader.mjs +9 -9
  21. package/esm2020/src/router_scroller.mjs +3 -3
  22. package/esm2020/src/shared.mjs +1 -10
  23. package/esm2020/src/url_tree.mjs +9 -4
  24. package/esm2020/src/utils/config.mjs +17 -17
  25. package/esm2020/src/utils/type_guards.mjs +9 -5
  26. package/esm2020/src/version.mjs +1 -1
  27. package/esm2020/testing/src/router_testing_module.mjs +10 -12
  28. package/fesm2015/router.mjs +304 -246
  29. package/fesm2015/router.mjs.map +1 -1
  30. package/fesm2015/testing.mjs +10 -12
  31. package/fesm2015/testing.mjs.map +1 -1
  32. package/fesm2015/upgrade.mjs +1 -1
  33. package/fesm2020/router.mjs +307 -250
  34. package/fesm2020/router.mjs.map +1 -1
  35. package/fesm2020/testing.mjs +10 -12
  36. package/fesm2020/testing.mjs.map +1 -1
  37. package/fesm2020/upgrade.mjs +1 -1
  38. package/index.d.ts +79 -7
  39. package/package.json +4 -4
  40. package/testing/index.d.ts +2 -3
  41. package/upgrade/index.d.ts +1 -1
@@ -1,15 +1,15 @@
1
1
  /**
2
- * @license Angular v14.1.0-next.3
2
+ * @license Angular v14.1.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 { ɵisObservable, ɵisPromise, EventEmitter, Directive, Attribute, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, InjectionToken, InjectFlags, NgModuleFactory, Injectable, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, Input, HostListener, HostBinding, Optional, ContentChildren, Injector, Compiler, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Inject, ApplicationRef, ENVIRONMENT_INITIALIZER, Version } from '@angular/core';
8
+ import { ɵisObservable, ɵisPromise, ɵRuntimeError, EventEmitter, Directive, Attribute, Output, Component, createEnvironmentInjector, ɵisStandalone, ComponentFactoryResolver, InjectionToken, InjectFlags, NgModuleFactory, Injectable, NgModuleRef, ɵConsole, NgZone, ɵcoerceToBoolean, Input, HostListener, HostBinding, Optional, ContentChildren, inject, Injector, Compiler, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Inject, ApplicationRef, ENVIRONMENT_INITIALIZER, Version } from '@angular/core';
9
9
  import { from, of, BehaviorSubject, combineLatest, concat, defer, pipe, throwError, EmptyError, Observable, EMPTY, ConnectableObservable, Subject } from 'rxjs';
10
10
  import * as i3 from '@angular/common';
11
11
  import { Location, LocationStrategy, HashLocationStrategy, PathLocationStrategy, ViewportScroller, LOCATION_INITIALIZED } from '@angular/common';
12
- import { map, switchMap, take, startWith, scan, filter, mergeMap, first, concatMap, tap, catchError, last as last$1, takeWhile, defaultIfEmpty, takeLast, mapTo, finalize, refCount, mergeAll } from 'rxjs/operators';
12
+ import { map, switchMap, take, startWith, filter, mergeMap, first, concatMap, tap, catchError, scan, last as last$1, takeWhile, defaultIfEmpty, takeLast, mapTo, finalize, refCount, mergeAll } from 'rxjs/operators';
13
13
  import * as i1 from '@angular/platform-browser';
14
14
 
15
15
  /**
@@ -60,15 +60,6 @@ class ParamsAsMap {
60
60
  function convertToParamMap(params) {
61
61
  return new ParamsAsMap(params);
62
62
  }
63
- const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
64
- function navigationCancelingError(message) {
65
- const error = Error('NavigationCancelingError: ' + message);
66
- error[NAVIGATION_CANCELING_ERROR] = true;
67
- return error;
68
- }
69
- function isNavigationCancelingError(error) {
70
- return error && error[NAVIGATION_CANCELING_ERROR];
71
- }
72
63
  // Matches the route configuration (`route`) against the actual URL (`segments`).
73
64
  function defaultUrlMatcher(segments, segmentGroup, route) {
74
65
  const parts = route.path.split('/');
@@ -191,6 +182,7 @@ function wrapIntoObservable(value) {
191
182
  * Use of this source code is governed by an MIT-style license that can be
192
183
  * found in the LICENSE file at https://angular.io/license
193
184
  */
185
+ const NG_DEV_MODE$7 = typeof ngDevMode === 'undefined' || ngDevMode;
194
186
  function createEmptyUrlTree() {
195
187
  return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
196
188
  }
@@ -655,7 +647,7 @@ class UrlParser {
655
647
  parseSegment() {
656
648
  const path = matchSegments(this.remaining);
657
649
  if (path === '' && this.peekStartsWith(';')) {
658
- throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);
650
+ throw new ɵRuntimeError(4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, NG_DEV_MODE$7 && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
659
651
  }
660
652
  this.capture(path);
661
653
  return new UrlSegment(decode(path), this.parseMatrixParams());
@@ -724,7 +716,7 @@ class UrlParser {
724
716
  // if is is not one of these characters, then the segment was unescaped
725
717
  // or the group was not closed
726
718
  if (next !== '/' && next !== ')' && next !== ';') {
727
- throw new Error(`Cannot parse url '${this.url}'`);
719
+ throw new ɵRuntimeError(4010 /* RuntimeErrorCode.UNPARSABLE_URL */, NG_DEV_MODE$7 && `Cannot parse url '${this.url}'`);
728
720
  }
729
721
  let outletName = undefined;
730
722
  if (path.indexOf(':') > -1) {
@@ -755,7 +747,7 @@ class UrlParser {
755
747
  }
756
748
  capture(str) {
757
749
  if (!this.consumeOptional(str)) {
758
- throw new Error(`Expected "${str}".`);
750
+ throw new ɵRuntimeError(4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, NG_DEV_MODE$7 && `Expected "${str}".`);
759
751
  }
760
752
  }
761
753
  }
@@ -797,6 +789,9 @@ function mergeTrivialChildren(s) {
797
789
  }
798
790
  return s;
799
791
  }
792
+ function isUrlTree(v) {
793
+ return v instanceof UrlTree;
794
+ }
800
795
 
801
796
  /**
802
797
  * @license
@@ -805,6 +800,7 @@ function mergeTrivialChildren(s) {
805
800
  * Use of this source code is governed by an MIT-style license that can be
806
801
  * found in the LICENSE file at https://angular.io/license
807
802
  */
803
+ const NG_DEV_MODE$6 = typeof ngDevMode === 'undefined' || ngDevMode;
808
804
  /**
809
805
  * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`.
810
806
  *
@@ -980,11 +976,11 @@ class Navigation {
980
976
  this.numberOfDoubleDots = numberOfDoubleDots;
981
977
  this.commands = commands;
982
978
  if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
983
- throw new Error('Root segment cannot have matrix parameters');
979
+ throw new ɵRuntimeError(4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, NG_DEV_MODE$6 && 'Root segment cannot have matrix parameters');
984
980
  }
985
981
  const cmdWithOutlet = commands.find(isCommandWithOutlets);
986
982
  if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
987
- throw new Error('{outlets:{}} has to be the last command');
983
+ throw new ɵRuntimeError(4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, NG_DEV_MODE$6 && '{outlets:{}} has to be the last command');
988
984
  }
989
985
  }
990
986
  toRoot() {
@@ -1083,7 +1079,7 @@ function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
1083
1079
  dd -= ci;
1084
1080
  g = g.parent;
1085
1081
  if (!g) {
1086
- throw new Error('Invalid number of \'../\'');
1082
+ throw new ɵRuntimeError(4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, NG_DEV_MODE$6 && 'Invalid number of \'../\'');
1087
1083
  }
1088
1084
  ci = g.segments.length;
1089
1085
  }
@@ -1338,10 +1334,20 @@ class NavigationCancel extends RouterEvent {
1338
1334
  id,
1339
1335
  /** @docsNotRequired */
1340
1336
  url,
1341
- /** @docsNotRequired */
1342
- reason) {
1337
+ /**
1338
+ * A description of why the navigation was cancelled. For debug purposes only. Use `code`
1339
+ * instead for a stable cancellation reason that can be used in production.
1340
+ */
1341
+ reason,
1342
+ /**
1343
+ * A code to indicate why the navigation was canceled. This cancellation code is stable for
1344
+ * the reason and can be relied on whereas the `reason` string could change and should not be
1345
+ * used in production.
1346
+ */
1347
+ code) {
1343
1348
  super(id, url);
1344
1349
  this.reason = reason;
1350
+ this.code = code;
1345
1351
  this.type = 2 /* EventType.NavigationCancel */;
1346
1352
  }
1347
1353
  /** @docsNotRequired */
@@ -1365,9 +1371,17 @@ class NavigationError extends RouterEvent {
1365
1371
  /** @docsNotRequired */
1366
1372
  url,
1367
1373
  /** @docsNotRequired */
1368
- error) {
1374
+ error,
1375
+ /**
1376
+ * The target of the navigation when the error occurred.
1377
+ *
1378
+ * Note that this can be `undefined` because an error could have occurred before the
1379
+ * `RouterStateSnapshot` was created for the navigation.
1380
+ */
1381
+ target) {
1369
1382
  super(id, url);
1370
1383
  this.error = error;
1384
+ this.target = target;
1371
1385
  this.type = 3 /* EventType.NavigationError */;
1372
1386
  }
1373
1387
  /** @docsNotRequired */
@@ -2229,6 +2243,37 @@ function createActivatedRoute(c) {
2229
2243
  return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
2230
2244
  }
2231
2245
 
2246
+ /**
2247
+ * @license
2248
+ * Copyright Google LLC All Rights Reserved.
2249
+ *
2250
+ * Use of this source code is governed by an MIT-style license that can be
2251
+ * found in the LICENSE file at https://angular.io/license
2252
+ */
2253
+ const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
2254
+ function redirectingNavigationError(urlSerializer, redirect) {
2255
+ const { redirectTo, navigationBehaviorOptions } = isUrlTree(redirect) ? { redirectTo: redirect, navigationBehaviorOptions: undefined } : redirect;
2256
+ const error = navigationCancelingError(ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`, 0 /* NavigationCancellationCode.Redirect */, redirect);
2257
+ error.url = redirectTo;
2258
+ error.navigationBehaviorOptions = navigationBehaviorOptions;
2259
+ return error;
2260
+ }
2261
+ function navigationCancelingError(message, code, redirectUrl) {
2262
+ const error = new Error('NavigationCancelingError: ' + (message || ''));
2263
+ error[NAVIGATION_CANCELING_ERROR] = true;
2264
+ error.cancellationCode = code;
2265
+ if (redirectUrl) {
2266
+ error.url = redirectUrl;
2267
+ }
2268
+ return error;
2269
+ }
2270
+ function isRedirectingNavigationCancelingError$1(error) {
2271
+ return isNavigationCancelingError$1(error) && isUrlTree(error.url);
2272
+ }
2273
+ function isNavigationCancelingError$1(error) {
2274
+ return error && error[NAVIGATION_CANCELING_ERROR];
2275
+ }
2276
+
2232
2277
  /**
2233
2278
  * @license
2234
2279
  * Copyright Google LLC All Rights Reserved.
@@ -2315,6 +2360,7 @@ class ChildrenOutletContexts {
2315
2360
  * Use of this source code is governed by an MIT-style license that can be
2316
2361
  * found in the LICENSE file at https://angular.io/license
2317
2362
  */
2363
+ const NG_DEV_MODE$5 = typeof ngDevMode === 'undefined' || ngDevMode;
2318
2364
  /**
2319
2365
  * @description
2320
2366
  *
@@ -2423,12 +2469,12 @@ class RouterOutlet {
2423
2469
  */
2424
2470
  get component() {
2425
2471
  if (!this.activated)
2426
- throw new Error('Outlet is not activated');
2472
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$5 && 'Outlet is not activated');
2427
2473
  return this.activated.instance;
2428
2474
  }
2429
2475
  get activatedRoute() {
2430
2476
  if (!this.activated)
2431
- throw new Error('Outlet is not activated');
2477
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$5 && 'Outlet is not activated');
2432
2478
  return this._activatedRoute;
2433
2479
  }
2434
2480
  get activatedRouteData() {
@@ -2442,7 +2488,7 @@ class RouterOutlet {
2442
2488
  */
2443
2489
  detach() {
2444
2490
  if (!this.activated)
2445
- throw new Error('Outlet is not activated');
2491
+ throw new ɵRuntimeError(4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, NG_DEV_MODE$5 && 'Outlet is not activated');
2446
2492
  this.location.detach();
2447
2493
  const cmp = this.activated;
2448
2494
  this.activated = null;
@@ -2470,7 +2516,7 @@ class RouterOutlet {
2470
2516
  }
2471
2517
  activateWith(activatedRoute, resolverOrInjector) {
2472
2518
  if (this.isActivated) {
2473
- throw new Error('Cannot activate an already activated outlet');
2519
+ throw new ɵRuntimeError(4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, NG_DEV_MODE$5 && 'Cannot activate an already activated outlet');
2474
2520
  }
2475
2521
  this._activatedRoute = activatedRoute;
2476
2522
  const location = this.location;
@@ -2492,9 +2538,9 @@ class RouterOutlet {
2492
2538
  this.activateEvents.emit(this.activated.instance);
2493
2539
  }
2494
2540
  }
2495
- RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
2496
- RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
2497
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterOutlet, decorators: [{
2541
+ RouterOutlet.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterOutlet, deps: [{ token: ChildrenOutletContexts }, { token: i0.ViewContainerRef }, { token: 'name', attribute: true }, { token: i0.ChangeDetectorRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Directive });
2542
+ RouterOutlet.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: RouterOutlet, selector: "router-outlet", outputs: { activateEvents: "activate", deactivateEvents: "deactivate", attachEvents: "attach", detachEvents: "detach" }, exportAs: ["outlet"], ngImport: i0 });
2543
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterOutlet, decorators: [{
2498
2544
  type: Directive,
2499
2545
  args: [{ selector: 'router-outlet', exportAs: 'outlet' }]
2500
2546
  }], ctorParameters: function () { return [{ type: ChildrenOutletContexts }, { type: i0.ViewContainerRef }, { type: undefined, decorators: [{
@@ -2551,9 +2597,9 @@ function isComponentFactoryResolver(item) {
2551
2597
  */
2552
2598
  class ɵEmptyOutletComponent {
2553
2599
  }
2554
- ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2555
- ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0-next.3", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2600
+ ɵEmptyOutletComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: ɵEmptyOutletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2601
+ ɵEmptyOutletComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.1.0", type: ɵEmptyOutletComponent, selector: "ng-component", ngImport: i0, template: `<router-outlet></router-outlet>`, isInline: true, dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
2602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: ɵEmptyOutletComponent, decorators: [{
2557
2603
  type: Component,
2558
2604
  args: [{ template: `<router-outlet></router-outlet>` }]
2559
2605
  }] });
@@ -2602,13 +2648,13 @@ function validateConfig(config, parentPath = '', requireStandaloneComponents = f
2602
2648
  }
2603
2649
  function assertStandalone(fullPath, component) {
2604
2650
  if (component && !ɵisStandalone(component)) {
2605
- throw new Error(`Invalid configuration of route '${fullPath}'. The component must be standalone.`);
2651
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}'. The component must be standalone.`);
2606
2652
  }
2607
2653
  }
2608
2654
  function validateNode(route, fullPath, requireStandaloneComponents) {
2609
2655
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
2610
2656
  if (!route) {
2611
- throw new Error(`
2657
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `
2612
2658
  Invalid configuration of route '${fullPath}': Encountered undefined route.
2613
2659
  The reason might be an extra comma.
2614
2660
 
@@ -2621,47 +2667,47 @@ function validateNode(route, fullPath, requireStandaloneComponents) {
2621
2667
  `);
2622
2668
  }
2623
2669
  if (Array.isArray(route)) {
2624
- throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
2670
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': Array cannot be specified`);
2625
2671
  }
2626
2672
  if (!route.component && !route.loadComponent && !route.children && !route.loadChildren &&
2627
2673
  (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
2628
- throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
2674
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
2629
2675
  }
2630
2676
  if (route.redirectTo && route.children) {
2631
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
2677
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
2632
2678
  }
2633
2679
  if (route.redirectTo && route.loadChildren) {
2634
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
2680
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
2635
2681
  }
2636
2682
  if (route.children && route.loadChildren) {
2637
- throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
2683
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
2638
2684
  }
2639
2685
  if (route.redirectTo && (route.component || route.loadComponent)) {
2640
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
2686
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
2641
2687
  }
2642
2688
  if (route.component && route.loadComponent) {
2643
- throw new Error(`Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
2689
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
2644
2690
  }
2645
2691
  if (route.redirectTo && route.canActivate) {
2646
- throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
2692
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` +
2647
2693
  `so canActivate will never be executed.`);
2648
2694
  }
2649
2695
  if (route.path && route.matcher) {
2650
- throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
2696
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
2651
2697
  }
2652
2698
  if (route.redirectTo === void 0 && !route.component && !route.loadComponent &&
2653
2699
  !route.children && !route.loadChildren) {
2654
- throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
2700
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
2655
2701
  }
2656
2702
  if (route.path === void 0 && route.matcher === void 0) {
2657
- throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
2703
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
2658
2704
  }
2659
2705
  if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
2660
- throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
2706
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': path cannot start with a slash`);
2661
2707
  }
2662
2708
  if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
2663
2709
  const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
2664
- throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
2710
+ throw new ɵRuntimeError(4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
2665
2711
  }
2666
2712
  if (requireStandaloneComponents) {
2667
2713
  assertStandalone(fullPath, route.component);
@@ -3089,9 +3135,6 @@ function isFunction(v) {
3089
3135
  function isBoolean(v) {
3090
3136
  return typeof v === 'boolean';
3091
3137
  }
3092
- function isUrlTree(v) {
3093
- return v instanceof UrlTree;
3094
- }
3095
3138
  function isCanLoad(guard) {
3096
3139
  return guard && isFunction(guard.canLoad);
3097
3140
  }
@@ -3107,6 +3150,12 @@ function isCanDeactivate(guard) {
3107
3150
  function isCanMatch(guard) {
3108
3151
  return guard && isFunction(guard.canMatch);
3109
3152
  }
3153
+ function isRedirectingNavigationCancelingError(error) {
3154
+ return isNavigationCancelingError(error) && isUrlTree(error.url);
3155
+ }
3156
+ function isNavigationCancelingError(error) {
3157
+ return error && error[NAVIGATION_CANCELING_ERROR];
3158
+ }
3110
3159
 
3111
3160
  /**
3112
3161
  * @license
@@ -3119,31 +3168,26 @@ const INITIAL_VALUE = Symbol('INITIAL_VALUE');
3119
3168
  function prioritizedGuardValue() {
3120
3169
  return switchMap(obs => {
3121
3170
  return combineLatest(obs.map(o => o.pipe(take(1), startWith(INITIAL_VALUE))))
3122
- .pipe(scan((acc, list) => {
3123
- let isPending = false;
3124
- return list.reduce((innerAcc, val, i) => {
3125
- if (innerAcc !== INITIAL_VALUE)
3126
- return innerAcc;
3127
- // Toggle pending flag if any values haven't been set yet
3128
- if (val === INITIAL_VALUE)
3129
- isPending = true;
3130
- // Any other return values are only valid if we haven't yet hit a pending
3131
- // call. This guarantees that in the case of a guard at the bottom of the
3132
- // tree that returns a redirect, we will wait for the higher priority
3133
- // guard at the top to finish before performing the redirect.
3134
- if (!isPending) {
3135
- // Early return when we hit a `false` value as that should always
3136
- // cancel navigation
3137
- if (val === false)
3138
- return val;
3139
- if (i === list.length - 1 || isUrlTree(val)) {
3140
- return val;
3141
- }
3171
+ .pipe(map((results) => {
3172
+ for (const result of results) {
3173
+ if (result === true) {
3174
+ // If result is true, check the next one
3175
+ continue;
3176
+ }
3177
+ else if (result === INITIAL_VALUE) {
3178
+ // If guard has not finished, we need to stop processing.
3179
+ return INITIAL_VALUE;
3142
3180
  }
3143
- return innerAcc;
3144
- }, acc);
3145
- }, INITIAL_VALUE), filter(item => item !== INITIAL_VALUE), map(item => isUrlTree(item) ? item : item === true), //
3146
- take(1));
3181
+ else if (result === false || result instanceof UrlTree) {
3182
+ // Result finished and was not true. Return the result.
3183
+ // Note that we only allow false/UrlTree. Other values are considered invalid and
3184
+ // ignored.
3185
+ return result;
3186
+ }
3187
+ }
3188
+ // Everything resolved to true. Return true.
3189
+ return true;
3190
+ }), filter((item) => item !== INITIAL_VALUE), take(1));
3147
3191
  });
3148
3192
  }
3149
3193
 
@@ -3215,17 +3259,9 @@ function runCanActivate(futureRSS, futureARS, moduleInjector) {
3215
3259
  const canActivateObservables = canActivate.map((c) => {
3216
3260
  return defer(() => {
3217
3261
  const guard = getToken(c, futureARS, moduleInjector);
3218
- let observable;
3219
- if (isCanActivate(guard)) {
3220
- observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
3221
- }
3222
- else if (isFunction(guard)) {
3223
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
3224
- }
3225
- else {
3226
- throw new Error('Invalid CanActivate guard');
3227
- }
3228
- return observable.pipe(first());
3262
+ const guardVal = isCanActivate(guard) ? guard.canActivate(futureARS, futureRSS) :
3263
+ guard(futureARS, futureRSS);
3264
+ return wrapIntoObservable(guardVal).pipe(first());
3229
3265
  });
3230
3266
  });
3231
3267
  return of(canActivateObservables).pipe(prioritizedGuardValue());
@@ -3240,17 +3276,9 @@ function runCanActivateChild(futureRSS, path, moduleInjector) {
3240
3276
  return defer(() => {
3241
3277
  const guardsMapped = d.guards.map((c) => {
3242
3278
  const guard = getToken(c, d.node, moduleInjector);
3243
- let observable;
3244
- if (isCanActivateChild(guard)) {
3245
- observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
3246
- }
3247
- else if (isFunction(guard)) {
3248
- observable = wrapIntoObservable(guard(futureARS, futureRSS));
3249
- }
3250
- else {
3251
- throw new Error('Invalid CanActivateChild guard');
3252
- }
3253
- return observable.pipe(first());
3279
+ const guardVal = isCanActivateChild(guard) ? guard.canActivateChild(futureARS, futureRSS) :
3280
+ guard(futureARS, futureRSS);
3281
+ return wrapIntoObservable(guardVal).pipe(first());
3254
3282
  });
3255
3283
  return of(guardsMapped).pipe(prioritizedGuardValue());
3256
3284
  });
@@ -3263,17 +3291,10 @@ function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector
3263
3291
  return of(true);
3264
3292
  const canDeactivateObservables = canDeactivate.map((c) => {
3265
3293
  const guard = getToken(c, currARS, moduleInjector);
3266
- let observable;
3267
- if (isCanDeactivate(guard)) {
3268
- observable = wrapIntoObservable(guard.canDeactivate(component, currARS, currRSS, futureRSS));
3269
- }
3270
- else if (isFunction(guard)) {
3271
- observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
3272
- }
3273
- else {
3274
- throw new Error('Invalid CanDeactivate guard');
3275
- }
3276
- return observable.pipe(first());
3294
+ const guardVal = isCanDeactivate(guard) ?
3295
+ guard.canDeactivate(component, currARS, currRSS, futureRSS) :
3296
+ guard(component, currARS, currRSS, futureRSS);
3297
+ return wrapIntoObservable(guardVal).pipe(first());
3277
3298
  });
3278
3299
  return of(canDeactivateObservables).pipe(prioritizedGuardValue());
3279
3300
  }
@@ -3284,16 +3305,7 @@ function runCanLoadGuards(injector, route, segments, urlSerializer) {
3284
3305
  }
3285
3306
  const canLoadObservables = canLoad.map((injectionToken) => {
3286
3307
  const guard = injector.get(injectionToken);
3287
- let guardVal;
3288
- if (isCanLoad(guard)) {
3289
- guardVal = guard.canLoad(route, segments);
3290
- }
3291
- else if (isFunction(guard)) {
3292
- guardVal = guard(route, segments);
3293
- }
3294
- else {
3295
- throw new Error('Invalid CanLoad guard');
3296
- }
3308
+ const guardVal = isCanLoad(guard) ? guard.canLoad(route, segments) : guard(route, segments);
3297
3309
  return wrapIntoObservable(guardVal);
3298
3310
  });
3299
3311
  return of(canLoadObservables)
@@ -3303,9 +3315,7 @@ function redirectIfUrlTree(urlSerializer) {
3303
3315
  return pipe(tap((result) => {
3304
3316
  if (!isUrlTree(result))
3305
3317
  return;
3306
- const error = navigationCancelingError(`Redirecting to "${urlSerializer.serialize(result)}"`);
3307
- error.url = result;
3308
- throw error;
3318
+ throw redirectingNavigationError(urlSerializer, result);
3309
3319
  }), map(result => result === true));
3310
3320
  }
3311
3321
  function runCanMatchGuards(injector, route, segments, urlSerializer) {
@@ -3483,6 +3493,7 @@ function noLeftoversInUrl(segmentGroup, segments, outlet) {
3483
3493
  * Use of this source code is governed by an MIT-style license that can be
3484
3494
  * found in the LICENSE file at https://angular.io/license
3485
3495
  */
3496
+ const NG_DEV_MODE$4 = typeof ngDevMode === 'undefined' || ngDevMode;
3486
3497
  class NoMatch$1 {
3487
3498
  constructor(segmentGroup) {
3488
3499
  this.segmentGroup = segmentGroup || null;
@@ -3500,10 +3511,12 @@ function absoluteRedirect(newTree) {
3500
3511
  return throwError(new AbsoluteRedirect(newTree));
3501
3512
  }
3502
3513
  function namedOutletsRedirect(redirectTo) {
3503
- return throwError(new Error(`Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3514
+ return throwError(new ɵRuntimeError(4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, NG_DEV_MODE$4 &&
3515
+ `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
3504
3516
  }
3505
3517
  function canLoadFails(route) {
3506
- return throwError(navigationCancelingError(`Cannot load children because the guard of the route "path: '${route.path}'" returned false`));
3518
+ return throwError(navigationCancelingError(NG_DEV_MODE$4 &&
3519
+ `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, 3 /* NavigationCancellationCode.GuardRejected */));
3507
3520
  }
3508
3521
  /**
3509
3522
  * Returns the `UrlTree` with the redirection applied.
@@ -3562,7 +3575,7 @@ class ApplyRedirects {
3562
3575
  }));
3563
3576
  }
3564
3577
  noMatchError(e) {
3565
- return new Error(`Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3578
+ return new ɵRuntimeError(4002 /* RuntimeErrorCode.NO_MATCH */, NG_DEV_MODE$4 && `Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
3566
3579
  }
3567
3580
  createUrlTree(rootCandidate, queryParams, fragment) {
3568
3581
  const root = createRoot(rootCandidate);
@@ -3742,9 +3755,9 @@ class ApplyRedirects {
3742
3755
  }
3743
3756
  }
3744
3757
  applyRedirectCommands(segments, redirectTo, posParams) {
3745
- return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3758
+ return this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
3746
3759
  }
3747
- applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
3760
+ applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
3748
3761
  const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
3749
3762
  return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
3750
3763
  }
@@ -3777,7 +3790,8 @@ class ApplyRedirects {
3777
3790
  findPosParam(redirectTo, redirectToUrlSegment, posParams) {
3778
3791
  const pos = posParams[redirectToUrlSegment.path.substring(1)];
3779
3792
  if (!pos)
3780
- throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3793
+ throw new ɵRuntimeError(4001 /* RuntimeErrorCode.MISSING_REDIRECT */, NG_DEV_MODE$4 &&
3794
+ `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
3781
3795
  return pos;
3782
3796
  }
3783
3797
  findOrReturn(redirectToUrlSegment, actualSegments) {
@@ -3901,7 +3915,7 @@ class Recognizer {
3901
3915
  // multiple activated results for the same outlet. We should merge the children of
3902
3916
  // these results so the final return value is only one `TreeNode` per outlet.
3903
3917
  const mergedChildren = mergeEmptyPathMatches(children);
3904
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
3918
+ if (NG_DEV_MODE$3) {
3905
3919
  // This should really never happen - we are only taking the first match for each
3906
3920
  // outlet and merge the empty path matches.
3907
3921
  checkOutletNameUniqueness(mergedChildren);
@@ -4063,7 +4077,7 @@ function checkOutletNameUniqueness(nodes) {
4063
4077
  if (routeWithSameOutletName) {
4064
4078
  const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
4065
4079
  const c = n.value.url.map(s => s.toString()).join('/');
4066
- throw new Error(`Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
4080
+ throw new ɵRuntimeError(4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, NG_DEV_MODE$3 && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
4067
4081
  }
4068
4082
  names[n.value.outlet] = n.value;
4069
4083
  });
@@ -4369,9 +4383,9 @@ class RouterConfigLoader {
4369
4383
  }));
4370
4384
  }
4371
4385
  }
4372
- RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4373
- RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader });
4374
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterConfigLoader, decorators: [{
4386
+ RouterConfigLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterConfigLoader, deps: [{ token: i0.Injector }, { token: i0.Compiler }], target: i0.ɵɵFactoryTarget.Injectable });
4387
+ RouterConfigLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterConfigLoader });
4388
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterConfigLoader, decorators: [{
4375
4389
  type: Injectable
4376
4390
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.Compiler }]; } });
4377
4391
 
@@ -4628,10 +4642,11 @@ class Router {
4628
4642
  // Extract URL
4629
4643
  map(t => ({ ...t, extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) })),
4630
4644
  // Using switchMap so we cancel executing navigations when a new one comes in
4631
- switchMap(t => {
4645
+ switchMap(overallTransitionState => {
4632
4646
  let completed = false;
4633
4647
  let errored = false;
4634
- return of(t).pipe(
4648
+ return of(overallTransitionState)
4649
+ .pipe(
4635
4650
  // Store the Navigation object
4636
4651
  tap(t => {
4637
4652
  this.currentNavigation = {
@@ -4650,8 +4665,8 @@ class Router {
4650
4665
  t.extractedUrl.toString() !== browserUrlTree ||
4651
4666
  // Navigations which succeed or ones which fail and are cleaned up
4652
4667
  // correctly should result in `browserUrlTree` and `currentUrlTree`
4653
- // matching. If this is not the case, assume something went wrong and try
4654
- // processing the URL again.
4668
+ // matching. If this is not the case, assume something went wrong and
4669
+ // try processing the URL again.
4655
4670
  browserUrlTree !== this.currentUrlTree.toString();
4656
4671
  const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
4657
4672
  this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
@@ -4682,11 +4697,13 @@ class Router {
4682
4697
  ...this.currentNavigation,
4683
4698
  finalUrl: t.urlAfterRedirects
4684
4699
  };
4700
+ overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
4685
4701
  }),
4686
4702
  // Recognize
4687
4703
  recognize(this.ngModule.injector, this.rootComponentType, this.config, this.urlSerializer, this.paramsInheritanceStrategy, this.relativeLinkResolution),
4688
4704
  // Update URL if in `eager` update mode
4689
4705
  tap(t => {
4706
+ overallTransitionState.targetSnapshot = t.targetSnapshot;
4690
4707
  if (this.urlUpdateStrategy === 'eager') {
4691
4708
  if (!t.extras.skipLocationChange) {
4692
4709
  const rawUrl = this.urlHandlingStrategy.merge(t.urlAfterRedirects, t.rawUrl);
@@ -4702,26 +4719,27 @@ class Router {
4702
4719
  else {
4703
4720
  const processPreviousUrl = urlTransition && this.rawUrlTree &&
4704
4721
  this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
4705
- /* When the current URL shouldn't be processed, but the previous one was,
4706
- * we handle this "error condition" by navigating to the previously
4707
- * successful URL, but leaving the URL intact.*/
4722
+ /* When the current URL shouldn't be processed, but the previous one
4723
+ * was, we handle this "error condition" by navigating to the
4724
+ * previously successful URL, but leaving the URL intact.*/
4708
4725
  if (processPreviousUrl) {
4709
4726
  const { id, extractedUrl, source, restoredState, extras } = t;
4710
4727
  const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
4711
4728
  eventsSubject.next(navStart);
4712
4729
  const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
4713
- return of({
4730
+ overallTransitionState = {
4714
4731
  ...t,
4715
4732
  targetSnapshot,
4716
4733
  urlAfterRedirects: extractedUrl,
4717
4734
  extras: { ...extras, skipLocationChange: false, replaceUrl: false },
4718
- });
4735
+ };
4736
+ return of(overallTransitionState);
4719
4737
  }
4720
4738
  else {
4721
- /* When neither the current or previous URL can be processed, do nothing
4722
- * other than update router's internal reference to the current "settled"
4723
- * URL. This way the next navigation will be coming from the current URL
4724
- * in the browser.
4739
+ /* When neither the current or previous URL can be processed, do
4740
+ * nothing other than update router's internal reference to the
4741
+ * current "settled" URL. This way the next navigation will be coming
4742
+ * from the current URL in the browser.
4725
4743
  */
4726
4744
  this.rawUrlTree = t.rawUrl;
4727
4745
  t.resolve(null);
@@ -4733,21 +4751,23 @@ class Router {
4733
4751
  tap(t => {
4734
4752
  const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot);
4735
4753
  this.triggerEvent(guardsStart);
4736
- }), map(t => ({
4737
- ...t,
4738
- guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
4739
- })), checkGuards(this.ngModule.injector, (evt) => this.triggerEvent(evt)), tap(t => {
4754
+ }), map(t => {
4755
+ overallTransitionState = {
4756
+ ...t,
4757
+ guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
4758
+ };
4759
+ return overallTransitionState;
4760
+ }), checkGuards(this.ngModule.injector, (evt) => this.triggerEvent(evt)), tap(t => {
4761
+ overallTransitionState.guardsResult = t.guardsResult;
4740
4762
  if (isUrlTree(t.guardsResult)) {
4741
- const error = navigationCancelingError(`Redirecting to "${this.serializeUrl(t.guardsResult)}"`);
4742
- error.url = t.guardsResult;
4743
- throw error;
4763
+ throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
4744
4764
  }
4745
4765
  const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
4746
4766
  this.triggerEvent(guardsEnd);
4747
4767
  }), filter(t => {
4748
4768
  if (!t.guardsResult) {
4749
4769
  this.restoreHistory(t);
4750
- this.cancelNavigationTransition(t, '');
4770
+ this.cancelNavigationTransition(t, '', 3 /* NavigationCancellationCode.GuardRejected */);
4751
4771
  return false;
4752
4772
  }
4753
4773
  return true;
@@ -4765,7 +4785,9 @@ class Router {
4765
4785
  complete: () => {
4766
4786
  if (!dataResolved) {
4767
4787
  this.restoreHistory(t);
4768
- this.cancelNavigationTransition(t, `At least one route resolver didn't emit any value.`);
4788
+ this.cancelNavigationTransition(t, NG_DEV_MODE$1 ?
4789
+ `At least one route resolver didn't emit any value.` :
4790
+ '', 2 /* NavigationCancellationCode.NoDataFromResolver */);
4769
4791
  }
4770
4792
  }
4771
4793
  }));
@@ -4775,7 +4797,7 @@ class Router {
4775
4797
  }));
4776
4798
  }
4777
4799
  return undefined;
4778
- }), switchTap(() => this.afterPreactivation()),
4800
+ }),
4779
4801
  // --- LOAD COMPONENTS ---
4780
4802
  switchTap((t) => {
4781
4803
  const loadComponents = (route) => {
@@ -4794,15 +4816,16 @@ class Router {
4794
4816
  };
4795
4817
  return combineLatest(loadComponents(t.targetSnapshot.root))
4796
4818
  .pipe(defaultIfEmpty(), take(1));
4797
- }), map((t) => {
4819
+ }), switchTap(() => this.afterPreactivation()), map((t) => {
4798
4820
  const targetRouterState = createRouterState(this.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
4799
- return ({ ...t, targetRouterState });
4821
+ overallTransitionState = { ...t, targetRouterState };
4822
+ return (overallTransitionState);
4800
4823
  }),
4801
- /* Once here, we are about to activate syncronously. The assumption is this
4802
- will succeed, and user code may read from the Router service. Therefore
4803
- before activation, we need to update router properties storing the current
4804
- URL and the RouterState, as well as updated the browser URL. All this should
4805
- happen *before* activating. */
4824
+ /* Once here, we are about to activate synchronously. The assumption is
4825
+ this will succeed, and user code may read from the Router service.
4826
+ Therefore before activation, we need to update router properties storing
4827
+ the current URL and the RouterState, as well as updated the browser URL.
4828
+ All this should happen *before* activating. */
4806
4829
  tap((t) => {
4807
4830
  this.currentUrlTree = t.urlAfterRedirects;
4808
4831
  this.rawUrlTree =
@@ -4822,80 +4845,75 @@ class Router {
4822
4845
  completed = true;
4823
4846
  }
4824
4847
  }), finalize(() => {
4825
- /* When the navigation stream finishes either through error or success, we
4826
- * set the `completed` or `errored` flag. However, there are some situations
4827
- * where we could get here without either of those being set. For instance, a
4828
- * redirect during NavigationStart. Therefore, this is a catch-all to make
4829
- * sure the NavigationCancel
4830
- * event is fired when a navigation gets cancelled but not caught by other
4831
- * means. */
4848
+ /* When the navigation stream finishes either through error or success,
4849
+ * we set the `completed` or `errored` flag. However, there are some
4850
+ * situations where we could get here without either of those being set.
4851
+ * For instance, a redirect during NavigationStart. Therefore, this is a
4852
+ * catch-all to make sure the NavigationCancel event is fired when a
4853
+ * navigation gets cancelled but not caught by other means. */
4832
4854
  if (!completed && !errored) {
4833
- const cancelationReason = `Navigation ID ${t.id} is not equal to the current navigation id ${this.navigationId}`;
4834
- this.cancelNavigationTransition(t, cancelationReason);
4855
+ const cancelationReason = NG_DEV_MODE$1 ?
4856
+ `Navigation ID ${overallTransitionState
4857
+ .id} is not equal to the current navigation id ${this.navigationId}` :
4858
+ '';
4859
+ this.cancelNavigationTransition(overallTransitionState, cancelationReason, 1 /* NavigationCancellationCode.SupersededByNewNavigation */);
4835
4860
  }
4836
4861
  // Only clear current navigation if it is still set to the one that
4837
4862
  // finalized.
4838
- if (this.currentNavigation?.id === t.id) {
4863
+ if (this.currentNavigation?.id === overallTransitionState.id) {
4839
4864
  this.currentNavigation = null;
4840
4865
  }
4841
4866
  }), catchError((e) => {
4842
- // TODO(atscott): The NavigationTransition `t` used here does not accurately
4843
- // reflect the current state of the whole transition because some operations
4844
- // return a new object rather than modifying the one in the outermost
4845
- // `switchMap`.
4846
- // The fix can likely be to:
4847
- // 1. Rename the outer `t` variable so it's not shadowed all the time and
4848
- // confusing
4849
- // 2. Keep reassigning to the outer variable after each stage to ensure it
4850
- // gets updated. Or change the implementations to not return a copy.
4851
- // Not changed yet because it affects existing code and would need to be
4852
- // tested more thoroughly.
4853
4867
  errored = true;
4854
4868
  /* This error type is issued during Redirect, and is handled as a
4855
4869
  * cancellation rather than an error. */
4856
- if (isNavigationCancelingError(e)) {
4857
- const redirecting = isUrlTree(e.url);
4858
- if (!redirecting) {
4859
- // Set property only if we're not redirecting. If we landed on a page and
4860
- // redirect to `/` route, the new navigation is going to see the `/`
4861
- // isn't a change from the default currentUrlTree and won't navigate.
4862
- // This is only applicable with initial navigation, so setting
4863
- // `navigated` only when not redirecting resolves this scenario.
4870
+ if (isNavigationCancelingError$1(e)) {
4871
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4872
+ // Set property only if we're not redirecting. If we landed on a page
4873
+ // and redirect to `/` route, the new navigation is going to see the
4874
+ // `/` isn't a change from the default currentUrlTree and won't
4875
+ // navigate. This is only applicable with initial navigation, so
4876
+ // setting `navigated` only when not redirecting resolves this
4877
+ // scenario.
4864
4878
  this.navigated = true;
4865
- this.restoreHistory(t, true);
4879
+ this.restoreHistory(overallTransitionState, true);
4866
4880
  }
4867
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), e.message);
4881
+ const navCancel = new NavigationCancel(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e.message, e.cancellationCode);
4868
4882
  eventsSubject.next(navCancel);
4869
4883
  // When redirecting, we need to delay resolving the navigation
4870
4884
  // promise and push it to the redirect navigation
4871
- if (!redirecting) {
4872
- t.resolve(false);
4885
+ if (!isRedirectingNavigationCancelingError$1(e)) {
4886
+ overallTransitionState.resolve(false);
4873
4887
  }
4874
4888
  else {
4875
4889
  const mergedTree = this.urlHandlingStrategy.merge(e.url, this.rawUrlTree);
4876
4890
  const extras = {
4877
- skipLocationChange: t.extras.skipLocationChange,
4891
+ skipLocationChange: overallTransitionState.extras.skipLocationChange,
4878
4892
  // The URL is already updated at this point if we have 'eager' URL
4879
4893
  // updates or if the navigation was triggered by the browser (back
4880
- // button, URL bar, etc). We want to replace that item in history if
4881
- // the navigation is rejected.
4894
+ // button, URL bar, etc). We want to replace that item in history
4895
+ // if the navigation is rejected.
4882
4896
  replaceUrl: this.urlUpdateStrategy === 'eager' ||
4883
- isBrowserTriggeredNavigation(t.source)
4897
+ isBrowserTriggeredNavigation(overallTransitionState.source)
4884
4898
  };
4885
- this.scheduleNavigation(mergedTree, 'imperative', null, extras, { resolve: t.resolve, reject: t.reject, promise: t.promise });
4899
+ this.scheduleNavigation(mergedTree, 'imperative', null, extras, {
4900
+ resolve: overallTransitionState.resolve,
4901
+ reject: overallTransitionState.reject,
4902
+ promise: overallTransitionState.promise
4903
+ });
4886
4904
  }
4887
- /* All other errors should reset to the router's internal URL reference to
4888
- * the pre-error state. */
4905
+ /* All other errors should reset to the router's internal URL reference
4906
+ * to the pre-error state. */
4889
4907
  }
4890
4908
  else {
4891
- this.restoreHistory(t, true);
4892
- const navError = new NavigationError(t.id, this.serializeUrl(t.extractedUrl), e);
4909
+ this.restoreHistory(overallTransitionState, true);
4910
+ const navError = new NavigationError(overallTransitionState.id, this.serializeUrl(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined);
4893
4911
  eventsSubject.next(navError);
4894
4912
  try {
4895
- t.resolve(this.errorHandler(e));
4913
+ overallTransitionState.resolve(this.errorHandler(e));
4896
4914
  }
4897
4915
  catch (ee) {
4898
- t.reject(ee);
4916
+ overallTransitionState.reject(ee);
4899
4917
  }
4900
4918
  }
4901
4919
  return EMPTY;
@@ -5289,7 +5307,7 @@ class Router {
5289
5307
  // The navigator change the location before triggered the browser event,
5290
5308
  // so we need to go back to the current url if the navigation is canceled.
5291
5309
  // Also, when navigation gets cancelled while using url update strategy eager, then we need to
5292
- // go back. Because, when `urlUpdateSrategy` is `eager`; `setBrowserUrl` method is called
5310
+ // go back. Because, when `urlUpdateStrategy` is `eager`; `setBrowserUrl` method is called
5293
5311
  // before any verification.
5294
5312
  const browserUrlUpdateOccurred = (t.source === 'popstate' || this.urlUpdateStrategy === 'eager' ||
5295
5313
  this.currentUrlTree === this.currentNavigation?.finalUrl);
@@ -5335,8 +5353,8 @@ class Router {
5335
5353
  resetUrlToCurrentUrlTree() {
5336
5354
  this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
5337
5355
  }
5338
- cancelNavigationTransition(t, reason) {
5339
- const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason);
5356
+ cancelNavigationTransition(t, reason, code) {
5357
+ const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), reason, code);
5340
5358
  this.triggerEvent(navCancel);
5341
5359
  t.resolve(false);
5342
5360
  }
@@ -5347,16 +5365,16 @@ class Router {
5347
5365
  return { navigationId };
5348
5366
  }
5349
5367
  }
5350
- Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5351
- Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router });
5352
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: Router, decorators: [{
5368
+ Router.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: Router, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
5369
+ Router.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: Router });
5370
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: Router, decorators: [{
5353
5371
  type: Injectable
5354
5372
  }], ctorParameters: function () { return [{ type: i0.Type }, { type: UrlSerializer }, { type: ChildrenOutletContexts }, { type: i3.Location }, { type: i0.Injector }, { type: i0.Compiler }, { type: undefined }]; } });
5355
5373
  function validateCommands(commands) {
5356
5374
  for (let i = 0; i < commands.length; i++) {
5357
5375
  const cmd = commands[i];
5358
5376
  if (cmd == null) {
5359
- throw new Error(`The requested path contains ${cmd} segment at index ${i}`);
5377
+ throw new ɵRuntimeError(4008 /* RuntimeErrorCode.NULLISH_COMMAND */, NG_DEV_MODE$1 && `The requested path contains ${cmd} segment at index ${i}`);
5360
5378
  }
5361
5379
  }
5362
5380
  }
@@ -5548,9 +5566,9 @@ class RouterLink {
5548
5566
  });
5549
5567
  }
5550
5568
  }
5551
- RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
5552
- RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
5553
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLink, decorators: [{
5569
+ RouterLink.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLink, deps: [{ token: Router }, { token: ActivatedRoute }, { token: 'tabindex', attribute: true }, { token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
5570
+ RouterLink.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: RouterLink, selector: ":not(a):not(area)[routerLink]", inputs: { queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick()" } }, usesOnChanges: true, ngImport: i0 });
5571
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLink, decorators: [{
5554
5572
  type: Directive,
5555
5573
  args: [{ selector: ':not(a):not(area)[routerLink]' }]
5556
5574
  }], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: undefined, decorators: [{
@@ -5667,9 +5685,9 @@ class RouterLinkWithHref {
5667
5685
  });
5668
5686
  }
5669
5687
  }
5670
- RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
5671
- RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
5672
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkWithHref, decorators: [{
5688
+ RouterLinkWithHref.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLinkWithHref, deps: [{ token: Router }, { token: ActivatedRoute }, { token: i3.LocationStrategy }], target: i0.ɵɵFactoryTarget.Directive });
5689
+ RouterLinkWithHref.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: { target: "target", queryParams: "queryParams", fragment: "fragment", queryParamsHandling: "queryParamsHandling", preserveFragment: "preserveFragment", skipLocationChange: "skipLocationChange", replaceUrl: "replaceUrl", state: "state", relativeTo: "relativeTo", routerLink: "routerLink" }, host: { listeners: { "click": "onClick($event.button,$event.ctrlKey,$event.shiftKey,$event.altKey,$event.metaKey)" }, properties: { "attr.target": "this.target", "attr.href": "this.href" } }, usesOnChanges: true, ngImport: i0 });
5690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLinkWithHref, decorators: [{
5673
5691
  type: Directive,
5674
5692
  args: [{ selector: 'a[routerLink],area[routerLink]' }]
5675
5693
  }], ctorParameters: function () { return [{ type: Router }, { type: ActivatedRoute }, { type: i3.LocationStrategy }]; }, propDecorators: { target: [{
@@ -5894,9 +5912,9 @@ class RouterLinkActive {
5894
5912
  this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
5895
5913
  }
5896
5914
  }
5897
- RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
5898
- RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0-next.3", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
5899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterLinkActive, decorators: [{
5915
+ RouterLinkActive.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLinkActive, deps: [{ token: Router }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: RouterLink, optional: true }, { token: RouterLinkWithHref, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
5916
+ RouterLinkActive.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: { routerLinkActiveOptions: "routerLinkActiveOptions", ariaCurrentWhenActive: "ariaCurrentWhenActive", routerLinkActive: "routerLinkActive" }, outputs: { isActiveChange: "isActiveChange" }, queries: [{ propertyName: "links", predicate: RouterLink, descendants: true }, { propertyName: "linksWithHrefs", predicate: RouterLinkWithHref, descendants: true }], exportAs: ["routerLinkActive"], usesOnChanges: true, ngImport: i0 });
5917
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterLinkActive, decorators: [{
5900
5918
  type: Directive,
5901
5919
  args: [{
5902
5920
  selector: '[routerLinkActive]',
@@ -5979,6 +5997,12 @@ class TitleStrategy {
5979
5997
  return snapshot.data[RouteTitle];
5980
5998
  }
5981
5999
  }
6000
+ TitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: TitleStrategy, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6001
+ TitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: TitleStrategy, providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) });
6002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: TitleStrategy, decorators: [{
6003
+ type: Injectable,
6004
+ args: [{ providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy) }]
6005
+ }] });
5982
6006
  /**
5983
6007
  * The default `TitleStrategy` used by the router that updates the title using the `Title` service.
5984
6008
  */
@@ -5999,9 +6023,9 @@ class DefaultTitleStrategy extends TitleStrategy {
5999
6023
  }
6000
6024
  }
6001
6025
  }
6002
- DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
6003
- DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
6004
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
6026
+ DefaultTitleStrategy.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: DefaultTitleStrategy, deps: [{ token: i1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
6027
+ DefaultTitleStrategy.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: DefaultTitleStrategy, providedIn: 'root' });
6028
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: DefaultTitleStrategy, decorators: [{
6005
6029
  type: Injectable,
6006
6030
  args: [{ providedIn: 'root' }]
6007
6031
  }], ctorParameters: function () { return [{ type: i1.Title }]; } });
@@ -6038,9 +6062,9 @@ class PreloadAllModules {
6038
6062
  return fn().pipe(catchError(() => of(null)));
6039
6063
  }
6040
6064
  }
6041
- PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6042
- PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6043
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: PreloadAllModules, decorators: [{
6065
+ PreloadAllModules.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PreloadAllModules, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6066
+ PreloadAllModules.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PreloadAllModules, providedIn: 'root' });
6067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: PreloadAllModules, decorators: [{
6044
6068
  type: Injectable,
6045
6069
  args: [{ providedIn: 'root' }]
6046
6070
  }] });
@@ -6058,9 +6082,9 @@ class NoPreloading {
6058
6082
  return of(null);
6059
6083
  }
6060
6084
  }
6061
- NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6062
- NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6063
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: NoPreloading, decorators: [{
6085
+ NoPreloading.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: NoPreloading, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
6086
+ NoPreloading.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: NoPreloading, providedIn: 'root' });
6087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: NoPreloading, decorators: [{
6064
6088
  type: Injectable,
6065
6089
  args: [{ providedIn: 'root' }]
6066
6090
  }] });
@@ -6146,9 +6170,9 @@ class RouterPreloader {
6146
6170
  });
6147
6171
  }
6148
6172
  }
6149
- RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6150
- RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader });
6151
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterPreloader, decorators: [{
6173
+ RouterPreloader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterPreloader, deps: [{ token: Router }, { token: i0.Compiler }, { token: i0.EnvironmentInjector }, { token: PreloadingStrategy }, { token: RouterConfigLoader }], target: i0.ɵɵFactoryTarget.Injectable });
6174
+ RouterPreloader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterPreloader });
6175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterPreloader, decorators: [{
6152
6176
  type: Injectable
6153
6177
  }], ctorParameters: function () { return [{ type: Router }, { type: i0.Compiler }, { type: i0.EnvironmentInjector }, { type: PreloadingStrategy }, { type: RouterConfigLoader }]; } });
6154
6178
 
@@ -6235,9 +6259,9 @@ class RouterScroller {
6235
6259
  }
6236
6260
  }
6237
6261
  }
6238
- RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6239
- RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller });
6240
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterScroller, decorators: [{
6262
+ RouterScroller.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterScroller, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
6263
+ RouterScroller.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterScroller });
6264
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterScroller, decorators: [{
6241
6265
  type: Injectable
6242
6266
  }], ctorParameters: function () { return [{ type: Router }, { type: i3.ViewportScroller }, { type: undefined }]; } });
6243
6267
 
@@ -6274,9 +6298,9 @@ const ROUTER_PROVIDERS = [
6274
6298
  provide: Router,
6275
6299
  useFactory: setupRouter,
6276
6300
  deps: [
6277
- UrlSerializer, ChildrenOutletContexts, Location, Injector, Compiler, ROUTES,
6278
- ROUTER_CONFIGURATION, DefaultTitleStrategy, [TitleStrategy, new Optional()],
6279
- [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
6301
+ UrlSerializer, ChildrenOutletContexts, Location, Injector, Compiler, ROUTES, TitleStrategy,
6302
+ ROUTER_CONFIGURATION, [UrlHandlingStrategy, new Optional()],
6303
+ [RouteReuseStrategy, new Optional()]
6280
6304
  ]
6281
6305
  },
6282
6306
  ChildrenOutletContexts,
@@ -6370,10 +6394,10 @@ class RouterModule {
6370
6394
  return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
6371
6395
  }
6372
6396
  }
6373
- RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6374
- RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
6375
- RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule });
6376
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0-next.3", ngImport: i0, type: RouterModule, decorators: [{
6397
+ RouterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterModule, deps: [{ token: ROUTER_FORROOT_GUARD, optional: true }, { token: Router, optional: true }], target: i0.ɵɵFactoryTarget.NgModule });
6398
+ RouterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.1.0", ngImport: i0, type: RouterModule, declarations: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent], exports: [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent] });
6399
+ RouterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterModule });
6400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: RouterModule, decorators: [{
6377
6401
  type: NgModule,
6378
6402
  args: [{
6379
6403
  declarations: ROUTER_DIRECTIVES,
@@ -6409,7 +6433,7 @@ function providePathLocationStrategy() {
6409
6433
  }
6410
6434
  function provideForRootGuard(router) {
6411
6435
  if (NG_DEV_MODE && router) {
6412
- throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
6436
+ throw new ɵRuntimeError(4007 /* RuntimeErrorCode.FOR_ROOT_CALLED_TWICE */, `RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
6413
6437
  }
6414
6438
  return 'guarded';
6415
6439
  }
@@ -6435,7 +6459,7 @@ function provideRoutes(routes) {
6435
6459
  { provide: ROUTES, multi: true, useValue: routes },
6436
6460
  ];
6437
6461
  }
6438
- function setupRouter(urlSerializer, contexts, location, injector, compiler, config, opts = {}, defaultTitleStrategy, titleStrategy, urlHandlingStrategy, routeReuseStrategy) {
6462
+ function setupRouter(urlSerializer, contexts, location, injector, compiler, config, titleStrategy, opts = {}, urlHandlingStrategy, routeReuseStrategy) {
6439
6463
  const router = new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config));
6440
6464
  if (urlHandlingStrategy) {
6441
6465
  router.urlHandlingStrategy = urlHandlingStrategy;
@@ -6443,7 +6467,7 @@ function setupRouter(urlSerializer, contexts, location, injector, compiler, conf
6443
6467
  if (routeReuseStrategy) {
6444
6468
  router.routeReuseStrategy = routeReuseStrategy;
6445
6469
  }
6446
- router.titleStrategy = titleStrategy ?? defaultTitleStrategy;
6470
+ router.titleStrategy = titleStrategy;
6447
6471
  assignExtraOptionsToRouter(opts, router);
6448
6472
  return router;
6449
6473
  }
@@ -6535,17 +6559,50 @@ function provideEnabledBlockingInitialNavigation() {
6535
6559
  useFactory: (injector) => {
6536
6560
  const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
6537
6561
  let initNavigation = false;
6562
+ /**
6563
+ * Performs the given action once the router finishes its next/current navigation.
6564
+ *
6565
+ * If the navigation is canceled or errors without a redirect, the navigation is considered
6566
+ * complete. If the `NavigationEnd` event emits, the navigation is also considered complete.
6567
+ */
6568
+ function afterNextNavigation(action) {
6569
+ const router = injector.get(Router);
6570
+ router.events
6571
+ .pipe(filter((e) => e instanceof NavigationEnd || e instanceof NavigationCancel ||
6572
+ e instanceof NavigationError), map(e => {
6573
+ if (e instanceof NavigationEnd) {
6574
+ // Navigation assumed to succeed if we get `ActivationStart`
6575
+ return true;
6576
+ }
6577
+ const redirecting = e instanceof NavigationCancel ?
6578
+ (e.code === 0 /* NavigationCancellationCode.Redirect */ ||
6579
+ e.code === 1 /* NavigationCancellationCode.SupersededByNewNavigation */) :
6580
+ false;
6581
+ return redirecting ? null : false;
6582
+ }), filter((result) => result !== null), take(1))
6583
+ .subscribe(() => {
6584
+ action();
6585
+ });
6586
+ }
6538
6587
  return () => {
6539
6588
  return locationInitialized.then(() => {
6540
6589
  return new Promise(resolve => {
6541
6590
  const router = injector.get(Router);
6542
6591
  const bootstrapDone = injector.get(BOOTSTRAP_DONE);
6592
+ afterNextNavigation(() => {
6593
+ // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
6594
+ // without a redirect.
6595
+ resolve(true);
6596
+ initNavigation = true;
6597
+ });
6543
6598
  router.afterPreactivation = () => {
6544
- // only the initial navigation should be delayed
6599
+ // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
6600
+ // assume activation will complete successfully (even though this is not
6601
+ // guaranteed).
6602
+ resolve(true);
6603
+ // only the initial navigation should be delayed until bootstrapping is done.
6545
6604
  if (!initNavigation) {
6546
- initNavigation = true;
6547
- resolve(true);
6548
- return bootstrapDone;
6605
+ return bootstrapDone.closed ? of(void 0) : bootstrapDone;
6549
6606
  // subsequent navigations should not be delayed
6550
6607
  }
6551
6608
  else {
@@ -6616,7 +6673,7 @@ function providePreloading(preloadingStrategy) {
6616
6673
  /**
6617
6674
  * @publicApi
6618
6675
  */
6619
- const VERSION = new Version('14.1.0-next.3');
6676
+ const VERSION = new Version('14.1.0');
6620
6677
 
6621
6678
  /**
6622
6679
  * @license