66#include < utime.h>
77#include < string>
88#include " Caches.h"
9+ #include " DevFlags.h"
910#include " Helpers.h"
1011#include " ModuleInternalCallbacks.h" // for ResolveModuleCallback
1112#include " NativeScriptException.h"
12- #include " DevFlags.h"
1313#include " Runtime.h" // for GetAppConfigValue
1414#include " RuntimeConfig.h"
1515
@@ -177,7 +177,8 @@ bool IsESModule(const std::string& path) {
177177 Log (@" Error loading ES module: %s " , path.c_str ());
178178 Log (@" Exception: %s " , ex.getMessage ().c_str ());
179179 Log (@" ***** End stack trace - continuing execution *****" );
180- Log (@" Debug mode - ES module loading failed, but telling iOS it succeeded to prevent app termination" );
180+ Log (@" Debug mode - ES module loading failed, but telling iOS it succeeded to prevent app "
181+ @" termination" );
181182 return true ; // avoid termination in debug
182183 } else {
183184 return false ;
@@ -225,11 +226,10 @@ bool IsESModule(const std::string& path) {
225226 @" app termination" );
226227
227228 // Add a small delay to ensure error modal has time to render before we return
228- dispatch_after (
229- dispatch_time (DISPATCH_TIME_NOW, (int64_t )(0.3 * NSEC_PER_SEC)),
230- dispatch_get_main_queue (), ^{
231- Log (@" 🛡️ Debug mode - Crash prevention complete, app should remain stable" );
232- });
229+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t )(0.3 * NSEC_PER_SEC)),
230+ dispatch_get_main_queue (), ^{
231+ Log (@" 🛡️ Debug mode - Crash prevention complete, app should remain stable" );
232+ });
233233
234234 return true ; // LIE TO iOS - return success to prevent app termination
235235 } else {
@@ -302,7 +302,9 @@ bool IsESModule(const std::string& path) {
302302 if (*s) {
303303 moduleName.assign (*s, s.length ());
304304 if (moduleName.rfind (" http://" , 0 ) == 0 || moduleName.rfind (" https://" , 0 ) == 0 ) {
305- std::string msg = std::string (" NativeScript: require() of URL module is not supported: " ) + moduleName + " . Use dynamic import() instead." ;
305+ std::string msg =
306+ std::string (" NativeScript: require() of URL module is not supported: " ) + moduleName +
307+ " . Use dynamic import() instead." ;
306308 throw NativeScriptException (msg.c_str ());
307309 }
308310 }
@@ -357,7 +359,6 @@ bool IsESModule(const std::string& path) {
357359 fullPath = [NSString stringWithUTF8String: moduleName.c_str ()];
358360 }
359361
360-
361362 NSString * fileNameOnly = [fullPath lastPathComponent ];
362363 NSString * pathOnly = [fullPath stringByDeletingLastPathComponent ];
363364
@@ -638,7 +639,15 @@ throw NativeScriptException(isolate,
638639 stringByDeletingLastPathComponent ] UTF8String ];
639640
640641 // Shorten the parentDir for GetRequireFunction to avoid V8 parsing issues with long paths
641- std::string shortParentDir = " /app" + parentDir.substr (RuntimeConfig.ApplicationPath .length ());
642+ std::string shortParentDir;
643+ if (parentDir.length () >= RuntimeConfig.ApplicationPath .length () &&
644+ parentDir.compare (0 , RuntimeConfig.ApplicationPath .length (), RuntimeConfig.ApplicationPath ) ==
645+ 0 ) {
646+ shortParentDir = " /app" + parentDir.substr (RuntimeConfig.ApplicationPath .length ());
647+ } else {
648+ // Fallback: use the entire path if it doesn't start with ApplicationPath
649+ shortParentDir = parentDir;
650+ }
642651
643652 Local<v8::Function> require = GetRequireFunction (isolate, shortParentDir);
644653 // Use full paths for __filename and __dirname to match module.id
@@ -713,7 +722,8 @@ throw NativeScriptException(isolate,
713722 canonicalPath.c_str ());
714723 return Local<Value>();
715724 } else {
716- throw NativeScriptException (isolate, " Classic script compilation failed for " + canonicalPath);
725+ throw NativeScriptException (isolate,
726+ " Classic script compilation failed for " + canonicalPath);
717727 }
718728 }
719729
@@ -825,7 +835,8 @@ ScriptOrigin origin(isolate, urlString,
825835 tns::LogError (isolate, tc);
826836 }
827837 Log (@" ***** End stack trace - continuing execution *****" );
828- Log (@" Debug mode - Script compilation failed, returning gracefully: %s " , canonicalPath.c_str ());
838+ Log (@" Debug mode - Script compilation failed, returning gracefully: %s " ,
839+ canonicalPath.c_str ());
829840 // Return empty script to prevent crashes
830841 return Local<Script>();
831842 } else {
@@ -852,7 +863,8 @@ ScriptOrigin origin(isolate, urlString,
852863
853864 Local<v8::String> urlString;
854865 if (!v8::String::NewFromUtf8 (isolate, url.c_str (), NewStringType::kNormal ).ToLocal (&urlString)) {
855- throw NativeScriptException (isolate, " Failed to create URL string for ES module " + canonicalPath);
866+ throw NativeScriptException (isolate,
867+ " Failed to create URL string for ES module " + canonicalPath);
856868 }
857869
858870 ScriptOrigin origin (isolate, urlString, 0 , 0 , false , -1 , Local<Value>(), false , false ,
@@ -861,12 +873,15 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
861873 ScriptCompiler::Source source (sourceText, origin, cacheData);
862874
863875 // 2) Compile with its own TryCatch
864- // Phase diagnostics helper (local lambda) – only active in debug builds when logScriptLoading is enabled
865- auto logPhase = [&](const char * phase, const char * status, const char * classification = " " , const char * extra = " " ) {
876+ // Phase diagnostics helper (local lambda) – only active in debug builds when logScriptLoading is
877+ // enabled
878+ auto logPhase = [&](const char * phase, const char * status, const char * classification = " " ,
879+ const char * extra = " " ) {
866880 if (RuntimeConfig.IsDebug && IsScriptLoadingLogEnabled ()) {
867881 if (classification && classification[0 ] != ' \0 ' ) {
868882 if (extra && extra[0 ] != ' \0 ' ) {
869- Log (@" [esm][%s ][%s ][%s ] %s %s " , phase, status, classification, canonicalPath.c_str (), extra);
883+ Log (@" [esm][%s ][%s ][%s ] %s %s " , phase, status, classification, canonicalPath.c_str (),
884+ extra);
870885 } else {
871886 Log (@" [esm][%s ][%s ][%s ] %s " , phase, status, classification, canonicalPath.c_str ());
872887 }
@@ -896,8 +911,11 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
896911 v8::String::Utf8Value w (isolate, msg->Get ());
897912 if (*w) {
898913 std::string m (*w);
899- if (m.find (" Unexpected token" ) != std::string::npos || m.find (" SyntaxError" ) != std::string::npos) classification = " syntax" ;
900- else if (m.find (" Cannot use import statement outside a module" ) != std::string::npos) classification = " not-a-module" ;
914+ if (m.find (" Unexpected token" ) != std::string::npos ||
915+ m.find (" SyntaxError" ) != std::string::npos)
916+ classification = " syntax" ;
917+ else if (m.find (" Cannot use import statement outside a module" ) != std::string::npos)
918+ classification = " not-a-module" ;
901919 }
902920 }
903921 }
@@ -915,7 +933,8 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
915933 // Return empty to prevent crashes
916934 return Local<Value>();
917935 } else {
918- throw NativeScriptException (isolate, tcCompile, " Cannot compile ES module " + canonicalPath);
936+ throw NativeScriptException (isolate, tcCompile,
937+ " Cannot compile ES module " + canonicalPath);
919938 }
920939 }
921940 }
@@ -956,8 +975,11 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
956975 v8::String::Utf8Value w (isolate, msg->Get ());
957976 if (*w) {
958977 std::string m (*w);
959- if (m.find (" Cannot find module" ) != std::string::npos || m.find (" failed to resolve module specifier" ) != std::string::npos) classification = " resolve" ;
960- else if (m.find (" does not provide an export named" ) != std::string::npos) classification = " link-export" ;
978+ if (m.find (" Cannot find module" ) != std::string::npos ||
979+ m.find (" failed to resolve module specifier" ) != std::string::npos)
980+ classification = " resolve" ;
981+ else if (m.find (" does not provide an export named" ) != std::string::npos)
982+ classification = " link-export" ;
961983 }
962984 }
963985 }
@@ -974,7 +996,8 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
974996 return Local<Value>();
975997 } else {
976998 if (tcLink.HasCaught ()) {
977- throw NativeScriptException (isolate, tcLink, " Cannot instantiate module " + canonicalPath);
999+ throw NativeScriptException (isolate, tcLink,
1000+ " Cannot instantiate module " + canonicalPath);
9781001 } else {
9791002 // V8 gave no exception object—throw plain text
9801003 throw NativeScriptException (isolate, " Cannot instantiate module " + canonicalPath);
@@ -999,9 +1022,12 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
9991022 v8::String::Utf8Value w (isolate, msg->Get ());
10001023 if (*w) {
10011024 std::string m (*w);
1002- if (m.find (" is not defined" ) != std::string::npos) classification = " reference" ;
1003- else if (m.find (" TypeError" ) != std::string::npos) classification = " type" ;
1004- else if (m.find (" Cannot read properties" ) != std::string::npos) classification = " type-nullish" ;
1025+ if (m.find (" is not defined" ) != std::string::npos)
1026+ classification = " reference" ;
1027+ else if (m.find (" TypeError" ) != std::string::npos)
1028+ classification = " type" ;
1029+ else if (m.find (" Cannot read properties" ) != std::string::npos)
1030+ classification = " type-nullish" ;
10051031 }
10061032 }
10071033 }
@@ -1052,7 +1078,7 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
10521078 std::string errorTitle = " Uncaught JavaScript Exception" ;
10531079 std::string errorMessage = " Module evaluation promise rejected" ;
10541080 std::string stackTrace = " " ;
1055-
1081+
10561082 // Try to get the promise result (the actual error)
10571083 Local<Value> reason = promise->Result ();
10581084 if (!reason.IsEmpty ()) {
@@ -1062,7 +1088,8 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
10621088
10631089 auto messageKey = tns::ToV8String (isolate, " message" );
10641090 Local<Value> messageVal;
1065- if (errorObj->Get (context, messageKey).ToLocal (&messageVal) && messageVal->IsString ()) {
1091+ if (errorObj->Get (context, messageKey).ToLocal (&messageVal) &&
1092+ messageVal->IsString ()) {
10661093 v8::String::Utf8Value messageUtf8 (isolate, messageVal);
10671094 if (*messageUtf8) errorMessage = std::string (*messageUtf8);
10681095 }
@@ -1113,7 +1140,8 @@ ScriptOrigin origin(isolate, urlString, 0, 0, false, -1, Local<Value>(), false,
11131140
11141141 if (IsScriptLoadingLogEnabled ()) {
11151142 // Emit a concise summary of the rejection for diagnostics
1116- std::string stackPreview = stackTrace.size () > 240 ? stackTrace.substr (0 , 240 ) + " …" : stackTrace;
1143+ std::string stackPreview =
1144+ stackTrace.size () > 240 ? stackTrace.substr (0 , 240 ) + " …" : stackTrace;
11171145 Log (@" [esm][evaluate][promise-rejected:detail] path=%s message=%s stack=%s " ,
11181146 canonicalPath.c_str (), errorMessage.c_str (), stackPreview.c_str ());
11191147 }
@@ -1566,7 +1594,14 @@ throw NativeScriptException(
15661594}
15671595
15681596std::string ModuleInternal::GetCacheFileName (const std::string& path) {
1569- std::string key = path.substr (RuntimeConfig.ApplicationPath .size () + 1 );
1597+ std::string key;
1598+ if (path.length () > RuntimeConfig.ApplicationPath .size () &&
1599+ path.compare (0 , RuntimeConfig.ApplicationPath .size (), RuntimeConfig.ApplicationPath ) == 0 ) {
1600+ key = path.substr (RuntimeConfig.ApplicationPath .size () + 1 );
1601+ } else {
1602+ // Fallback: use the entire path if it doesn't start with ApplicationPath
1603+ key = path;
1604+ }
15701605 std::replace (key.begin (), key.end (), ' /' , ' -' );
15711606
15721607 NSArray * paths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES );
0 commit comments