Skip to content

Commit 95163ce

Browse files
authored
Added TypeScript support to the code interpreter (#91)
* added typescript support via SWC * added ts tests * changed target node version * minor nits by @0div * added test for typescript kernel failure * changed swc path in prod Dockerfile * added changeset * skip test here so that the template can be built
1 parent 120d097 commit 95163ce

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed

.changeset/tiny-adults-breathe.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@e2b/code-interpreter-template': patch
3+
---
4+
5+
added typescript support

js/tests/defaultKernels.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { expect } from 'vitest'
33
import { sandboxTest } from './setup'
44

55
sandboxTest('test js kernel', async ({ sandbox }) => {
6-
const output = await sandbox.runCode('console.log("Hello World!")', { language: 'js' })
6+
const output = await sandbox.runCode('console.log("Hello World!")', {
7+
language: 'js',
8+
})
79
expect(output.logs.stdout).toEqual(['Hello World!\n'])
810
})

template/.ts.swcrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
"targets": "node 20"
1313
},
1414
"isModule": false
15-
}
15+
}

template/server/contexts.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
logger = logging.Logger(__name__)
1313

14+
def get_kernel_for_language(language: str) -> str:
15+
if language == "typescript":
16+
return "javascript"
17+
18+
return language
1419

1520
def normalize_language(language: Optional[str]) -> str:
1621
if not language:
@@ -21,13 +26,16 @@ def normalize_language(language: Optional[str]) -> str:
2126
if language == "js":
2227
return "javascript"
2328

29+
if language == "ts":
30+
return "typescript"
31+
2432
return language
2533

2634

2735
async def create_context(client, websockets: dict, language: str, cwd: str) -> Context:
2836
data = {
2937
"path": str(uuid.uuid4()),
30-
"kernel": {"name": language},
38+
"kernel": {"name": get_kernel_for_language(language)},
3139
"type": "notebook",
3240
"name": str(uuid.uuid4()),
3341
}

template/server/messaging.py

+27-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import logging
44
import uuid
55
import asyncio
6+
import subprocess
67

78
from asyncio import Queue
89
from envs import get_envs
@@ -27,7 +28,6 @@
2728

2829
logger = logging.getLogger(__name__)
2930

30-
3131
class Execution:
3232
def __init__(self, in_background: bool = False):
3333
self.queue = Queue[
@@ -199,6 +199,32 @@ async def execute(
199199
+ code
200200
)
201201

202+
if self.language == "typescript":
203+
logger.info("Compiling TypeScript: %s", code)
204+
205+
# call SWC to compile the typescript code
206+
try:
207+
compile_result = subprocess.run("swc --config-file .ts.swcrc --filename index.ts".split(), input=code.encode(), capture_output=True)
208+
209+
if compile_result.returncode != 0:
210+
logger.error("Error during TypeScript compilation: %s", compile_result.stderr.decode())
211+
yield Error(
212+
name="TypeScriptCompilerError",
213+
value=compile_result.stderr.decode(),
214+
traceback="",
215+
)
216+
return
217+
218+
code = compile_result.stdout.decode()
219+
except Exception as e:
220+
logger.error("Error starting SWC process: %s", e)
221+
yield Error(
222+
name="TypeScriptCompilerError",
223+
value=str(e),
224+
traceback="",
225+
)
226+
return
227+
202228
logger.info(code)
203229
request = self._get_execute_request(message_id, code, False)
204230

0 commit comments

Comments
 (0)