import * as ts from 'typescript' ; import * as fs from 'fs-extra' ; import * as _ from 'lodash' ; import * as path from 'path' ; export function makeDefaultTypescriptConfig ( ) { const defaultTypescriptConfig = { preserveConstEnums : true , strictNullChecks : true , sourceMap : true , allowJs : true , target : ts . ScriptTarget . ES5 , moduleResolution : ts . ModuleResolutionKind . NodeJs , lib : [ 'lib.es2015.d.ts' ] , rootDir : './' , } ; return defaultTypescriptConfig ; } export function extractFileNames ( cwd , provider , functions ? ) { if ( provider === 'google' ) { const packageFilePath = path . join ( cwd , 'package.json' ) ; if ( fs . existsSync ( packageFilePath ) ) { const packageFile = JSON . parse ( fs . readFileSync ( packageFilePath ) . toString ( ) ) ; const main = packageFile . main ? packageFile . main . replace ( /\.js$/ , '.ts' ) : 'index.ts' ; if ( ! fs . existsSync ( path . join ( cwd , main ) ) ) { console . log ( `Cannot locate entrypoint, ${ main } not found` ) ; throw new Error ( 'Typescript compilation failed' ) ; } return [ main ] ; } } return _ . values ( functions ) . map ( fn => fn . handler ) . map ( h => { const fnName = _ . last ( h . split ( '.' ) ) ; const fnNameLastAppearanceIndex = h . lastIndexOf ( fnName ) ; const fileName = h . substring ( 0 , fnNameLastAppearanceIndex ) ; if ( fs . existsSync ( path . join ( cwd , fileName + 'ts' ) ) ) { return fileName + 'ts' ; } if ( fs . existsSync ( path . join ( cwd , fileName + 'js' ) ) ) { return fileName + 'js' ; } console . log ( `Cannot locate handler - ${ fileName } not found` ) ; throw new Error ( 'Typescript compilation failed. Please ensure handlers exists with ext .ts or .js' ) ; } ) ; } export async function run ( fileNames , options ) { options . listEmittedFiles = true ; const program = ts . createProgram ( fileNames , options ) ; const emitResult = program . emit ( ) ; const allDiagnostics = ts . getPreEmitDiagnostics ( program ) . concat ( emitResult . diagnostics ) ; allDiagnostics . forEach ( diagnostic => { if ( ! diagnostic . file ) { console . log ( diagnostic ) ; } const { line , character } = diagnostic . file . getLineAndCharacterOfPosition ( diagnostic . start ) ; const message = ts . flattenDiagnosticMessageText ( diagnostic . messageText , '\n' ) ; console . log ( `${ diagnostic . file . fileName } (${ line + 1 },${ character + 1 }): ${ message }` ) ; } ) ; if ( emitResult . emitSkipped ) { throw new Error ( 'Typescript compilation failed' ) ; } return emitResult . emittedFiles . filter ( filename => filename . endsWith ( '.js' ) ) ; } export function getSourceFiles ( rootFileNames , options ) { const program = ts . createProgram ( rootFileNames , options ) ; const programmFiles = program . getSourceFiles ( ) . map ( file => file . fileName ) . filter ( file => { return file . split ( path . sep ) . indexOf ( 'node_modules' ) < 0 ; } ) ; return programmFiles ; } export function getTypescriptConfig ( cwd , tsConfigFileLocation = 'tsconfig.json' , logger ? ) { const configFilePath = path . join ( cwd , tsConfigFileLocation ) ; if ( fs . existsSync ( configFilePath ) ) { const configFileText = fs . readFileSync ( configFilePath ) . toString ( ) ; const result = ts . parseConfigFileTextToJson ( configFilePath , configFileText ) ; if ( result . error ) { try { throw new Error ( JSON . stringify ( result . error ) ) ; } catch ( err ) { throw new Error ( 'Invalid TSConfig file - is this file JSON format?' ) ; } } const configParseResult = ts . parseJsonConfigFileContent ( result . config , ts . sys , path . dirname ( configFilePath ) ) ; if ( configParseResult . errors . length > 0 ) { throw new Error ( JSON . stringify ( configParseResult . errors ) ) ; } if ( logger ) { logger . log ( `Using local tsconfig.json - ${ tsConfigFileLocation }` ) ; } if ( configParseResult . options . rootDir && path . resolve ( configParseResult . options . rootDir ) !== path . resolve ( cwd ) && logger ) { logger . log ( 'Warning: "rootDir" from local tsconfig.json is overriden' ) ; } configParseResult . options . rootDir = cwd ; return configParseResult . options ; } return makeDefaultTypescriptConfig ( ) ; }