Skip to content
This repository was archived by the owner on Apr 4, 2025. It is now read-only.

Commit aa136a5

Browse files
committed
feat(@schematics/angular): Add guard schematic
1 parent 5ec1d98 commit aa136a5

File tree

5 files changed

+151
-0
lines changed

5 files changed

+151
-0
lines changed

packages/schematics/angular/collection.json

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@
2020
"description": "Create an enumeration.",
2121
"schema": "./enum/schema.json"
2222
},
23+
"guard": {
24+
"factory": "./guard",
25+
"description": "Create an guard.",
26+
"schema": "./guard/schema.json"
27+
},
2328
"interface": {
2429
"factory": "./interface",
2530
"description": "Create an interface.",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { TestBed, async, inject } from '@angular/core/testing';
2+
3+
import { <%= classify(name) %>Guard } from './<%= dasherize(name) %>.guard';
4+
5+
describe('<%= classify(name) %>Guard', () => {
6+
beforeEach(() => {
7+
TestBed.configureTestingModule({
8+
providers: [<%= classify(name) %>Guard]
9+
});
10+
});
11+
12+
it('should ...', inject([<%= classify(name) %>Guard], (guard: <%= classify(name) %>Guard) => {
13+
expect(guard).toBeTruthy();
14+
}));
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Injectable } from '@angular/core';
2+
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
3+
import { Observable } from 'rxjs/Observable';
4+
5+
@Injectable()
6+
export class <%= classify(name) %>Guard implements CanActivate {
7+
canActivate(
8+
next: ActivatedRouteSnapshot,
9+
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
10+
return true;
11+
}
12+
}
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
// TODO: replace `options: any` with an actual type generated from the schema.
9+
// tslint:disable:no-any
10+
import {addDeclarationToModule} from '../utility/ast-utils';
11+
import {InsertChange} from '../utility/change';
12+
13+
import {
14+
Rule,
15+
Tree,
16+
apply,
17+
branchAndMerge,
18+
chain,
19+
filter,
20+
mergeWith,
21+
move,
22+
noop,
23+
template,
24+
url,
25+
} from '@angular-devkit/schematics';
26+
import * as stringUtils from '../strings';
27+
28+
import 'rxjs/add/operator/merge';
29+
import * as ts from 'typescript';
30+
import { buildRelativePath, findModule } from '../utility/find-module';
31+
32+
33+
function addDeclarationToNgModule(options: any): Rule {
34+
return (host: Tree) => {
35+
if (!options.module) {
36+
return host;
37+
}
38+
39+
if (!host.exists(options.module)) {
40+
throw new Error(`Module specified (${options.module}) does not exist.`);
41+
}
42+
const modulePath = options.module;
43+
44+
const sourceText = host.read(modulePath) !.toString('utf-8');
45+
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
46+
47+
const componentPath = `/${options.sourceDir}/${options.path}/`
48+
+ (options.flat ? '' : stringUtils.dasherize(options.name) + '/')
49+
+ stringUtils.dasherize(options.name)
50+
+ '.guard';
51+
const relativePath = buildRelativePath(modulePath, componentPath);
52+
const changes = addDeclarationToModule(source, modulePath,
53+
stringUtils.classify(`${options.name}Component`),
54+
relativePath);
55+
const recorder = host.beginUpdate(modulePath);
56+
for (const change of changes) {
57+
if (change instanceof InsertChange) {
58+
recorder.insertLeft(change.pos, change.toAdd);
59+
}
60+
}
61+
host.commitUpdate(recorder);
62+
63+
return host;
64+
};
65+
}
66+
67+
export default function (options: any): Rule {
68+
const templateSource = apply(url('./files'), [
69+
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
70+
template({
71+
...stringUtils,
72+
...options,
73+
}),
74+
move(options.sourceDir),
75+
]);
76+
77+
return chain([
78+
branchAndMerge(chain([
79+
addDeclarationToNgModule(options),
80+
mergeWith(templateSource),
81+
])),
82+
]);
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"id": "SchematicsAngularGuard",
4+
"title": "Angular Guard Options Schema",
5+
"type": "object",
6+
"properties": {
7+
"name": {
8+
"type": "string"
9+
},
10+
"spec": {
11+
"type": "boolean",
12+
"default": true
13+
},
14+
"flat": {
15+
"type": "boolean",
16+
"default": false
17+
},
18+
"module": {
19+
"type": "string",
20+
"description": "Allows specification of the declaring module.",
21+
"alias": "m",
22+
"subtype": "filepath"
23+
},
24+
"path": {
25+
"type": "string",
26+
"default": "app"
27+
},
28+
"sourceDir": {
29+
"type": "string",
30+
"default": "src"
31+
}
32+
},
33+
"required": [
34+
"name"
35+
]
36+
}

0 commit comments

Comments
 (0)