| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  | import * as fs from 'fs'; | 
					
						
							|  |  |  | import * as path from 'path'; | 
					
						
							|  |  |  | import * as ts from 'typescript'; | 
					
						
							| 
									
										
										
										
											2016-06-08 11:14:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {check, tsc} from './tsc'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  | import NgOptions from './options'; | 
					
						
							|  |  |  | import {MetadataWriterHost, TsickleHost} from './compiler_host'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 10:45:37 -07:00
										 |  |  | export type CodegenExtension = (ngOptions: NgOptions, program: ts.Program, host: ts.CompilerHost) => | 
					
						
							| 
									
										
										
										
											2016-06-07 15:42:27 -07:00
										 |  |  |     Promise<void>; | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 10:45:37 -07:00
										 |  |  | export function main(project: string, basePath?: string, codegen?: CodegenExtension): Promise<any> { | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  |   try { | 
					
						
							|  |  |  |     let projectDir = project; | 
					
						
							|  |  |  |     if (fs.lstatSync(project).isFile()) { | 
					
						
							|  |  |  |       projectDir = path.dirname(project); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // file names in tsconfig are resolved relative to this absolute path
 | 
					
						
							|  |  |  |     basePath = path.join(process.cwd(), basePath || projectDir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // read the configuration options from wherever you store them
 | 
					
						
							|  |  |  |     const {parsed, ngOptions} = tsc.readConfiguration(project, basePath); | 
					
						
							|  |  |  |     ngOptions.basePath = basePath; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const host = ts.createCompilerHost(parsed.options, true); | 
					
						
							|  |  |  |     const program = ts.createProgram(parsed.fileNames, parsed.options, host); | 
					
						
							|  |  |  |     const errors = program.getOptionsDiagnostics(); | 
					
						
							|  |  |  |     check(errors); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ngOptions.skipTemplateCodegen || !codegen) { | 
					
						
							|  |  |  |       codegen = () => Promise.resolve(null); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return codegen(ngOptions, program, host).then(() => { | 
					
						
							| 
									
										
										
										
											2016-06-07 15:42:27 -07:00
										 |  |  |       // Create a new program since codegen files were created after making the old program
 | 
					
						
							|  |  |  |       const newProgram = ts.createProgram(parsed.fileNames, parsed.options, host, program); | 
					
						
							|  |  |  |       tsc.typeCheck(host, newProgram); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       // Emit *.js with Decorators lowered to Annotations, and also *.js.map
 | 
					
						
							| 
									
										
										
										
											2016-06-07 15:42:27 -07:00
										 |  |  |       const tsicklePreProcessor = new TsickleHost(host, newProgram); | 
					
						
							|  |  |  |       tsc.emit(tsicklePreProcessor, newProgram); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (!ngOptions.skipMetadataEmit) { | 
					
						
							|  |  |  |         // Emit *.metadata.json and *.d.ts
 | 
					
						
							|  |  |  |         // Not in the same emit pass with above, because tsickle erases
 | 
					
						
							|  |  |  |         // decorators which we want to read or document.
 | 
					
						
							|  |  |  |         // Do this emit second since TypeScript will create missing directories for us
 | 
					
						
							|  |  |  |         // in the standard emit.
 | 
					
						
							| 
									
										
										
										
											2016-06-07 15:42:27 -07:00
										 |  |  |         const metadataWriter = new MetadataWriterHost(host, newProgram); | 
					
						
							|  |  |  |         tsc.emit(metadataWriter, newProgram); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } catch (e) { | 
					
						
							|  |  |  |     return Promise.reject(e); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CLI entry point
 | 
					
						
							|  |  |  | if (require.main === module) { | 
					
						
							|  |  |  |   const args = require('minimist')(process.argv.slice(2)); | 
					
						
							|  |  |  |   main(args.p || args.project || '.', args.basePath) | 
					
						
							|  |  |  |       .then(exitCode => process.exit(exitCode)) | 
					
						
							|  |  |  |       .catch(e => { | 
					
						
							|  |  |  |         console.error(e.stack); | 
					
						
							| 
									
										
										
										
											2016-05-26 10:45:37 -07:00
										 |  |  |         console.error('Compilation failed'); | 
					
						
							| 
									
										
										
										
											2016-05-24 10:53:48 -07:00
										 |  |  |         process.exit(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | } |