2016-05-03 20:31:40 -04:00
|
|
|
#!/usr/bin/env node
|
2016-04-29 13:35:36 -04:00
|
|
|
|
|
|
|
// Must be imported first, because angular2 decorators throws on load.
|
|
|
|
import 'reflect-metadata';
|
|
|
|
|
|
|
|
import * as fs from 'fs';
|
|
|
|
import * as path from 'path';
|
|
|
|
import * as ts from 'typescript';
|
|
|
|
import {tsc, check} from './tsc';
|
2016-05-01 14:22:39 -04:00
|
|
|
import {MetadataWriterHost, TsickleHost} from './compiler_host';
|
|
|
|
import {NodeReflectorHost} from './reflector_host';
|
2016-04-29 13:35:36 -04:00
|
|
|
import {CodeGenerator} from './codegen';
|
2016-05-01 14:22:39 -04:00
|
|
|
import {MetadataCollector, ModuleMetadata} from 'ts-metadata-collector';
|
2016-04-29 13:35:36 -04:00
|
|
|
|
|
|
|
const DEBUG = false;
|
|
|
|
|
|
|
|
function debug(msg: string, ...o: any[]) {
|
|
|
|
if (DEBUG) console.log(msg, ...o);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function main(project: string, basePath?: string): Promise<any> {
|
2016-05-01 14:22:39 -04: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);
|
|
|
|
|
|
|
|
let codegenStep: Promise<any>;
|
|
|
|
|
|
|
|
const program = ts.createProgram(parsed.fileNames, parsed.options, host);
|
|
|
|
const errors = program.getOptionsDiagnostics();
|
|
|
|
check(errors);
|
|
|
|
|
2016-05-03 13:50:55 -04:00
|
|
|
const doCodegen = ngOptions.skipTemplateCodegen ?
|
|
|
|
Promise.resolve(null) :
|
|
|
|
CodeGenerator.create(ngOptions, program, parsed.options, host).codegen();
|
2016-05-01 14:22:39 -04:00
|
|
|
|
|
|
|
return doCodegen.then(() => {
|
|
|
|
tsc.typeCheck(host, program);
|
|
|
|
|
|
|
|
// Emit *.js with Decorators lowered to Annotations, and also *.js.map
|
|
|
|
const tsicklePreProcessor = new TsickleHost(host, parsed.options);
|
|
|
|
tsc.emit(tsicklePreProcessor, program);
|
|
|
|
|
|
|
|
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.
|
|
|
|
const metadataWriter = new MetadataWriterHost(host, program, parsed.options, ngOptions);
|
|
|
|
tsc.emit(metadataWriter, program);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (e) {
|
|
|
|
return Promise.reject(e);
|
|
|
|
}
|
2016-04-29 13:35:36 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// CLI entry point
|
|
|
|
if (require.main === module) {
|
|
|
|
const args = require('minimist')(process.argv.slice(2));
|
2016-05-01 14:22:39 -04:00
|
|
|
main(args.p || args.project || '.', args.basePath)
|
|
|
|
.then(exitCode => process.exit(exitCode))
|
|
|
|
.catch(e => {
|
|
|
|
console.error(e.stack);
|
|
|
|
console.error("Compilation failed");
|
|
|
|
process.exit(1);
|
|
|
|
});
|
2016-04-29 13:35:36 -04:00
|
|
|
}
|