1
1
import { Path , join , normalize , strings } from '@angular-devkit/core' ;
2
+ import { ProjectDefinition } from '@angular-devkit/core/src/workspace' ;
2
3
import { DirEntry , Rule , SchematicsException , Tree , apply , branchAndMerge , chain , filter , mergeWith , move , noop , template , url } from '@angular-devkit/schematics' ;
3
4
import { ModuleOptions , buildRelativePath } from '@schematics/angular/utility/find-module' ;
4
5
import { parseName } from '@schematics/angular/utility/parse-name' ;
5
- import { buildDefaultPath , getProject } from '@schematics/angular/utility/project' ;
6
6
import { validateHtmlSelector , validateName } from '@schematics/angular/utility/validation' ;
7
+ import { buildDefaultPath , getWorkspace } from '@schematics/angular/utility/workspace' ;
7
8
import * as ts from 'typescript' ;
8
9
9
10
import { buildSelector } from '../util' ;
@@ -12,19 +13,22 @@ import { Change, InsertChange } from '../util/change';
12
13
13
14
import { Schema as PageOptions } from './schema' ;
14
15
15
- function findRoutingModuleFromOptions ( host : Tree , options : ModuleOptions ) : Path | undefined {
16
+ function findRoutingModuleFromOptions (
17
+ host : Tree ,
18
+ options : ModuleOptions
19
+ ) : Path | undefined {
16
20
if ( options . hasOwnProperty ( 'skipImport' ) && options . skipImport ) {
17
21
return undefined ;
18
22
}
19
23
20
24
if ( ! options . module ) {
21
- const pathToCheck = ( options . path || '' )
22
- + ( options . flat ? '' : '/' + strings . dasherize ( options . name ) ) ;
25
+ const pathToCheck =
26
+ ( options . path || '' ) +
27
+ ( options . flat ? '' : '/' + strings . dasherize ( options . name ) ) ;
23
28
24
29
return normalize ( findRoutingModule ( host , pathToCheck ) ) ;
25
30
} else {
26
- const modulePath = normalize (
27
- '/' + ( options . path ) + '/' + options . module ) ;
31
+ const modulePath = normalize ( '/' + options . path + '/' + options . module ) ;
28
32
const moduleBaseName = normalize ( modulePath ) . split ( '/' ) . pop ( ) ;
29
33
30
34
if ( host . exists ( modulePath ) ) {
@@ -52,15 +56,19 @@ function findRoutingModule(host: Tree, generateDir: string): Path {
52
56
if ( matches . length === 1 ) {
53
57
return join ( dir . path , matches [ 0 ] ) ;
54
58
} else if ( matches . length > 1 ) {
55
- throw new Error ( 'More than one module matches. Use skip-import option to skip importing '
56
- + 'the component into the closest module.' ) ;
59
+ throw new Error (
60
+ 'More than one module matches. Use skip-import option to skip importing ' +
61
+ 'the component into the closest module.'
62
+ ) ;
57
63
}
58
64
59
65
dir = dir . parent ;
60
66
}
61
67
62
- throw new Error ( 'Could not find an NgModule. Use the skip-import '
63
- + 'option to skip importing in NgModule.' ) ;
68
+ throw new Error (
69
+ 'Could not find an NgModule. Use the skip-import ' +
70
+ 'option to skip importing in NgModule.'
71
+ ) ;
64
72
}
65
73
66
74
function addRouteToNgModule ( options : PageOptions ) : Rule {
@@ -78,19 +86,31 @@ function addRouteToNgModule(options: PageOptions): Rule {
78
86
}
79
87
80
88
const sourceText = text . toString ( 'utf8' ) ;
81
- const source = ts . createSourceFile ( module , sourceText , ts . ScriptTarget . Latest , true ) ;
89
+ const source = ts . createSourceFile (
90
+ module ,
91
+ sourceText ,
92
+ ts . ScriptTarget . Latest ,
93
+ true
94
+ ) ;
82
95
83
- const pagePath = (
96
+ const pagePath =
84
97
`/${ options . path } /` +
85
98
( options . flat ? '' : `${ strings . dasherize ( options . name ) } /` ) +
86
- `${ strings . dasherize ( options . name ) } .module`
87
- ) ;
99
+ `${ strings . dasherize ( options . name ) } .module` ;
88
100
89
101
const relativePath = buildRelativePath ( module , pagePath ) ;
90
102
91
- const routePath = strings . dasherize ( options . routePath ? options . routePath : options . name ) ;
103
+ const routePath = strings . dasherize (
104
+ options . routePath ? options . routePath : options . name
105
+ ) ;
92
106
const ngModuleName = `${ strings . classify ( options . name ) } PageModule` ;
93
- const changes = addRouteToRoutesArray ( source , module , routePath , relativePath , ngModuleName ) ;
107
+ const changes = addRouteToRoutesArray (
108
+ source ,
109
+ module ,
110
+ routePath ,
111
+ relativePath ,
112
+ ngModuleName
113
+ ) ;
94
114
const recorder = host . beginUpdate ( module ) ;
95
115
96
116
for ( const change of changes ) {
@@ -105,14 +125,24 @@ function addRouteToNgModule(options: PageOptions): Rule {
105
125
} ;
106
126
}
107
127
108
- function addRouteToRoutesArray ( source : ts . SourceFile , ngModulePath : string , routePath : string , routeLoadChildren : string , ngModuleName : string ) : Change [ ] {
128
+ function addRouteToRoutesArray (
129
+ source : ts . SourceFile ,
130
+ ngModulePath : string ,
131
+ routePath : string ,
132
+ routeLoadChildren : string ,
133
+ ngModuleName : string
134
+ ) : Change [ ] {
109
135
const keywords = findNodes ( source , ts . SyntaxKind . VariableStatement ) ;
110
136
111
137
for ( const keyword of keywords ) {
112
138
if ( ts . isVariableStatement ( keyword ) ) {
113
- const [ declaration ] = keyword . declarationList . declarations ;
139
+ const [ declaration ] = keyword . declarationList . declarations ;
114
140
115
- if ( ts . isVariableDeclaration ( declaration ) && declaration . initializer && declaration . name . getText ( ) === 'routes' ) {
141
+ if (
142
+ ts . isVariableDeclaration ( declaration ) &&
143
+ declaration . initializer &&
144
+ declaration . name . getText ( ) === 'routes'
145
+ ) {
116
146
const node = declaration . initializer . getChildAt ( 1 ) ;
117
147
const lastRouteNode = node . getLastToken ( ) ;
118
148
@@ -126,10 +156,20 @@ function addRouteToRoutesArray(source: ts.SourceFile, ngModulePath: string, rout
126
156
if ( lastRouteNode . kind === ts . SyntaxKind . CommaToken ) {
127
157
trailingCommaFound = true ;
128
158
} else {
129
- changes . push ( new InsertChange ( ngModulePath , lastRouteNode . getEnd ( ) , ',' ) ) ;
159
+ changes . push (
160
+ new InsertChange ( ngModulePath , lastRouteNode . getEnd ( ) , ',' )
161
+ ) ;
130
162
}
131
163
132
- changes . push ( new InsertChange ( ngModulePath , lastRouteNode . getEnd ( ) + 1 , ` {\n path: '${ routePath } ',\n loadChildren: () => import('${ routeLoadChildren } ').then( m => m.${ ngModuleName } )\n }${ trailingCommaFound ? ',' : '' } \n` ) ) ;
164
+ changes . push (
165
+ new InsertChange (
166
+ ngModulePath ,
167
+ lastRouteNode . getEnd ( ) + 1 ,
168
+ ` {\n path: '${ routePath } ',\n loadChildren: () => import('${ routeLoadChildren } ').then( m => m.${ ngModuleName } )\n }${
169
+ trailingCommaFound ? ',' : ''
170
+ } \n`
171
+ )
172
+ ) ;
133
173
134
174
return changes ;
135
175
}
@@ -140,23 +180,24 @@ function addRouteToRoutesArray(source: ts.SourceFile, ngModulePath: string, rout
140
180
}
141
181
142
182
export default function ( options : PageOptions ) : Rule {
143
- return ( host , context ) => {
183
+ return async ( host : Tree ) => {
144
184
if ( ! options . project ) {
145
185
throw new SchematicsException ( 'Option (project) is required.' ) ;
146
186
}
147
187
148
- const project = getProject ( host , options . project ) ;
188
+ const workspace = await getWorkspace ( host ) ;
189
+ const project = workspace . projects . get ( options . project ) ;
149
190
150
191
if ( options . path === undefined ) {
151
- options . path = buildDefaultPath ( project ) ;
192
+ options . path = buildDefaultPath ( project as ProjectDefinition ) ;
152
193
}
153
194
154
195
options . module = findRoutingModuleFromOptions ( host , options ) ;
155
196
156
197
const parsedPath = parseName ( options . path , options . name ) ;
157
198
options . name = parsedPath . name ;
158
199
options . path = parsedPath . path ;
159
- options . selector = options . selector ? options . selector : buildSelector ( options , project . prefix ) ;
200
+ options . selector = options . selector ? options . selector : buildSelector ( options , project ? .prefix ?? 'app' ) ;
160
201
161
202
validateName ( options . name ) ;
162
203
validateHtmlSelector ( options . selector ) ;
@@ -165,17 +206,16 @@ export default function(options: PageOptions): Rule {
165
206
options . spec ? noop ( ) : filter ( p => ! p . endsWith ( '.spec.ts' ) ) ,
166
207
template ( {
167
208
...strings ,
168
- 'if-flat' : ( s : string ) => options . flat ? '' : s ,
209
+ 'if-flat' : ( s : string ) => ( options . flat ? '' : s ) ,
169
210
...options ,
170
211
} ) ,
171
212
move ( parsedPath . path ) ,
172
213
] ) ;
173
214
174
215
return chain ( [
175
- branchAndMerge ( chain ( [
176
- addRouteToNgModule ( options ) ,
177
- mergeWith ( templateSource ) ,
178
- ] ) ) ,
179
- ] ) ( host , context ) ;
216
+ branchAndMerge (
217
+ chain ( [ addRouteToNgModule ( options ) , mergeWith ( templateSource ) ] )
218
+ ) ,
219
+ ] ) ;
180
220
} ;
181
221
}
0 commit comments