5
5
* Use of this source code is governed by an MIT-style license that can be
6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
- import { JsonObject , dirname , experimental , join , normalize } from '@angular-devkit/core' ;
8
+ import { dirname , experimental , join , normalize } from '@angular-devkit/core' ;
9
9
import {
10
10
Rule ,
11
11
SchematicContext ,
@@ -26,19 +26,13 @@ import {
26
26
isImported ,
27
27
} from '../utility/ast-utils' ;
28
28
import { Change , InsertChange } from '../utility/change' ;
29
- import { getWorkspace , getWorkspacePath } from '../utility/config' ;
29
+ import { getWorkspace , updateWorkspace } from '../utility/config' ;
30
30
import { getAppModulePath } from '../utility/ng-ast-utils' ;
31
- import { getProjectTargets } from '../utility/project-targets' ;
31
+ import { getProject } from '../utility/project' ;
32
+ import { getProjectTargets , targetBuildNotFoundError } from '../utility/project-targets' ;
33
+ import { Builders , WorkspaceProject } from '../utility/workspace-models' ;
32
34
import { Schema as AppShellOptions } from './schema' ;
33
35
34
-
35
- // Helper functions. (possible refactors to utils)
36
- function formatMissingAppMsg ( label : string , nameOrIndex : string | undefined ) : string {
37
- const nameOrIndexText = nameOrIndex ? ` (${ nameOrIndex } )` : '' ;
38
-
39
- return `${ label } app ${ nameOrIndexText } not found.` ;
40
- }
41
-
42
36
function getSourceFile ( host : Tree , path : string ) : ts . SourceFile {
43
37
const buffer = host . read ( path ) ;
44
38
if ( ! buffer ) {
@@ -103,9 +97,13 @@ function getComponentTemplate(host: Tree, compPath: string, tmplInfo: TemplateIn
103
97
104
98
function getBootstrapComponentPath (
105
99
host : Tree ,
106
- project : experimental . workspace . WorkspaceProject ,
100
+ project : WorkspaceProject ,
107
101
) : string {
108
102
const projectTargets = getProjectTargets ( project ) ;
103
+ if ( ! projectTargets . build ) {
104
+ throw targetBuildNotFoundError ( ) ;
105
+ }
106
+
109
107
const mainPath = projectTargets . build . options . main ;
110
108
const modulePath = getAppModulePath ( host , mainPath ) ;
111
109
const moduleSource = getSourceFile ( host , modulePath ) ;
@@ -137,7 +135,7 @@ function validateProject(options: AppShellOptions): Rule {
137
135
return ( host : Tree , context : SchematicContext ) => {
138
136
const routerOutletCheckRegex = / < r o u t e r \- o u t l e t .* ?> ( [ \s \S ] * ?) < \/ r o u t e r \- o u t l e t > / ;
139
137
140
- const clientProject = getClientProject ( host , options ) ;
138
+ const clientProject = getProject ( host , options . clientProject ) ;
141
139
if ( clientProject . projectType !== 'application' ) {
142
140
throw new SchematicsException ( `App shell requires a project type of "application".` ) ;
143
141
}
@@ -155,11 +153,9 @@ function validateProject(options: AppShellOptions): Rule {
155
153
156
154
function addUniversalTarget ( options : AppShellOptions ) : Rule {
157
155
return ( host : Tree , context : SchematicContext ) => {
158
- const architect = getClientArchitect ( host , options ) ;
159
- if ( architect !== null ) {
160
- if ( architect . server !== undefined ) {
161
- return host ;
162
- }
156
+ const architect = getProjectTargets ( host , options . clientProject ) ;
157
+ if ( architect . server ) {
158
+ return host ;
163
159
}
164
160
165
161
// Copy options.
@@ -187,10 +183,9 @@ function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
187
183
}
188
184
189
185
const workspace = getWorkspace ( host ) ;
190
- const workspacePath = getWorkspacePath ( host ) ;
191
-
192
- const appShellTarget : JsonObject = {
193
- builder : '@angular-devkit/build-angular:app-shell' ,
186
+ const projectTargets = getProjectTargets ( workspace , options . clientProject ) ;
187
+ projectTargets [ 'app-shell' ] = {
188
+ builder : Builders . AppShell ,
194
189
options : {
195
190
browserTarget : `${ options . clientProject } :build` ,
196
191
serverTarget : `${ options . clientProject } :server` ,
@@ -203,23 +198,17 @@ function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
203
198
} ,
204
199
} ;
205
200
206
- if ( ! workspace . projects [ options . clientProject ] ) {
207
- throw new SchematicsException ( `Client app ${ options . clientProject } not found.` ) ;
208
- }
209
- const clientProject = workspace . projects [ options . clientProject ] ;
210
- const projectTargets = getProjectTargets ( clientProject ) ;
211
- projectTargets [ 'app-shell' ] = appShellTarget ;
212
-
213
- host . overwrite ( workspacePath , JSON . stringify ( workspace , null , 2 ) ) ;
214
-
215
- return host ;
201
+ return updateWorkspace ( workspace ) ;
216
202
} ;
217
203
}
218
204
219
205
function addRouterModule ( options : AppShellOptions ) : Rule {
220
206
return ( host : Tree ) => {
221
- const clientArchitect = getClientArchitect ( host , options ) ;
222
- const mainPath = clientArchitect . build . options . main ;
207
+ const projectTargets = getProjectTargets ( host , options . clientProject ) ;
208
+ if ( ! projectTargets . build ) {
209
+ throw targetBuildNotFoundError ( ) ;
210
+ }
211
+ const mainPath = projectTargets . build . options . main ;
223
212
const modulePath = getAppModulePath ( host , mainPath ) ;
224
213
const moduleSource = getSourceFile ( host , modulePath ) ;
225
214
const changes = addImportToModule ( moduleSource , modulePath , 'RouterModule' , '@angular/router' ) ;
@@ -256,8 +245,8 @@ function getMetadataProperty(metadata: ts.Node, propertyName: string): ts.Proper
256
245
257
246
function addServerRoutes ( options : AppShellOptions ) : Rule {
258
247
return ( host : Tree ) => {
259
- const clientProject = getClientProject ( host , options ) ;
260
- const architect = getClientArchitect ( host , options ) ;
248
+ const clientProject = getProject ( host , options . clientProject ) ;
249
+ const architect = getProjectTargets ( clientProject ) ;
261
250
// const mainPath = universalArchitect.build.options.main;
262
251
const modulePath = getServerModulePath ( host , clientProject , architect ) ;
263
252
if ( modulePath === null ) {
@@ -322,27 +311,6 @@ function addShellComponent(options: AppShellOptions): Rule {
322
311
return schematic ( 'component' , componentOptions ) ;
323
312
}
324
313
325
- function getClientProject (
326
- host : Tree , options : AppShellOptions ,
327
- ) : experimental . workspace . WorkspaceProject {
328
- const workspace = getWorkspace ( host ) ;
329
- const clientProject = workspace . projects [ options . clientProject ] ;
330
- if ( ! clientProject ) {
331
- throw new SchematicsException ( formatMissingAppMsg ( 'Client' , options . clientProject ) ) ;
332
- }
333
-
334
- return clientProject ;
335
- }
336
-
337
- function getClientArchitect (
338
- host : Tree , options : AppShellOptions ,
339
- ) : experimental . workspace . WorkspaceTool {
340
- const clientProject = getClientProject ( host , options ) ;
341
- const projectTargets = getProjectTargets ( clientProject ) ;
342
-
343
- return projectTargets ;
344
- }
345
-
346
314
export default function ( options : AppShellOptions ) : Rule {
347
315
return chain ( [
348
316
validateProject ( options ) ,
0 commit comments