1- const { join, dirname, basename } = require ( "path" )
2- const { readFileSync, existsSync, mkdirSync, createWriteStream, readdirSync, lstatSync, rmSync } = require ( 'fs' )
1+ const { join, dirname, basename } = require ( 'path' )
2+ const {
3+ readFileSync,
4+ existsSync,
5+ mkdirSync,
6+ createWriteStream,
7+ readdirSync,
8+ lstatSync,
9+ rmSync,
10+ writeFileSync
11+ } = require ( 'fs' )
312const { spawn } = require ( 'child_process' )
413
514const esbuild = require ( 'esbuild' )
615const { copy } = require ( 'esbuild-plugin-copy' )
716const fs = require ( 'fs' )
17+ const ts = require ( 'typescript' )
818
9- async function execProcess ( cmd , logFile , args , buildDir = '.build' ) {
19+ async function execProcess ( cmd , logFile , args , buildDir = '.build' ) {
1020 let compileRoot = dirname ( dirname ( process . argv [ 1 ] ) )
11- console . log ( 'Running from' , )
12- console . log ( " Compiling...\n" , process . cwd ( ) , args )
21+ console . log ( 'Running from' )
22+ console . log ( ' Compiling...\n' , process . cwd ( ) , args )
1323
1424 if ( ! existsSync ( join ( process . cwd ( ) , buildDir ) ) ) {
1525 mkdirSync ( join ( process . cwd ( ) , buildDir ) )
@@ -20,7 +30,6 @@ async function execProcess(cmd, logFile, args, buildDir= '.build') {
2030 const stdoutFilePath = `${ buildDir } /${ logFile } .log`
2131 const stderrFilePath = `${ buildDir } /${ logFile } -err.log`
2232
23-
2433 const outPromise = new Promise ( ( resolve ) => {
2534 if ( compileOut . stdout != null ) {
2635 let outPipe = createWriteStream ( stdoutFilePath )
@@ -48,7 +57,7 @@ async function execProcess(cmd, logFile, args, buildDir= '.build') {
4857 } )
4958
5059 let editCode = 0
51- const closePromise = new Promise ( resolve => {
60+ const closePromise = new Promise ( ( resolve ) => {
5261 compileOut . on ( 'close' , ( code ) => {
5362 editCode = code
5463 resolve ( )
@@ -90,8 +99,8 @@ function collectFiles(source) {
9099 return result
91100}
92101
93- function collectFileStats ( source , result ) {
94- if ( ! existsSync ( source ) ) {
102+ function collectFileStats ( source , result ) {
103+ if ( ! existsSync ( source ) ) {
95104 return
96105 }
97106 const files = readdirSync ( source )
@@ -111,8 +120,8 @@ function collectFileStats(source, result) {
111120}
112121
113122function cleanNonModified ( before , after ) {
114- for ( const [ k , v ] of Object . entries ( before ) ) {
115- if ( after [ k ] === v ) {
123+ for ( const [ k , v ] of Object . entries ( before ) ) {
124+ if ( after [ k ] === v ) {
116125 // Same modify date, looks like not modified
117126 console . log ( 'clean file' , k )
118127 rmSync ( k )
@@ -132,9 +141,8 @@ switch (args[0]) {
132141 const after = { }
133142 collectFileStats ( 'lib' , before )
134143
135- performESBuild ( filesToTranspile )
136- . then ( ( ) => {
137- console . log ( "Transpile time: " , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
144+ performESBuild ( filesToTranspile ) . then ( ( ) => {
145+ console . log ( 'Transpile time: ' , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
138146 collectFileStats ( 'lib' , after )
139147 cleanNonModified ( before , after )
140148 } )
@@ -143,22 +151,16 @@ switch (args[0]) {
143151 case 'validate' : {
144152 let st = performance . now ( )
145153 validateTSC ( st ) . then ( ( ) => {
146- console . log ( " Validate time: " , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
154+ console . log ( ' Validate time: ' , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
147155 } )
148156 break
149157 }
150158 default : {
151159 let st = performance . now ( )
152160 const filesToTranspile = collectFiles ( join ( process . cwd ( ) , 'src' ) )
153- Promise . all (
154- [
155- performESBuild ( filesToTranspile ) ,
156- validateTSC ( )
157- ]
158- )
159- . then ( ( ) => {
160- console . log ( "Full build time: " , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
161- } )
161+ Promise . all ( [ performESBuild ( filesToTranspile ) , validateTSC ( ) ] ) . then ( ( ) => {
162+ console . log ( 'Full build time: ' , Math . round ( ( performance . now ( ) - st ) * 100 ) / 100 )
163+ } )
162164 break
163165 }
164166}
@@ -180,7 +182,7 @@ async function performESBuild(filesToTranspile) {
180182 resolveFrom : 'cwd' ,
181183 assets : {
182184 from : [ args [ 1 ] + '/**/*.json' ] ,
183- to : [ './lib' ] ,
185+ to : [ './lib' ]
184186 } ,
185187 watch : false
186188 } )
@@ -189,15 +191,67 @@ async function performESBuild(filesToTranspile) {
189191}
190192
191193async function validateTSC ( st ) {
192- await execProcess (
193- 'tsc' ,
194- 'validate' ,
195- [
196- '-pretty' ,
197- "--emitDeclarationOnly" ,
198- "--incremental" ,
199- "--tsBuildInfoFile" , ".validate/tsBuildInfoFile.info" ,
200- ...args . splice ( 1 )
201- ] , '.validate' )
202- }
194+ const buildDir = '.validate'
195+
196+ if ( ! existsSync ( buildDir ) ) {
197+ mkdirSync ( buildDir , { recursive : true } )
198+ }
199+
200+ const stdoutFilePath = `${ buildDir } /validate.log`
201+ const stderrFilePath = `${ buildDir } /validate-err.log`
202+
203+ // Read tsconfig.json
204+ const configPath = ts . findConfigFile ( process . cwd ( ) , ts . sys . fileExists , 'tsconfig.json' )
205+
206+ if ( ! configPath ) {
207+ console . error ( 'Could not find tsconfig.json' )
208+ process . exit ( 1 )
209+ }
210+
211+ const configFile = ts . readConfigFile ( configPath , ts . sys . readFile )
212+ const parsedConfig = ts . parseJsonConfigFileContent ( configFile . config , ts . sys , process . cwd ( ) , {
213+ emitDeclarationOnly : true ,
214+ incremental : true ,
215+ tsBuildInfoFile : join ( buildDir , 'tsBuildInfoFile.info' )
216+ } )
217+
218+ // Create the TypeScript program
219+ const program = ts . createProgram ( {
220+ rootNames : parsedConfig . fileNames ,
221+ options : parsedConfig . options
222+ } )
223+
224+ // Get diagnostics
225+ const emitResult = program . emit ( )
226+ const allDiagnostics = ts . getPreEmitDiagnostics ( program ) . concat ( emitResult . diagnostics )
227+
228+ const stdout = [ ]
229+ const stderr = [ ]
230+
231+ // Format diagnostics
232+ allDiagnostics . forEach ( ( diagnostic ) => {
233+ if ( diagnostic . file ) {
234+ const { line, character } = ts . getLineAndCharacterOfPosition ( diagnostic . file , diagnostic . start )
235+ const message = ts . flattenDiagnosticMessageText ( diagnostic . messageText , '\n' )
236+ const output = `${ diagnostic . file . fileName } (${ line + 1 } ,${ character + 1 } ): error TS${ diagnostic . code } : ${ message } `
237+ stderr . push ( output )
238+ } else {
239+ const message = ts . flattenDiagnosticMessageText ( diagnostic . messageText , '\n' )
240+ stderr . push ( `error TS${ diagnostic . code } : ${ message } ` )
241+ }
242+ } )
243+
244+ // Write logs
245+ writeFileSync ( stdoutFilePath , stdout . join ( '\n' ) )
246+ writeFileSync ( stderrFilePath , stderr . join ( '\n' ) )
247+
248+ if ( allDiagnostics . length > 0 ) {
249+ console . error ( '\n' + stderr . join ( '\n' ) )
250+ process . exit ( 1 )
251+ }
203252
253+ const exitCode = emitResult . emitSkipped ? 1 : 0
254+ if ( exitCode !== 0 ) {
255+ process . exit ( exitCode )
256+ }
257+ }
0 commit comments