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

Commit 8627da4

Browse files
jschwartyBrocco
authored andcommitted
feat(@schematics/angular): Add service schematic
1 parent 5ec1d98 commit 8627da4

File tree

5 files changed

+147
-0
lines changed

5 files changed

+147
-0
lines changed

packages/schematics/angular/collection.json

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"factory": "./module",
3030
"description": "Create an Angular module.",
3131
"schema": "./module/schema.json"
32+
},
33+
"service": {
34+
"factory": "./service",
35+
"description": "Create an Angular service.",
36+
"schema": "./service/schema.json"
3237
}
3338
}
3439
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { TestBed, inject } from '@angular/core/testing';
2+
3+
import { <%= classify(name) %>Service } from './<%= dasherize(name) %>.service';
4+
5+
describe('<%= classify(name) %>Service', () => {
6+
beforeEach(() => {
7+
TestBed.configureTestingModule({
8+
providers: [<%= classify(name) %>Service]
9+
});
10+
});
11+
12+
it('should be created', inject([<%= classify(name) %>Service], (service: <%= classify(name) %>Service) => {
13+
expect(service).toBeTruthy();
14+
}));
15+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Injectable } from '@angular/core';
2+
3+
@Injectable()
4+
export class <%= classify(name) %>Service {
5+
6+
constructor() { }
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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 {
11+
Rule,
12+
Tree,
13+
apply,
14+
branchAndMerge,
15+
chain,
16+
filter,
17+
mergeWith,
18+
move,
19+
noop,
20+
template,
21+
url,
22+
} from '@angular-devkit/schematics';
23+
import 'rxjs/add/operator/merge';
24+
import * as ts from 'typescript';
25+
import * as stringUtils from '../strings';
26+
import {addProviderToModule} from '../utility/ast-utils';
27+
import {InsertChange} from '../utility/change';
28+
import {buildRelativePath} from '../utility/find-module';
29+
30+
function addProviderToNgModule(options: any): Rule {
31+
return (host: Tree) => {
32+
if (!options.module) {
33+
return host;
34+
}
35+
36+
const modulePath = options.module;
37+
if (!host.exists(options.module)) {
38+
throw new Error(`Module specified (${options.module}) does not exist.`);
39+
}
40+
41+
const sourceText = host.read(modulePath) !.toString('utf-8');
42+
const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true);
43+
44+
const servicePath = `/${options.sourceDir}/${options.path}/`
45+
+ (options.flat ? '' : stringUtils.dasherize(options.name) + '/')
46+
+ stringUtils.dasherize(options.name)
47+
+ '.service';
48+
const relativePath = buildRelativePath(modulePath, servicePath);
49+
const changes = addProviderToModule(source, modulePath,
50+
stringUtils.classify(`${options.name}Service`),
51+
relativePath);
52+
const recorder = host.beginUpdate(modulePath);
53+
for (const change of changes) {
54+
if (change instanceof InsertChange) {
55+
recorder.insertLeft(change.pos, change.toAdd);
56+
}
57+
}
58+
host.commitUpdate(recorder);
59+
60+
return host;
61+
};
62+
}
63+
64+
export default function (options: any): Rule {
65+
const templateSource = apply(url('./files'), [
66+
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
67+
template({
68+
...stringUtils,
69+
'if-flat': (s: string) => options.flat ? '' : s,
70+
...options,
71+
}),
72+
move(options.sourceDir),
73+
]);
74+
75+
return chain([
76+
branchAndMerge(chain([
77+
filter(path => path.endsWith('.module.ts') && !path.endsWith('-routing.module.ts')),
78+
addProviderToNgModule(options),
79+
mergeWith(templateSource),
80+
])),
81+
]);
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"id": "SchematicsAngularService",
4+
"title": "Angular Service Options Schema",
5+
"type": "object",
6+
"properties": {
7+
"name": {
8+
"type": "string"
9+
},
10+
"path": {
11+
"type": "string",
12+
"default": "app"
13+
},
14+
"sourceDir": {
15+
"type": "string",
16+
"default": "src"
17+
},
18+
"flat": {
19+
"type": "boolean",
20+
"default": false,
21+
"description": "Flag to indicate if a dir is created."
22+
},
23+
"spec": {
24+
"type": "boolean",
25+
"default": true,
26+
"description": "Specifies if a spec file is generated."
27+
},
28+
"module": {
29+
"type": "string",
30+
"default": "",
31+
"description": "Allows specification of the declaring module."
32+
}
33+
},
34+
"required": [
35+
"name"
36+
]
37+
}

0 commit comments

Comments
 (0)