This repository has been archived by the owner on Sep 30, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.ts
116 lines (102 loc) · 3.28 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import {
apply,
branchAndMerge,
chain,
filter,
MergeStrategy,
mergeWith,
move,
noop,
Rule,
SchematicContext,
SchematicsException,
template,
Tree,
url
} from '@angular-devkit/schematics';
import * as ts from 'typescript';
import { strings } from '@angular-devkit/core';
import { getWorkspace } from '@schematics/angular/utility/config';
import { buildDefaultPath } from '@schematics/angular/utility/project';
import { buildRelativePath } from '@schematics/angular/utility/find-module';
import { addProviderToModule } from '@schematics/angular/utility/ast-utils';
import { parseName } from '@schematics/angular/utility/parse-name';
import { applyLintFix } from '@schematics/angular/utility/lint-fix';
import { InsertChange } from '@schematics/angular/utility/change';
import { Schema as ModelServiceOptions } from './schema';
export function modelService(options: ModelServiceOptions): Rule {
return (host: Tree, _context: SchematicContext) => {
const workspace = getWorkspace(host);
if (!options.project) {
throw new SchematicsException('Option (project) is required.');
}
const project = workspace.projects[options.project];
if (options.path === undefined) {
options.path = buildDefaultPath(project);
}
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
const templateSource = apply(url('./files'), [
options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')),
template({
...strings,
'if-flat': (s: string) => (options.flat ? '' : s),
...options
}),
move(parsedPath.path)
]);
return chain([
branchAndMerge(
chain([
addToNgModuleProviders(options),
mergeWith(templateSource, MergeStrategy.Default)
])
),
options.lintFix ? applyLintFix(options.path) : noop()
])(host, _context);
};
}
function addToNgModuleProviders(options: ModelServiceOptions): Rule {
return (host: Tree) => {
if (!options.module) {
return host;
}
const modulePath = `${options.path}/${options.module}`;
const moduleSource = readIntoSourceFile(host, modulePath);
const servicePath =
`${options.path}/` +
(options.flat ? '' : strings.dasherize(options.name) + '/') +
strings.dasherize(options.name) +
'.service';
const relativePath = buildRelativePath(modulePath, servicePath);
const classifiedName = strings.classify(`${options.name}Service`);
const providersChanges = addProviderToModule(
moduleSource,
modulePath,
classifiedName,
relativePath
);
const providersRecorder = host.beginUpdate(modulePath);
for (const change of providersChanges) {
if (change instanceof InsertChange) {
providersRecorder.insertLeft(change.pos, change.toAdd);
}
}
host.commitUpdate(providersRecorder);
return host;
};
}
function readIntoSourceFile(host: Tree, modulePath: string): ts.SourceFile {
const text = host.read(modulePath);
if (text === null) {
throw new SchematicsException(`File ${modulePath} does not exist.`);
}
const sourceText = text.toString('utf-8');
return ts.createSourceFile(
modulePath,
sourceText,
ts.ScriptTarget.Latest,
true
);
}