Skip to content

Commit ec6db29

Browse files
committed
fix: add TypeScript support for steps_file.ts and support objects
- Added transpilation of .ts files using TypeScript compiler - Creates temporary .mjs file to load transpiled code - Cleans up temporary files after loading - Fixes 'Unknown file extension .ts' error when using steps_file.ts
1 parent 050669a commit ec6db29

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

lib/container.js

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { globSync } from 'glob'
22
import path from 'path'
3+
import fs from 'fs'
34
import debugModule from 'debug'
45
const debug = debugModule('codeceptjs:container')
56
import { MetaStep } from './step.js'
@@ -674,12 +675,65 @@ async function loadSupportObject(modulePath, supportObjectName) {
674675
try {
675676
// Use dynamic import for both ESM and CJS modules
676677
let importPath = modulePath
677-
// Append .js if no extension provided (ESM resolution requires it)
678+
let tempJsFile = null
679+
678680
if (typeof importPath === 'string') {
679681
const ext = path.extname(importPath)
680-
if (!ext) importPath = `${importPath}.js`
682+
683+
// Handle TypeScript files
684+
if (ext === '.ts') {
685+
try {
686+
const { transpile } = await import('typescript')
687+
const tsContent = fs.readFileSync(importPath, 'utf8')
688+
689+
// Transpile TypeScript to JavaScript with ES module output
690+
const jsContent = transpile(tsContent, {
691+
module: 99, // ModuleKind.ESNext
692+
target: 99, // ScriptTarget.ESNext
693+
esModuleInterop: true,
694+
allowSyntheticDefaultImports: true,
695+
})
696+
697+
// Create a temporary JS file with .mjs extension to force ES module treatment
698+
tempJsFile = importPath.replace('.ts', '.temp.mjs')
699+
fs.writeFileSync(tempJsFile, jsContent)
700+
importPath = tempJsFile
701+
} catch (tsError) {
702+
throw new Error(`Failed to compile TypeScript file ${importPath}: ${tsError.message}`)
703+
}
704+
} else if (!ext) {
705+
// Append .js if no extension provided (ESM resolution requires it)
706+
importPath = `${importPath}.js`
707+
}
708+
}
709+
710+
let obj
711+
try {
712+
obj = await import(importPath)
713+
} catch (importError) {
714+
// Clean up temp file if created before rethrowing
715+
if (tempJsFile) {
716+
try {
717+
if (fs.existsSync(tempJsFile)) {
718+
fs.unlinkSync(tempJsFile)
719+
}
720+
} catch (cleanupError) {
721+
// Ignore cleanup errors
722+
}
723+
}
724+
throw importError
725+
} finally {
726+
// Clean up temp file if created
727+
if (tempJsFile) {
728+
try {
729+
if (fs.existsSync(tempJsFile)) {
730+
fs.unlinkSync(tempJsFile)
731+
}
732+
} catch (cleanupError) {
733+
// Ignore cleanup errors
734+
}
735+
}
681736
}
682-
const obj = await import(importPath)
683737

684738
// Handle ESM module wrapper
685739
let actualObj = obj

0 commit comments

Comments
 (0)