1+ #!/usr/bin/env node
2+
3+ import fs from 'fs' ;
4+ import path from 'path' ;
5+ import axios from 'axios' ;
6+ import { program } from 'commander' ;
7+ import dotenv from 'dotenv' ;
8+ import { languageOptions } from '../src/utils/constant.js' ;
9+
10+ dotenv . config ( ) ;
11+
12+ program
13+ . name ( 'tech-run' )
14+ . description ( 'Execute code files via Tech Compiler API' )
15+ . version ( '1.0.0' )
16+ . argument ( '<file>' , 'File to execute' )
17+ . option ( '-l, --language <lang>' , 'Programming language (e.g., python, javascript, cpp)' )
18+ . action ( async ( file , options ) => {
19+ try {
20+ const filePath = path . resolve ( file ) ;
21+ if ( ! fs . existsSync ( filePath ) ) {
22+ console . error ( `Error: File not found at ${ filePath } ` ) ;
23+ process . exit ( 1 ) ;
24+ }
25+
26+ const sourceCode = fs . readFileSync ( filePath , 'utf-8' ) ;
27+
28+ const ext = path . extname ( file ) . replace ( '.' , '' ) ;
29+ const langKey = options . language || mapExtensionToLanguage ( ext ) ;
30+
31+ const selectedLanguage = languageOptions [ langKey ] ;
32+ if ( ! selectedLanguage ) {
33+ console . error ( `Error: Unsupported language "${ langKey } ". Use -l to specify.` ) ;
34+ process . exit ( 1 ) ;
35+ }
36+
37+ console . log ( `Running ${ file } (${ selectedLanguage . name } )...` ) ;
38+ await runCode ( selectedLanguage . id , sourceCode ) ;
39+
40+ } catch ( err ) {
41+ console . error ( 'CLI Error:' , err . message ) ;
42+ }
43+ } ) ;
44+
45+ function mapExtensionToLanguage ( ext ) {
46+ const map = {
47+ 'js' : 'javascript' ,
48+ 'py' : 'python' ,
49+ 'cpp' : 'cpp' ,
50+ 'c' : 'c' ,
51+ 'java' : 'java' ,
52+ 'rb' : 'ruby' ,
53+ 'go' : 'go'
54+ } ;
55+ return map [ ext ] || null ;
56+ }
57+
58+ async function runCode ( languageId , code ) {
59+ const apiKey = process . env . VITE_API_TOKENS
60+ ? JSON . parse ( process . env . VITE_API_TOKENS ) [ 0 ]
61+ : "YOUR_FALLBACK_KEY" ;
62+
63+ const host = process . env . VITE_RAP_API_HOST || "judge0-ce.p.rapidapi.com" ;
64+ const url = process . env . VITE_RAPID_API_URL || "https://judge0-ce.p.rapidapi.com/submissions" ;
65+
66+ try {
67+ const response = await axios . post ( url , {
68+ language_id : languageId ,
69+ source_code : Buffer . from ( code ) . toString ( 'base64' ) ,
70+ } , {
71+ params : { base64_encoded : "true" , fields : "*" } ,
72+ headers : {
73+ "content-type" : "application/json" ,
74+ "X-RapidAPI-Host" : host ,
75+ "X-RapidAPI-Key" : apiKey ,
76+ }
77+ } ) ;
78+
79+ const token = response . data . token ;
80+
81+ let result = null ;
82+ while ( ! result ) {
83+ const statusRes = await axios . get ( `${ url } /${ token } ` , {
84+ params : { base64_encoded : "true" , fields : "*" } ,
85+ headers : { "X-RapidAPI-Host" : host , "X-RapidAPI-Key" : apiKey }
86+ } ) ;
87+
88+ const statusId = statusRes . data . status ?. id ;
89+ if ( statusId > 2 ) {
90+ result = statusRes . data ;
91+ } else {
92+ await new Promise ( res => setTimeout ( res , 1000 ) ) ;
93+ }
94+ }
95+
96+ if ( result . stdout ) console . log ( Buffer . from ( result . stdout , 'base64' ) . toString ( ) ) ;
97+ if ( result . stderr ) console . error ( 'Error:' , Buffer . from ( result . stderr , 'base64' ) . toString ( ) ) ;
98+ if ( result . compile_output ) console . error ( 'Compile Error:' , Buffer . from ( result . compile_output , 'base64' ) . toString ( ) ) ;
99+
100+ } catch ( error ) {
101+ console . error ( 'Execution Failed:' , error . response ?. data ?. message || error . message ) ;
102+ }
103+ }
104+
105+ program . parse ( ) ;
0 commit comments