1313#include " embedded_data.h"
1414#include " executable_wrapper.h"
1515#include " simdutf.h"
16+ #include " typescript_transpiler.h"
1617#include " uv.h"
1718
1819#if defined(_WIN32)
@@ -131,13 +132,14 @@ bool SearchFiles(const std::string& dir,
131132
132133constexpr std::string_view kMjsSuffix = " .mjs" ;
133134constexpr std::string_view kJsSuffix = " .js" ;
135+ constexpr std::string_view kTsSuffix = " .ts" ;
134136constexpr std::string_view kGypiSuffix = " .gypi" ;
135137constexpr std::string_view depsPrefix = " deps/" ;
136138constexpr std::string_view libPrefix = " lib/" ;
137139
138140constexpr std::string_view HasAllowedExtensions (
139141 const std::string_view filename) {
140- for (const auto & ext : {kGypiSuffix , kJsSuffix , kMjsSuffix }) {
142+ for (const auto & ext : {kGypiSuffix , kJsSuffix , kMjsSuffix , kTsSuffix }) {
141143 if (filename.ends_with (ext)) {
142144 return ext;
143145 }
@@ -329,11 +331,13 @@ std::string GetFileId(const std::string& filename) {
329331 size_t end = filename.size ();
330332 size_t start = 0 ;
331333 std::string prefix;
332- // Strip .mjs and .js suffix
334+ // Strip .mjs, .js and .ts suffix
333335 if (filename.ends_with (kMjsSuffix )) {
334336 end -= kMjsSuffix .size ();
335337 } else if (filename.ends_with (kJsSuffix )) {
336338 end -= kJsSuffix .size ();
339+ } else if (filename.ends_with (kTsSuffix )) {
340+ end -= kTsSuffix .size ();
337341 }
338342
339343 // deps/acorn/acorn/dist/acorn.js -> internal/deps/acorn/acorn/dist/acorn
@@ -670,6 +674,7 @@ Fragment GetDefinition(const std::string& var, const std::vector<char>& code) {
670674}
671675
672676int AddModule (const std::string& filename,
677+ TypeScriptTranspiler* transpiler,
673678 Fragments* definitions,
674679 Fragments* initializers,
675680 Fragments* registrations) {
@@ -684,6 +689,21 @@ int AddModule(const std::string& filename,
684689 if (error != 0 ) {
685690 return error;
686691 }
692+
693+ if (filename.ends_with (kTsSuffix )) {
694+ std::vector<char > transpiled;
695+ if (transpiler->Strip (std::string_view (code.data (), code.size ()),
696+ filename,
697+ &transpiled) != 0 ) {
698+ fprintf (stderr,
699+ " Failed to transpile TypeScript file %s: %s\n " ,
700+ filename.c_str (),
701+ std::string (transpiler->LastError ()).c_str ());
702+ return 1 ;
703+ }
704+ code = std::move (transpiled);
705+ }
706+
687707 std::string file_id = GetFileId (filename);
688708 std::string var = GetVariableName (file_id);
689709
@@ -826,23 +846,39 @@ int AddGypi(const std::string& var,
826846
827847int JS2C (const FileList& js_files,
828848 const FileList& mjs_files,
849+ const FileList& ts_files,
829850 const std::string& config,
851+ const char * argv0,
830852 const std::string& dest) {
853+ TypeScriptTranspiler transpiler;
831854 Fragments definitions;
832- definitions.reserve (js_files.size () + mjs_files.size () + 1 );
855+ definitions.reserve (js_files.size () + mjs_files.size () + ts_files. size () + 1 );
833856 Fragments initializers;
834- initializers.reserve (js_files.size () + mjs_files.size ());
857+ initializers.reserve (js_files.size () + mjs_files.size () + ts_files. size () );
835858 Fragments registrations;
836- registrations.reserve (js_files.size () + mjs_files.size () + 1 );
859+ registrations.reserve (js_files.size () + mjs_files.size () + ts_files.size () +
860+ 1 );
837861
838- for ( const auto & filename : js_files ) {
839- int r = AddModule (filename, &definitions, &initializers, ®istrations);
840- if (r != 0 ) {
841- return r ;
842- }
862+ if (!ts_files. empty () && transpiler. Initialize (argv0) != 0 ) {
863+ fprintf (stderr,
864+ " Failed to initialize TypeScript transpiler: %s \n " ,
865+ std::string (transpiler. LastError ()). c_str ()) ;
866+ return 1 ;
843867 }
844- for (const auto & filename : mjs_files) {
845- int r = AddModule (filename, &definitions, &initializers, ®istrations);
868+
869+ auto add_modules = [&](const FileList& files) {
870+ for (const auto & filename : files) {
871+ int r = AddModule (
872+ filename, &transpiler, &definitions, &initializers, ®istrations);
873+ if (r != 0 ) {
874+ return r;
875+ }
876+ }
877+ return 0 ;
878+ };
879+
880+ for (const auto * files : {&js_files, &mjs_files, &ts_files}) {
881+ int r = add_modules (*files);
846882 if (r != 0 ) {
847883 return r;
848884 }
@@ -910,7 +946,8 @@ int Main(int argc, char* argv[]) {
910946 const std::string& file = args[i];
911947 if (IsDirectory (file, &error)) {
912948 if (!SearchFiles (file, &file_map, kJsSuffix ) ||
913- !SearchFiles (file, &file_map, kMjsSuffix )) {
949+ !SearchFiles (file, &file_map, kMjsSuffix ) ||
950+ !SearchFiles (file, &file_map, kTsSuffix )) {
914951 return 1 ;
915952 }
916953 } else if (error != 0 ) {
@@ -927,8 +964,6 @@ int Main(int argc, char* argv[]) {
927964 }
928965 }
929966
930- // Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
931- assert (file_map.size () == 3 );
932967 auto gypi_it = file_map.find (" .gypi" );
933968 // Currently config.gypi is the only `.gypi` file allowed
934969 if (gypi_it == file_map.end () || gypi_it->second .size () != 1 ||
@@ -940,19 +975,37 @@ int Main(int argc, char* argv[]) {
940975 }
941976 auto js_it = file_map.find (" .js" );
942977 auto mjs_it = file_map.find (" .mjs" );
943- assert (js_it != file_map.end () && mjs_it != file_map.end ());
944-
945- auto it = std::find (mjs_it->second .begin (),
946- mjs_it->second .end (),
947- " lib/eslint.config_partial.mjs" );
948- if (it != mjs_it->second .end ()) {
949- mjs_it->second .erase (it);
978+ auto ts_it = file_map.find (" .ts" );
979+ if (mjs_it != file_map.end ()) {
980+ auto it = std::find (mjs_it->second .begin (),
981+ mjs_it->second .end (),
982+ " lib/eslint.config_partial.mjs" );
983+ if (it != mjs_it->second .end ()) {
984+ mjs_it->second .erase (it);
985+ }
950986 }
951987
952- std::sort (js_it->second .begin (), js_it->second .end ());
953- std::sort (mjs_it->second .begin (), mjs_it->second .end ());
988+ if (js_it != file_map.end ()) {
989+ std::sort (js_it->second .begin (), js_it->second .end ());
990+ }
991+ if (mjs_it != file_map.end ()) {
992+ std::sort (mjs_it->second .begin (), mjs_it->second .end ());
993+ }
994+ if (ts_it != file_map.end ()) {
995+ std::sort (ts_it->second .begin (), ts_it->second .end ());
996+ }
954997
955- return JS2C (js_it->second , mjs_it->second , gypi_it->second [0 ], output);
998+ static const FileList empty_list;
999+ const FileList& js_files =
1000+ js_it == file_map.end () ? empty_list : js_it->second ;
1001+ const FileList& mjs_files =
1002+ mjs_it == file_map.end () ? empty_list : mjs_it->second ;
1003+ return JS2C (js_files,
1004+ mjs_files,
1005+ ts_it == file_map.end () ? empty_list : ts_it->second ,
1006+ gypi_it->second [0 ],
1007+ argv[0 ],
1008+ output);
9561009}
9571010} // namespace js2c
9581011} // namespace node
0 commit comments