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,20 @@ 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+ std::string source (code.begin (), code.end ());
696+ if (transpiler->Strip (source, filename, &transpiled) != 0 ) {
697+ fprintf (stderr,
698+ " Failed to transpile TypeScript file %s: %s\n " ,
699+ filename.c_str (),
700+ transpiler->LastError ().c_str ());
701+ return 1 ;
702+ }
703+ code = std::move (transpiled);
704+ }
705+
687706 std::string file_id = GetFileId (filename);
688707 std::string var = GetVariableName (file_id);
689708
@@ -826,23 +845,44 @@ int AddGypi(const std::string& var,
826845
827846int JS2C (const FileList& js_files,
828847 const FileList& mjs_files,
848+ const FileList& ts_files,
829849 const std::string& config,
850+ const char * argv0,
830851 const std::string& dest) {
852+ TypeScriptTranspiler transpiler;
831853 Fragments definitions;
832- definitions.reserve (js_files.size () + mjs_files.size () + 1 );
854+ definitions.reserve (
855+ 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 (
860+ js_files.size () + mjs_files.size () + ts_files.size () + 1 );
861+
862+ if (!ts_files.empty () && transpiler.Initialize (argv0) != 0 ) {
863+ fprintf (stderr,
864+ " Failed to initialize TypeScript transpiler: %s\n " ,
865+ transpiler.LastError ().c_str ());
866+ return 1 ;
867+ }
837868
838869 for (const auto & filename : js_files) {
839- int r = AddModule (filename, &definitions, &initializers, ®istrations);
870+ int r = AddModule (
871+ filename, &transpiler, &definitions, &initializers, ®istrations);
840872 if (r != 0 ) {
841873 return r;
842874 }
843875 }
844876 for (const auto & filename : mjs_files) {
845- int r = AddModule (filename, &definitions, &initializers, ®istrations);
877+ int r = AddModule (
878+ filename, &transpiler, &definitions, &initializers, ®istrations);
879+ if (r != 0 ) {
880+ return r;
881+ }
882+ }
883+ for (const auto & filename : ts_files) {
884+ int r = AddModule (
885+ filename, &transpiler, &definitions, &initializers, ®istrations);
846886 if (r != 0 ) {
847887 return r;
848888 }
@@ -910,7 +950,8 @@ int Main(int argc, char* argv[]) {
910950 const std::string& file = args[i];
911951 if (IsDirectory (file, &error)) {
912952 if (!SearchFiles (file, &file_map, kJsSuffix ) ||
913- !SearchFiles (file, &file_map, kMjsSuffix )) {
953+ !SearchFiles (file, &file_map, kMjsSuffix ) ||
954+ !SearchFiles (file, &file_map, kTsSuffix )) {
914955 return 1 ;
915956 }
916957 } else if (error != 0 ) {
@@ -927,8 +968,6 @@ int Main(int argc, char* argv[]) {
927968 }
928969 }
929970
930- // Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
931- assert (file_map.size () == 3 );
932971 auto gypi_it = file_map.find (" .gypi" );
933972 // Currently config.gypi is the only `.gypi` file allowed
934973 if (gypi_it == file_map.end () || gypi_it->second .size () != 1 ||
@@ -940,19 +979,37 @@ int Main(int argc, char* argv[]) {
940979 }
941980 auto js_it = file_map.find (" .js" );
942981 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);
982+ auto ts_it = file_map.find (" .ts" );
983+ if (mjs_it != file_map.end ()) {
984+ auto it = std::find (mjs_it->second .begin (),
985+ mjs_it->second .end (),
986+ " lib/eslint.config_partial.mjs" );
987+ if (it != mjs_it->second .end ()) {
988+ mjs_it->second .erase (it);
989+ }
950990 }
951991
952- std::sort (js_it->second .begin (), js_it->second .end ());
953- std::sort (mjs_it->second .begin (), mjs_it->second .end ());
992+ if (js_it != file_map.end ()) {
993+ std::sort (js_it->second .begin (), js_it->second .end ());
994+ }
995+ if (mjs_it != file_map.end ()) {
996+ std::sort (mjs_it->second .begin (), mjs_it->second .end ());
997+ }
998+ if (ts_it != file_map.end ()) {
999+ std::sort (ts_it->second .begin (), ts_it->second .end ());
1000+ }
9541001
955- return JS2C (js_it->second , mjs_it->second , gypi_it->second [0 ], output);
1002+ static const FileList empty_list;
1003+ const FileList& js_files =
1004+ js_it == file_map.end () ? empty_list : js_it->second ;
1005+ const FileList& mjs_files =
1006+ mjs_it == file_map.end () ? empty_list : mjs_it->second ;
1007+ return JS2C (js_files,
1008+ mjs_files,
1009+ ts_it == file_map.end () ? empty_list : ts_it->second ,
1010+ gypi_it->second [0 ],
1011+ argv[0 ],
1012+ output);
9561013}
9571014} // namespace js2c
9581015} // namespace node
0 commit comments