55 * Use of this source code is governed by an MIT-style license that can be
66 * found in the LICENSE file at https://angular.io/license
77 */
8- import { JsonObject , dirname , experimental , join , normalize } from '@angular-devkit/core' ;
8+ import { dirname , experimental , join , normalize } from '@angular-devkit/core' ;
99import {
1010 Rule ,
1111 SchematicContext ,
@@ -26,19 +26,13 @@ import {
2626 isImported ,
2727} from '../utility/ast-utils' ;
2828import { Change , InsertChange } from '../utility/change' ;
29- import { getWorkspace , getWorkspacePath } from '../utility/config' ;
29+ import { getWorkspace , updateWorkspace } from '../utility/config' ;
3030import { 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' ;
3234import { Schema as AppShellOptions } from './schema' ;
3335
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-
4236function getSourceFile ( host : Tree , path : string ) : ts . SourceFile {
4337 const buffer = host . read ( path ) ;
4438 if ( ! buffer ) {
@@ -103,9 +97,13 @@ function getComponentTemplate(host: Tree, compPath: string, tmplInfo: TemplateIn
10397
10498function getBootstrapComponentPath (
10599 host : Tree ,
106- project : experimental . workspace . WorkspaceProject ,
100+ project : WorkspaceProject ,
107101) : string {
108102 const projectTargets = getProjectTargets ( project ) ;
103+ if ( ! projectTargets . build ) {
104+ throw targetBuildNotFoundError ( ) ;
105+ }
106+
109107 const mainPath = projectTargets . build . options . main ;
110108 const modulePath = getAppModulePath ( host , mainPath ) ;
111109 const moduleSource = getSourceFile ( host , modulePath ) ;
@@ -137,7 +135,7 @@ function validateProject(options: AppShellOptions): Rule {
137135 return ( host : Tree , context : SchematicContext ) => {
138136 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 > / ;
139137
140- const clientProject = getClientProject ( host , options ) ;
138+ const clientProject = getProject ( host , options . clientProject ) ;
141139 if ( clientProject . projectType !== 'application' ) {
142140 throw new SchematicsException ( `App shell requires a project type of "application".` ) ;
143141 }
@@ -155,11 +153,9 @@ function validateProject(options: AppShellOptions): Rule {
155153
156154function addUniversalTarget ( options : AppShellOptions ) : Rule {
157155 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 ;
163159 }
164160
165161 // Copy options.
@@ -187,10 +183,9 @@ function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
187183 }
188184
189185 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 ,
194189 options : {
195190 browserTarget : `${ options . clientProject } :build` ,
196191 serverTarget : `${ options . clientProject } :server` ,
@@ -203,23 +198,17 @@ function addAppShellConfigToWorkspace(options: AppShellOptions): Rule {
203198 } ,
204199 } ;
205200
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 ) ;
216202 } ;
217203}
218204
219205function addRouterModule ( options : AppShellOptions ) : Rule {
220206 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 ;
223212 const modulePath = getAppModulePath ( host , mainPath ) ;
224213 const moduleSource = getSourceFile ( host , modulePath ) ;
225214 const changes = addImportToModule ( moduleSource , modulePath , 'RouterModule' , '@angular/router' ) ;
@@ -256,8 +245,8 @@ function getMetadataProperty(metadata: ts.Node, propertyName: string): ts.Proper
256245
257246function addServerRoutes ( options : AppShellOptions ) : Rule {
258247 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 ) ;
261250 // const mainPath = universalArchitect.build.options.main;
262251 const modulePath = getServerModulePath ( host , clientProject , architect ) ;
263252 if ( modulePath === null ) {
@@ -322,27 +311,6 @@ function addShellComponent(options: AppShellOptions): Rule {
322311 return schematic ( 'component' , componentOptions ) ;
323312}
324313
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-
346314export default function ( options : AppShellOptions ) : Rule {
347315 return chain ( [
348316 validateProject ( options ) ,
0 commit comments