import os from 'os' ; import path from 'path' ; import fs from 'fs' ; import child_process from 'child_process' ; import { Environment } from '@/application/Environment/Environment' ; import { OperatingSystem } from '@/domain/OperatingSystem' ; export class CodeRunner { constructor ( private readonly node = getNodeJs ( ) , private readonly environment = Environment . CurrentEnvironment ) { } public async runCode ( code , folderName , fileExtension ) { const dir = this . node . path . join ( this . node . os . tmpdir ( ) , folderName ) ; await this . node . fs . promises . mkdir ( dir , { recursive : true } ) ; const filePath = this . node . path . join ( dir , `run.${ fileExtension }` ) ; await this . node . fs . promises . writeFile ( filePath , code ) ; await this . node . fs . promises . chmod ( filePath , '755' ) ; const command = getExecuteCommand ( filePath , this . environment ) ; this . node . child_process . exec ( command ) ; } } function getExecuteCommand ( scriptPath , environment ) { switch ( environment . os ) { case OperatingSystem . macOS : return `open -a Terminal.app ${ scriptPath }` ; case OperatingSystem . Windows : return scriptPath ; default : throw Error ( 'undefined os' ) ; } } function getNodeJs ( ) { return { os , path , fs , child_process , } ; } export interface INodeJs { os : INodeOs ; path : INodePath ; fs : INodeFs ; child_process : INodeChildProcess ; } export interface INodeOs { tmpdir ( ) : string ; } export interface INodePath { join ( ... paths ) : string ; } export interface INodeChildProcess { exec ( command ) : void ; } export interface INodeFs { readonly promises : INodeFsPromises ; } interface INodeFsPromisesMakeDirectoryOptions { recursive ? : boolean ; } interface INodeFsPromises { chmod ( path , mode ) : Promise < void > ; mkdir ( path , options ) : Promise < string > ; writeFile ( path , data ) : Promise < void > ; }