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,43 @@ 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 (js_files.size () + mjs_files.size () + ts_files. size () + 1 );
833855 Fragments initializers;
834- initializers.reserve (js_files.size () + mjs_files.size ());
856+ initializers.reserve (js_files.size () + mjs_files.size () + ts_files. size () );
835857 Fragments registrations;
836- registrations.reserve (js_files.size () + mjs_files.size () + 1 );
858+ registrations.reserve (js_files.size () + mjs_files.size () + ts_files.size () +
859+ 1 );
860+
861+ if (!ts_files.empty () && transpiler.Initialize (argv0) != 0 ) {
862+ fprintf (stderr,
863+ " Failed to initialize TypeScript transpiler: %s\n " ,
864+ transpiler.LastError ().c_str ());
865+ return 1 ;
866+ }
837867
838868 for (const auto & filename : js_files) {
839- int r = AddModule (filename, &definitions, &initializers, ®istrations);
869+ int r = AddModule (
870+ filename, &transpiler, &definitions, &initializers, ®istrations);
840871 if (r != 0 ) {
841872 return r;
842873 }
843874 }
844875 for (const auto & filename : mjs_files) {
845- int r = AddModule (filename, &definitions, &initializers, ®istrations);
876+ int r = AddModule (
877+ filename, &transpiler, &definitions, &initializers, ®istrations);
878+ if (r != 0 ) {
879+ return r;
880+ }
881+ }
882+ for (const auto & filename : ts_files) {
883+ int r = AddModule (
884+ filename, &transpiler, &definitions, &initializers, ®istrations);
846885 if (r != 0 ) {
847886 return r;
848887 }
@@ -910,7 +949,8 @@ int Main(int argc, char* argv[]) {
910949 const std::string& file = args[i];
911950 if (IsDirectory (file, &error)) {
912951 if (!SearchFiles (file, &file_map, kJsSuffix ) ||
913- !SearchFiles (file, &file_map, kMjsSuffix )) {
952+ !SearchFiles (file, &file_map, kMjsSuffix ) ||
953+ !SearchFiles (file, &file_map, kTsSuffix )) {
914954 return 1 ;
915955 }
916956 } else if (error != 0 ) {
@@ -927,8 +967,6 @@ int Main(int argc, char* argv[]) {
927967 }
928968 }
929969
930- // Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
931- assert (file_map.size () == 3 );
932970 auto gypi_it = file_map.find (" .gypi" );
933971 // Currently config.gypi is the only `.gypi` file allowed
934972 if (gypi_it == file_map.end () || gypi_it->second .size () != 1 ||
@@ -940,19 +978,37 @@ int Main(int argc, char* argv[]) {
940978 }
941979 auto js_it = file_map.find (" .js" );
942980 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);
981+ auto ts_it = file_map.find (" .ts" );
982+ if (mjs_it != file_map.end ()) {
983+ auto it = std::find (mjs_it->second .begin (),
984+ mjs_it->second .end (),
985+ " lib/eslint.config_partial.mjs" );
986+ if (it != mjs_it->second .end ()) {
987+ mjs_it->second .erase (it);
988+ }
950989 }
951990
952- std::sort (js_it->second .begin (), js_it->second .end ());
953- std::sort (mjs_it->second .begin (), mjs_it->second .end ());
991+ if (js_it != file_map.end ()) {
992+ std::sort (js_it->second .begin (), js_it->second .end ());
993+ }
994+ if (mjs_it != file_map.end ()) {
995+ std::sort (mjs_it->second .begin (), mjs_it->second .end ());
996+ }
997+ if (ts_it != file_map.end ()) {
998+ std::sort (ts_it->second .begin (), ts_it->second .end ());
999+ }
9541000
955- return JS2C (js_it->second , mjs_it->second , gypi_it->second [0 ], output);
1001+ static const FileList empty_list;
1002+ const FileList& js_files =
1003+ js_it == file_map.end () ? empty_list : js_it->second ;
1004+ const FileList& mjs_files =
1005+ mjs_it == file_map.end () ? empty_list : mjs_it->second ;
1006+ return JS2C (js_files,
1007+ mjs_files,
1008+ ts_it == file_map.end () ? empty_list : ts_it->second ,
1009+ gypi_it->second [0 ],
1010+ argv[0 ],
1011+ output);
9561012}
9571013} // namespace js2c
9581014} // namespace node
0 commit comments