88 getPythonTransformers ,
99 getMultifileJSXTransformers
1010} from './transformers.js' ;
11+ import { setupTSCompiler } from './typescript-worker-handler.js' ;
1112
1213interface Source {
1314 index : string ;
@@ -165,6 +166,39 @@ type BuildResult = {
165166 error ?: unknown ;
166167} ;
167168
169+ function hasTS ( challengeFiles : ChallengeFile [ ] ) {
170+ return challengeFiles . some (
171+ challengeFile => challengeFile . ext === 'ts' || challengeFile . ext === 'tsx'
172+ ) ;
173+ }
174+
175+ const isTSConfig = ( f : { name : string ; ext : string } ) =>
176+ f . name === 'tsconfig' && f . ext === 'json' ;
177+
178+ export function getTSConfig ( challengeFiles : ChallengeFile [ ] ) {
179+ const tsConfigFiles = challengeFiles . filter ( isTSConfig ) ;
180+
181+ if ( tsConfigFiles . length > 1 ) {
182+ throw new Error (
183+ 'TypeScript challenge must include only one tsconfig.json file'
184+ ) ;
185+ }
186+
187+ return tsConfigFiles . length === 1 ? tsConfigFiles [ 0 ] . contents : null ;
188+ }
189+
190+ async function configureTSCompiler ( challengeFiles : ChallengeFile [ ] ) {
191+ if ( hasTS ( challengeFiles ) ) {
192+ const tsConfig = getTSConfig ( challengeFiles ) ;
193+
194+ if ( tsConfig ) {
195+ await setupTSCompiler ( tsConfig ) ;
196+ } else {
197+ await setupTSCompiler ( ) ;
198+ }
199+ }
200+ }
201+
168202// TODO: All the buildXChallenge files have a similar structure, so make that
169203// abstraction (function, class, whatever) and then create the various functions
170204// out of it.
@@ -182,20 +216,18 @@ async function buildDOMChallenge(
182216 const hasJsx = challengeFiles . some (
183217 challengeFile => challengeFile . ext === 'jsx' || challengeFile . ext === 'tsx'
184218 ) ;
185- const isMultifile = challengeFiles . length > 1 ;
186-
187- const requiresReact16 = required . some ( ( { src } ) =>
188- src ?. includes ( 'https://cdnjs.cloudflare.com/ajax/libs/react/16.' )
189- ) ;
190219
220+ await configureTSCompiler ( challengeFiles ) ;
221+ const sourceFiles = challengeFiles . filter ( file => ! isTSConfig ( file ) ) ;
222+ const isMultifile = sourceFiles . length > 1 ;
191223 // I'm reasonably sure this is fine, but we need to migrate transformers to
192224 // TypeScript to be sure.
193225 const transformers : ApplyFunctionProps [ ] = ( isMultifile && hasJsx
194226 ? getMultifileJSXTransformers ( options )
195227 : getTransformers ( options ) ) as unknown as ApplyFunctionProps [ ] ;
196228
197229 const pipeLine = composeFunctions ( ...transformers ) ;
198- const finalFiles = await Promise . all ( challengeFiles . map ( pipeLine ) ) ;
230+ const finalFiles = await Promise . all ( sourceFiles . map ( pipeLine ) ) ;
199231 const error = finalFiles . find ( ( { error } ) => error ) ?. error ;
200232 const contents = ( await embedFilesInHtml ( finalFiles ) ) as string ;
201233
@@ -209,6 +241,10 @@ async function buildDOMChallenge(
209241 contents
210242 } ;
211243
244+ const requiresReact16 = required . some ( ( { src } ) =>
245+ src ?. includes ( 'https://cdnjs.cloudflare.com/ajax/libs/react/16.' )
246+ ) ;
247+
212248 return {
213249 challengeType,
214250 build : concatHtml ( toBuild ) ,
@@ -230,7 +266,9 @@ async function buildJSChallenge(
230266 ...( getTransformers ( options ) as unknown as ApplyFunctionProps [ ] )
231267 ) ;
232268
233- const finalFiles = await Promise . all ( challengeFiles ?. map ( pipeLine ) ) ;
269+ await configureTSCompiler ( challengeFiles ) ;
270+ const sourceFiles = challengeFiles . filter ( file => ! isTSConfig ( file ) ) ;
271+ const finalFiles = await Promise . all ( sourceFiles ?. map ( pipeLine ) ) ;
234272 const error = finalFiles . find ( ( { error } ) => error ) ?. error ;
235273
236274 const toBuild = error ? [ ] : finalFiles ;
0 commit comments