|
| 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 * as stringUtils from '../strings'; |
| 24 | + |
| 25 | +import 'rxjs/add/operator/merge'; |
| 26 | +import * as ts from 'typescript'; |
| 27 | +import {addProviderToModule} from '../utility/ast-utils'; |
| 28 | +import {InsertChange} from '../utility/change'; |
| 29 | +import {buildRelativePath} from '../utility/find-module'; |
| 30 | + |
| 31 | +function addProviderToNgModule(options: any): Rule { |
| 32 | + return (host: Tree) => { |
| 33 | + if (!options.module) { |
| 34 | + return host; |
| 35 | + } |
| 36 | + |
| 37 | + let modulePath; |
| 38 | + if (options.module) { |
| 39 | + if (!host.exists(options.module)) { |
| 40 | + throw new Error(`Module specified (${options.module}) does not exist.`); |
| 41 | + } |
| 42 | + modulePath = options.module; |
| 43 | + } |
| 44 | + |
| 45 | + const sourceText = host.read(modulePath) !.toString('utf-8'); |
| 46 | + const source = ts.createSourceFile(modulePath, sourceText, ts.ScriptTarget.Latest, true); |
| 47 | + |
| 48 | + const servicePath = `/${options.sourceDir}/${options.path}/` |
| 49 | + + (options.flat ? '' : stringUtils.dasherize(options.name) + '/') |
| 50 | + + stringUtils.dasherize(options.name) |
| 51 | + + '.service'; |
| 52 | + const relativePath = buildRelativePath(modulePath, servicePath); |
| 53 | + const changes = addProviderToModule(source, modulePath, |
| 54 | + stringUtils.classify(`${options.name}Service`), |
| 55 | + relativePath); |
| 56 | + const recorder = host.beginUpdate(modulePath); |
| 57 | + for (const change of changes) { |
| 58 | + if (change instanceof InsertChange) { |
| 59 | + recorder.insertLeft(change.pos, change.toAdd); |
| 60 | + } |
| 61 | + } |
| 62 | + host.commitUpdate(recorder); |
| 63 | + |
| 64 | + return host; |
| 65 | + }; |
| 66 | +} |
| 67 | + |
| 68 | +export default function (options: any): Rule { |
| 69 | + const templateSource = apply(url('./files'), [ |
| 70 | + options.spec ? noop() : filter(path => !path.endsWith('.spec.ts')), |
| 71 | + template({ |
| 72 | + ...stringUtils, |
| 73 | + 'if-flat': (s: string) => options.flat ? '' : s, |
| 74 | + ...options, |
| 75 | + }), |
| 76 | + move(options.sourceDir), |
| 77 | + ]); |
| 78 | + |
| 79 | + return chain([ |
| 80 | + branchAndMerge(chain([ |
| 81 | + filter(path => path.endsWith('.module.ts') && !path.endsWith('-routing.module.ts')), |
| 82 | + addProviderToNgModule(options), |
| 83 | + mergeWith(templateSource), |
| 84 | + ])), |
| 85 | + ]); |
| 86 | +} |
0 commit comments