Skip to content

Commit 2e747a7

Browse files
committed
feat(@schematics/angular): Added multiselect guard implements option
1 parent 53f1571 commit 2e747a7

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
import { Injectable } from '@angular/core';
2-
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
2+
import { <%= implementationImports %>ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
33
import { Observable } from 'rxjs';
44

55
@Injectable({
66
providedIn: 'root'
77
})
8-
export class <%= classify(name) %>Guard implements CanActivate {
9-
canActivate(
8+
export class <%= classify(name) %>Guard implements <%= implementations %> {
9+
<% if (implements && implements.includes('CanActivate')) { %>canActivate(
1010
next: ActivatedRouteSnapshot,
1111
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
1212
return true;
1313
}
14+
<% } %><% if (implements && implements.includes('CanActivateChild')) { %>canActivateChild(
15+
next: ActivatedRouteSnapshot,
16+
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
17+
return true;
18+
}
19+
<% } %><% if (implements && implements.includes('CanLoad')) { %>canLoad(
20+
route: Route,
21+
segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
22+
return true;
23+
}<% } %>
1424
}

packages/schematics/angular/guard/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,26 @@ export default function (options: GuardOptions): Rule {
3737
options.path = buildDefaultPath(project);
3838
}
3939

40+
let implementations = '';
41+
let implementationImports = '';
42+
if (options.implements && options.implements.length > 0) {
43+
implementations = options.implements.join(', ');
44+
implementationImports = `${implementations}, `;
45+
// As long as we aren't in IE... ;)
46+
if (options.implements.includes('CanLoad')) {
47+
implementationImports = `${implementationImports}Route, UrlSegment, `;
48+
}
49+
}
50+
4051
const parsedPath = parseName(options.path, options.name);
4152
options.name = parsedPath.name;
4253
options.path = parsedPath.path;
4354

4455
const templateSource = apply(url('./files'), [
4556
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
4657
template({
58+
implementations: implementations,
59+
implementationImports: implementationImports,
4760
...strings,
4861
...options,
4962
}),

packages/schematics/angular/guard/index_spec.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { Schema as ApplicationOptions } from '../application/schema';
1010
import { Schema as WorkspaceOptions } from '../workspace/schema';
1111
import { Schema as GuardOptions } from './schema';
1212

13-
1413
describe('Guard Schematic', () => {
1514
const schematicRunner = new SchematicTestRunner(
1615
'@schematics/angular',
@@ -66,4 +65,30 @@ describe('Guard Schematic', () => {
6665
appTree = schematicRunner.runSchematic('guard', defaultOptions, appTree);
6766
expect(appTree.files).toContain('/projects/bar/custom/app/foo.guard.ts');
6867
});
68+
69+
it('should respect the implements value', () => {
70+
const options = { ...defaultOptions, implements: ['CanActivate']};
71+
const tree = schematicRunner.runSchematic('guard', options, appTree);
72+
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
73+
expect(fileString).toContain('CanActivate');
74+
expect(fileString).toContain('canActivate');
75+
expect(fileString).not.toContain('CanActivateChild');
76+
expect(fileString).not.toContain('canActivateChild');
77+
expect(fileString).not.toContain('CanLoad');
78+
expect(fileString).not.toContain('canLoad');
79+
});
80+
81+
it('should respect the implements values', () => {
82+
const implementationOptions = ['CanActivate', 'CanLoad', 'CanActivateChild'];
83+
const options = { ...defaultOptions, implements: implementationOptions};
84+
const tree = schematicRunner.runSchematic('guard', options, appTree);
85+
const fileString = tree.readContent('/projects/bar/src/app/foo.guard.ts');
86+
87+
// Should contain all implementations
88+
implementationOptions.forEach((implementation: string) => {
89+
expect(fileString).toContain(implementation);
90+
const functionName = `${implementation.charAt(0).toLowerCase()}${implementation.slice(1)}`;
91+
expect(fileString).toContain(functionName);
92+
});
93+
});
6994
});

packages/schematics/angular/guard/schema.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,20 @@
4141
"type": "boolean",
4242
"default": false,
4343
"description": "When true, applies lint fixes after generating the guard."
44+
},
45+
"implements": {
46+
"type": "array",
47+
"description": "Specifies which interfaces to implement.",
48+
"x-prompt": {
49+
"message": "Which interfaces would you like to implement?",
50+
"type": "list",
51+
"multiselect": true,
52+
"items": [
53+
{ "value": "CanActivate", "label": "CanActivate" },
54+
{ "value": "CanActivateChild", "label": "CanActivateChild" },
55+
{ "value": "CanLoad", "label": "CanLoad" }
56+
]
57+
}
4458
}
4559
},
4660
"required": [

0 commit comments

Comments
 (0)