1
+ import * as ts from 'typescript' ;
2
+
3
+ import { SchematicsException , Tree } from '@angular-devkit/schematics' ;
4
+ import { classify } from '@angular-devkit/core/src/utils/strings' ;
5
+ import { buildRelativePath } from '@schematics/angular/utility/find-module' ;
6
+ import { InsertChange , Change } from '@schematics/angular/utility/change' ;
7
+ import { addEntryComponentToModule , addExportToModule , addDeclarationToModule } from '@schematics/angular/utility/ast-utils' ;
8
+ import { Schema as ComponentOptions } from './schema' ;
9
+ import { getSourceFile } from '../../utils' ;
10
+ import { addSymbolToDecoratorMetadata } from '../../ast-utils' ;
11
+
12
+ export const insertModuleId = ( tree : Tree , component : string ) => {
13
+ const componentSource = getSourceFile ( tree , component ) ;
14
+ const recorder = tree . beginUpdate ( component ) ;
15
+
16
+ const metadataChange = addSymbolToComponentMetadata (
17
+ componentSource , component , 'moduleId' , 'module.id' ) ;
18
+
19
+ metadataChange . forEach ( ( change : InsertChange ) =>
20
+ recorder . insertRight ( change . pos , change . toAdd )
21
+ ) ;
22
+ tree . commitUpdate ( recorder ) ;
23
+ } ;
24
+
25
+ function addSymbolToComponentMetadata (
26
+ source : ts . SourceFile ,
27
+ componentPath : string ,
28
+ metadataField : string ,
29
+ symbolName : string ,
30
+ ) : Change [ ] {
31
+ return addSymbolToDecoratorMetadata (
32
+ source ,
33
+ componentPath ,
34
+ metadataField ,
35
+ symbolName ,
36
+ 'Component' ,
37
+ '@angular/core'
38
+ ) ;
39
+ }
40
+
41
+ export function addDeclarationToNgModule ( tree : Tree , options : ComponentOptions , componentPath : string , modulePath : string ) {
42
+ const source = readIntoSourceFile ( tree , modulePath ) ;
43
+ const relativePath = buildRelativePath ( modulePath , componentPath ) ;
44
+ const classifiedName = classify ( `${ options . name } Component` ) ;
45
+ const declarationChanges = addDeclarationToModule ( source , modulePath , classifiedName , relativePath ) ;
46
+ const declarationRecorder = tree . beginUpdate ( modulePath ) ;
47
+ for ( const change of declarationChanges ) {
48
+ if ( change instanceof InsertChange ) {
49
+ declarationRecorder . insertLeft ( change . pos , change . toAdd ) ;
50
+ }
51
+ }
52
+ tree . commitUpdate ( declarationRecorder ) ;
53
+ if ( options . export ) {
54
+ // Need to refresh the AST because we overwrote the file in the host.
55
+ const source = readIntoSourceFile ( tree , modulePath ) ;
56
+ const exportRecorder = tree . beginUpdate ( modulePath ) ;
57
+ const exportChanges = addExportToModule ( source , modulePath , classify ( `${ options . name } Component` ) , relativePath ) ;
58
+ for ( const change of exportChanges ) {
59
+ if ( change instanceof InsertChange ) {
60
+ exportRecorder . insertLeft ( change . pos , change . toAdd ) ;
61
+ }
62
+ }
63
+ tree . commitUpdate ( exportRecorder ) ;
64
+ }
65
+ if ( options . entryComponent ) {
66
+ // Need to refresh the AST because we overwrote the file in the host.
67
+ const source = readIntoSourceFile ( tree , modulePath ) ;
68
+ const entryComponentRecorder = tree . beginUpdate ( modulePath ) ;
69
+ const entryComponentChanges = addEntryComponentToModule ( source , modulePath , classify ( `${ options . name } Component` ) , relativePath ) ;
70
+ for ( const change of entryComponentChanges ) {
71
+ if ( change instanceof InsertChange ) {
72
+ entryComponentRecorder . insertLeft ( change . pos , change . toAdd ) ;
73
+ }
74
+ }
75
+ tree . commitUpdate ( entryComponentRecorder ) ;
76
+ }
77
+ }
78
+
79
+ function readIntoSourceFile ( host : Tree , modulePath : string ) : ts . SourceFile {
80
+ const text = host . read ( modulePath ) ;
81
+ if ( text === null ) {
82
+ throw new SchematicsException ( `File ${ modulePath } does not exist.` ) ;
83
+ }
84
+ const sourceText = text . toString ( 'utf-8' ) ;
85
+
86
+ return ts . createSourceFile ( modulePath , sourceText , ts . ScriptTarget . Latest , true ) ;
87
+ }
0 commit comments