Skip to content

Commit

Permalink
docs(router): Remove deprecation on Router guard interfaces (#56408)
Browse files Browse the repository at this point in the history
Many developers find these interfaces useful for various reasons. Beyond
that, the deprecation of the interfaces has incorrectly implied that
existing class-based guard implementations need to be migrated to
functions. Class injectables are _not_ deprecated and choosing to
implement a guard's state and logic as a class that is injectable in the
functions run inside the injection context is valid.

resolves #50234

PR Close #56408
  • Loading branch information
atscott authored and AndrewKushnir committed Jun 17, 2024
1 parent 4bc99f0 commit f346448
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 59 deletions.
30 changes: 10 additions & 20 deletions goldens/public-api/router/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ export abstract class BaseRouteReuseStrategy implements RouteReuseStrategy {
store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void;
}

// @public @deprecated
// @public
export interface CanActivate {
// (undocumented)
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): MaybeAsync<GuardResult>;
}

// @public @deprecated
// @public
export interface CanActivateChild {
// (undocumented)
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): MaybeAsync<GuardResult>;
Expand All @@ -130,7 +130,7 @@ export type CanActivateChildFn = (childRoute: ActivatedRouteSnapshot, state: Rou
// @public
export type CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => MaybeAsync<GuardResult>;

// @public @deprecated
// @public
export interface CanDeactivate<T> {
// (undocumented)
canDeactivate(component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState: RouterStateSnapshot): MaybeAsync<GuardResult>;
Expand All @@ -148,7 +148,7 @@ export interface CanLoad {
// @public @deprecated
export type CanLoadFn = (route: Route, segments: UrlSegment[]) => MaybeAsync<GuardResult>;

// @public @deprecated
// @public
export interface CanMatch {
// (undocumented)
canMatch(route: Route, segments: UrlSegment[]): MaybeAsync<GuardResult>;
Expand Down Expand Up @@ -376,29 +376,19 @@ export type LoadChildren = LoadChildrenCallback;
export type LoadChildrenCallback = () => Type<any> | NgModuleFactory<any> | Routes | Observable<Type<any> | Routes | DefaultExport<Type<any>> | DefaultExport<Routes>> | Promise<NgModuleFactory<any> | Type<any> | Routes | DefaultExport<Type<any>> | DefaultExport<Routes>>;

// @public
export function mapToCanActivate(providers: Array<Type<{
canActivate: CanActivateFn;
}>>): CanActivateFn[];
export function mapToCanActivate(providers: Array<Type<CanActivate>>): CanActivateFn[];

// @public
export function mapToCanActivateChild(providers: Array<Type<{
canActivateChild: CanActivateChildFn;
}>>): CanActivateChildFn[];
export function mapToCanActivateChild(providers: Array<Type<CanActivateChild>>): CanActivateChildFn[];

// @public
export function mapToCanDeactivate<T = unknown>(providers: Array<Type<{
canDeactivate: CanDeactivateFn<T>;
}>>): CanDeactivateFn<T>[];
export function mapToCanDeactivate<T = unknown>(providers: Array<Type<CanDeactivate<T>>>): CanDeactivateFn<T>[];

// @public
export function mapToCanMatch(providers: Array<Type<{
canMatch: CanMatchFn;
}>>): CanMatchFn[];
export function mapToCanMatch(providers: Array<Type<CanMatch>>): CanMatchFn[];

// @public
export function mapToResolve<T>(provider: Type<{
resolve: ResolveFn<T>;
}>): ResolveFn<T>;
export function mapToResolve<T>(provider: Type<Resolve<T>>): ResolveFn<T>;

// @public
export type MaybeAsync<T> = T | Observable<T> | Promise<T>;
Expand Down Expand Up @@ -610,7 +600,7 @@ export class RedirectCommand {
// @public
export type RedirectFunction = (redirectData: Pick<ActivatedRouteSnapshot, 'routeConfig' | 'url' | 'params' | 'queryParams' | 'fragment' | 'data' | 'outlet' | 'title'>) => string | UrlTree;

// @public @deprecated
// @public
export interface Resolve<T> {
// (undocumented)
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): MaybeAsync<T>;
Expand Down
6 changes: 6 additions & 0 deletions packages/router/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ export {
UrlMatcher,
UrlMatchResult,
RedirectCommand,
CanActivate,
CanActivateChild,
CanDeactivate,
CanLoad,
CanMatch,
Resolve,
} from './models';
export {ViewTransitionInfo, ViewTransitionsFeatureOptions} from './utils/view_transition';

Expand Down
24 changes: 2 additions & 22 deletions packages/router/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,10 +803,6 @@ export interface LoadedRouterConfig {
* ```
*
* @publicApi
* @deprecated Class-based `Route` guards are deprecated in favor of functional guards. An
* injectable class can be used as a functional guard using the [`inject`](api/core/inject)
* function: `canActivate: [() => inject(myGuard).canActivate()]`.
* @see {@link CanActivateFn}
*/
export interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): MaybeAsync<GuardResult>;
Expand Down Expand Up @@ -926,10 +922,6 @@ export type CanActivateFn = (
* ```
*
* @publicApi
* @deprecated Class-based `Route` guards are deprecated in favor of functional guards. An
* injectable class can be used as a functional guard using the [`inject`](api/core/inject)
* function: `canActivateChild: [() => inject(myGuard).canActivateChild()]`.
* @see {@link CanActivateChildFn}
*/
export interface CanActivateChild {
canActivateChild(
Expand Down Expand Up @@ -1013,10 +1005,6 @@ export type CanActivateChildFn = (
* ```
*
* @publicApi
* @deprecated Class-based `Route` guards are deprecated in favor of functional guards. An
* injectable class can be used as a functional guard using the [`inject`](api/core/inject)
* function: `canDeactivate: [() => inject(myGuard).canDeactivate()]`.
* @see {@link CanDeactivateFn}
*/
export interface CanDeactivate<T> {
canDeactivate(
Expand Down Expand Up @@ -1109,10 +1097,6 @@ export type CanDeactivateFn<T> = (
* could not be used for a URL match but the catch-all `**` `Route` did instead.
*
* @publicApi
* @deprecated Class-based `Route` guards are deprecated in favor of functional guards. An
* injectable class can be used as a functional guard using the [`inject`](api/core/inject)
* function: `canMatch: [() => inject(myGuard).canMatch()]`.
* @see {@link CanMatchFn}
*/
export interface CanMatch {
canMatch(route: Route, segments: UrlSegment[]): MaybeAsync<GuardResult>;
Expand Down Expand Up @@ -1226,10 +1210,6 @@ export type CanMatchFn = (route: Route, segments: UrlSegment[]) => MaybeAsync<Gu
* The order of execution is: BaseGuard, ChildGuard, BaseDataResolver, ChildDataResolver.
*
* @publicApi
* @deprecated Class-based `Route` resolvers are deprecated in favor of functional resolvers. An
* injectable class can be used as a functional guard using the [`inject`](api/core/inject)
function: `resolve:
* {'user': () => inject(UserResolver).resolve()}`.
* @see {@link ResolveFn}
*/
export interface Resolve<T> {
Expand Down Expand Up @@ -1395,7 +1375,7 @@ export type ResolveFn<T> = (
* ```
*
* @publicApi
* @deprecated Use {@link CanMatchFn} instead
* @deprecated Use {@link CanMatch} instead
*/
export interface CanLoad {
canLoad(route: Route, segments: UrlSegment[]): MaybeAsync<GuardResult>;
Expand All @@ -1407,7 +1387,7 @@ export interface CanLoad {
* @publicApi
* @see {@link CanLoad}
* @see {@link Route}
* @see {@link CanMatchFn}
* @see {@link CanMatch}
* @deprecated Use `Route.canMatch` and `CanMatchFn` instead
*/
export type CanLoadFn = (route: Route, segments: UrlSegment[]) => MaybeAsync<GuardResult>;
Expand Down
10 changes: 1 addition & 9 deletions packages/router/src/models_deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,4 @@
// The public API re-exports everything from this file, which can be patched
// locally in g3 to prevent regressions after cleanups complete.

export {
CanActivate,
CanActivateChild,
CanDeactivate,
CanLoad,
CanMatch,
DeprecatedGuard,
Resolve,
} from './models';
export {DeprecatedGuard} from './models';
25 changes: 17 additions & 8 deletions packages/router/src/utils/functional_guards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@

import {inject, Type} from '@angular/core';

import {CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, ResolveFn} from '../models';
import {
CanActivate,
CanActivateChild,
CanActivateChildFn,
CanActivateFn,
CanDeactivate,
CanDeactivateFn,
CanMatch,
CanMatchFn,
Resolve,
ResolveFn,
} from '../models';

/**
* Maps an array of injectable classes with canMatch functions to an array of equivalent
Expand All @@ -19,7 +30,7 @@ import {CanActivateChildFn, CanActivateFn, CanDeactivateFn, CanMatchFn, ResolveF
* @publicApi
* @see {@link Route}
*/
export function mapToCanMatch(providers: Array<Type<{canMatch: CanMatchFn}>>): CanMatchFn[] {
export function mapToCanMatch(providers: Array<Type<CanMatch>>): CanMatchFn[] {
return providers.map(
(provider) =>
(...params) =>
Expand All @@ -36,9 +47,7 @@ export function mapToCanMatch(providers: Array<Type<{canMatch: CanMatchFn}>>): C
* @publicApi
* @see {@link Route}
*/
export function mapToCanActivate(
providers: Array<Type<{canActivate: CanActivateFn}>>,
): CanActivateFn[] {
export function mapToCanActivate(providers: Array<Type<CanActivate>>): CanActivateFn[] {
return providers.map(
(provider) =>
(...params) =>
Expand All @@ -55,7 +64,7 @@ export function mapToCanActivate(
* @see {@link Route}
*/
export function mapToCanActivateChild(
providers: Array<Type<{canActivateChild: CanActivateChildFn}>>,
providers: Array<Type<CanActivateChild>>,
): CanActivateChildFn[] {
return providers.map(
(provider) =>
Expand All @@ -73,7 +82,7 @@ export function mapToCanActivateChild(
* @see {@link Route}
*/
export function mapToCanDeactivate<T = unknown>(
providers: Array<Type<{canDeactivate: CanDeactivateFn<T>}>>,
providers: Array<Type<CanDeactivate<T>>>,
): CanDeactivateFn<T>[] {
return providers.map(
(provider) =>
Expand All @@ -90,6 +99,6 @@ export function mapToCanDeactivate<T = unknown>(
* @publicApi
* @see {@link Route}
*/
export function mapToResolve<T>(provider: Type<{resolve: ResolveFn<T>}>): ResolveFn<T> {
export function mapToResolve<T>(provider: Type<Resolve<T>>): ResolveFn<T> {
return (...params) => inject(provider).resolve(...params);
}

0 comments on commit f346448

Please sign in to comment.