require "tmpdir" require "tempfile" require "typescript-src" require "typescript-node/version" require "typescript-node/compile_result" require "open3" module TypeScript module Node class << self def tsc_version TypeScript::Src.version end def tsc(*args) cmd = [node, Src.tsc_path.to_s, *args] Open3.capture3(*cmd) end # Compile TypeScript source file. # @param [String] source_file TypeScript source file # @return [TypeScript::Node::CompileResult] compile result def compile_file(source_file, *tsc_options) Dir.mktmpdir do |output_dir| output_file = File.join(output_dir, "out.js") stdout, stderr, exit_status = tsc(*tsc_options, '--out', output_file, source_file) output_js = File.exists?(output_file) ? File.read(output_file) : nil CompileResult.new( output_js, exit_status, stdout, stderr, ) end end # Compile TypeScript to JavaScript. # @param [String] source TypeScript to be compiled # @return [String] Resulted JavaScript def compile(source, *tsc_options) js_file = Tempfile.new(["typescript-node", ".ts"]) begin js_file.write(source) js_file.close result = compile_file(js_file.path, *tsc_options) if result.success? result.js else raise result.stderr end ensure js_file.unlink end end # node command # TS_NODE environmental variable is used when it is set. def node ENV["TS_NODE"] || "node" end def locate_executable(cmd) if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && File.extname(cmd) == "" cmd << ".exe" end if File.executable? cmd cmd else path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |p| full_path = File.join(p, cmd) File.executable?(full_path) && File.file?(full_path) } path && File.expand_path(cmd, path) end end def check_node unless locate_executable(node) raise "typescript-node requires node command, but it's not found. Please install it. " + "Set TS_NODE environmental variable If you want to use node command in non-standard path." end end end end end TypeScript::Node.check_node