@@ -115,21 +115,63 @@ function wrapBootstrapCall(options: UniversalOptions): Rule {
115115 let currentCall = bootstrapCall ;
116116 while ( bootstrapCallExpression === null && currentCall . parent ) {
117117 currentCall = currentCall . parent ;
118- if ( currentCall . kind === ts . SyntaxKind . ExpressionStatement ) {
118+ if ( ts . isExpressionStatement ( currentCall ) || ts . isVariableStatement ( currentCall ) ) {
119119 bootstrapCallExpression = currentCall ;
120120 }
121121 }
122122 bootstrapCall = currentCall ;
123123
124+ // In case the bootstrap code is a variable statement
125+ // we need to determine it's usage
126+ if ( bootstrapCallExpression && ts . isVariableStatement ( bootstrapCallExpression ) ) {
127+ const declaration = bootstrapCallExpression . declarationList . declarations [ 0 ] ;
128+ const bootstrapVar = ( declaration . name as ts . Identifier ) . text ;
129+ const sf = bootstrapCallExpression . getSourceFile ( ) ;
130+ bootstrapCall = findCallExpressionNode ( sf , bootstrapVar ) || currentCall ;
131+ }
132+
133+ // indent contents
134+ const triviaWidth = bootstrapCall . getLeadingTriviaWidth ( ) ;
135+ const beforeText = `document.addEventListener('DOMContentLoaded', () => {\n`
136+ + ' ' . repeat ( triviaWidth > 2 ? triviaWidth + 1 : triviaWidth ) ;
137+ const afterText = `\n${ triviaWidth > 2 ? ' ' . repeat ( triviaWidth - 1 ) : '' } );` ;
138+
139+ // in some cases we need to cater for a trailing semicolon such as;
140+ // bootstrap().catch(err => console.log(err));
141+ const lastToken = bootstrapCall . parent . getLastToken ( ) ;
142+ let endPos = bootstrapCall . getEnd ( ) ;
143+ if ( lastToken && lastToken . kind === ts . SyntaxKind . SemicolonToken ) {
144+ endPos = lastToken . getEnd ( ) ;
145+ }
146+
124147 const recorder = host . beginUpdate ( mainPath ) ;
125- const beforeText = `document.addEventListener('DOMContentLoaded', () => {\n ` ;
126- const afterText = `\n});` ;
127148 recorder . insertLeft ( bootstrapCall . getStart ( ) , beforeText ) ;
128- recorder . insertRight ( bootstrapCall . getEnd ( ) , afterText ) ;
149+ recorder . insertRight ( endPos , afterText ) ;
129150 host . commitUpdate ( recorder ) ;
130151 } ;
131152}
132153
154+ function findCallExpressionNode ( node : ts . Node , text : string ) : ts . Node | null {
155+ if (
156+ ts . isCallExpression ( node )
157+ && ts . isIdentifier ( node . expression )
158+ && node . expression . text === text
159+ ) {
160+ return node ;
161+ }
162+
163+ let foundNode : ts . Node | null = null ;
164+ ts . forEachChild ( node , childNode => {
165+ foundNode = findCallExpressionNode ( childNode , text ) ;
166+
167+ if ( foundNode ) {
168+ return true ;
169+ }
170+ } ) ;
171+
172+ return foundNode ;
173+ }
174+
133175function addServerTransition ( options : UniversalOptions ) : Rule {
134176 return ( host : Tree ) => {
135177 const clientProject = getProject ( host , options . clientProject ) ;
0 commit comments