Skip to content

Commit 07d2cc8

Browse files
Copilotkobenguyent
andcommitted
Add TypeScript transpilation support for custom helpers
Co-authored-by: kobenguyent <7845001+kobenguyent@users.noreply.github.com>
1 parent 9ef01ef commit 07d2cc8

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed
File renamed without changes.
File renamed without changes.

lib/container.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,20 +398,52 @@ async function requireHelperFromModule(helperName, config, HelperClass) {
398398
throw err
399399
}
400400
} else {
401+
// Handle TypeScript files
402+
let importPath = moduleName
403+
let tempJsFile = null
404+
const ext = path.extname(moduleName)
405+
406+
if (ext === '.ts') {
407+
try {
408+
// Use the TypeScript transpilation utility
409+
const typescript = await import('typescript')
410+
const { tempFile, allTempFiles } = await transpileTypeScript(importPath, typescript)
411+
412+
debug(`Transpiled TypeScript helper: ${importPath} -> ${tempFile}`)
413+
414+
importPath = tempFile
415+
tempJsFile = allTempFiles
416+
} catch (tsError) {
417+
throw new Error(`Failed to load TypeScript helper ${importPath}: ${tsError.message}. Make sure 'typescript' package is installed.`)
418+
}
419+
}
420+
401421
// check if the new syntax export default HelperName is used and loads the Helper, otherwise loads the module that used old syntax export = HelperName.
402422
try {
403423
// Try dynamic import for both CommonJS and ESM modules
404-
const mod = await import(moduleName)
424+
const mod = await import(importPath)
405425
if (!mod && !mod.default) {
406426
throw new Error(`Helper module '${moduleName}' was not found. Make sure you have installed the package correctly.`)
407427
}
408428
HelperClass = mod.default || mod
429+
430+
// Clean up temp files if created
431+
if (tempJsFile) {
432+
const filesToClean = Array.isArray(tempJsFile) ? tempJsFile : [tempJsFile]
433+
cleanupTempFiles(filesToClean)
434+
}
409435
} catch (err) {
436+
// Clean up temp files before rethrowing
437+
if (tempJsFile) {
438+
const filesToClean = Array.isArray(tempJsFile) ? tempJsFile : [tempJsFile]
439+
cleanupTempFiles(filesToClean)
440+
}
441+
410442
if (err.code === 'ERR_REQUIRE_ESM' || (err.message && err.message.includes('ES module'))) {
411443
// This is an ESM module, use dynamic import
412444
try {
413445
const pathModule = await import('path')
414-
const absolutePath = pathModule.default.resolve(moduleName)
446+
const absolutePath = pathModule.default.resolve(importPath)
415447
const mod = await import(absolutePath)
416448
HelperClass = mod.default || mod
417449
debug(`helper ${helperName} loaded via ESM import`)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// TypeScript custom helper for testing
2+
class CustomHelper {
3+
constructor(config: any) {
4+
this.config = config
5+
}
6+
7+
config: any
8+
9+
customMethod(): string {
10+
return 'TypeScript helper loaded successfully'
11+
}
12+
13+
async asyncCustomMethod(): Promise<string> {
14+
return 'Async TypeScript helper method'
15+
}
16+
}
17+
18+
export default CustomHelper

test/unit/container_test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,5 +350,23 @@ describe('Container', () => {
350350
expect(I.loadModule).to.be.a('function')
351351
// The test verifies that the file loads without "ReferenceError: require is not defined"
352352
})
353+
354+
it('should load TypeScript custom helper', async () => {
355+
const tsHelperPath = path.join(__dirname, '../data/typescript-support/CustomHelper.ts')
356+
await container.create({
357+
helpers: {
358+
CustomHelper: {
359+
require: tsHelperPath,
360+
},
361+
},
362+
})
363+
await container.started()
364+
365+
const helper = container.helpers('CustomHelper')
366+
expect(helper).to.be.ok
367+
expect(helper.customMethod).to.be.a('function')
368+
expect(helper.customMethod()).to.eql('TypeScript helper loaded successfully')
369+
expect(helper.asyncCustomMethod).to.be.a('function')
370+
})
353371
})
354372
})

0 commit comments

Comments
 (0)