@@ -235,12 +235,75 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
235235 // Check for Node.js built-in modules
236236 if (IsNodeBuiltinModule (spec)) {
237237 std::string builtinName = spec.substr (5 ); // Remove "node:" prefix
238- std::string builtinPath = appPath + " /" + builtinName + " .mjs" ;
239238
240- // For now, just throw an error - polyfill creation would need file system access
241- std::string msg = " Node.js built-in modules not supported yet: " + spec;
242- isolate->ThrowException (v8::Exception::Error (ArgConverter::ConvertToV8String (isolate, msg)));
243- return v8::MaybeLocal<v8::Module>();
239+ // Create polyfill content for Node.js built-in modules
240+ std::string polyfillContent;
241+
242+ if (builtinName == " url" ) {
243+ // Create a polyfill for node:url with fileURLToPath
244+ polyfillContent = " // Polyfill for node:url\n "
245+ " export function fileURLToPath(url) {\n "
246+ " if (typeof url === 'string') {\n "
247+ " if (url.startsWith('file://')) {\n "
248+ " return decodeURIComponent(url.slice(7));\n "
249+ " }\n "
250+ " return url;\n "
251+ " }\n "
252+ " if (url && typeof url.href === 'string') {\n "
253+ " return fileURLToPath(url.href);\n "
254+ " }\n "
255+ " throw new Error('Invalid URL');\n "
256+ " }\n "
257+ " \n "
258+ " export function pathToFileURL(path) {\n "
259+ " return new URL('file://' + encodeURIComponent(path));\n "
260+ " }\n " ;
261+ } else {
262+ // Generic polyfill for other Node.js built-in modules
263+ polyfillContent = " // Polyfill for node:" + builtinName + " \n "
264+ " console.warn('Node.js built-in module \\ 'node:" + builtinName + " \\ ' is not fully supported in NativeScript');\n "
265+ " export default {};\n " ;
266+ }
267+
268+ // Create module source and compile it in-memory
269+ v8::Local<v8::String> sourceText = ArgConverter::ConvertToV8String (isolate, polyfillContent);
270+
271+ // Build URL for stack traces
272+ std::string moduleUrl = " node:" + builtinName;
273+ v8::Local<v8::String> urlString = ArgConverter::ConvertToV8String (isolate, moduleUrl);
274+
275+ v8::ScriptOrigin origin (isolate, urlString, 0 , 0 , false , -1 , v8::Local<v8::Value>(), false , false , true /* is_module */ );
276+ v8::ScriptCompiler::Source src (sourceText, origin);
277+
278+ v8::Local<v8::Module> polyfillModule;
279+ if (!v8::ScriptCompiler::CompileModule (isolate, &src).ToLocal (&polyfillModule)) {
280+ std::string msg = " Failed to compile polyfill for: " + spec;
281+ isolate->ThrowException (v8::Exception::Error (ArgConverter::ConvertToV8String (isolate, msg)));
282+ return v8::MaybeLocal<v8::Module>();
283+ }
284+
285+ // Store in registry before instantiation
286+ g_moduleRegistry[spec].Reset (isolate, polyfillModule);
287+
288+ // Instantiate the module
289+ if (!polyfillModule->InstantiateModule (context, ResolveModuleCallback).FromMaybe (false )) {
290+ g_moduleRegistry.erase (spec);
291+ std::string msg = " Failed to instantiate polyfill for: " + spec;
292+ isolate->ThrowException (v8::Exception::Error (ArgConverter::ConvertToV8String (isolate, msg)));
293+ return v8::MaybeLocal<v8::Module>();
294+ }
295+
296+ // Evaluate the module
297+ v8::MaybeLocal<v8::Value> evalResult = polyfillModule->Evaluate (context);
298+ if (evalResult.IsEmpty ()) {
299+ g_moduleRegistry.erase (spec);
300+ std::string msg = " Failed to evaluate polyfill for: " + spec;
301+ isolate->ThrowException (v8::Exception::Error (ArgConverter::ConvertToV8String (isolate, msg)));
302+ return v8::MaybeLocal<v8::Module>();
303+ }
304+
305+ return v8::MaybeLocal<v8::Module>(polyfillModule);
306+
244307 } else if (tns::ModuleInternal::IsLikelyOptionalModule (spec)) {
245308 // For optional modules, create a placeholder
246309 std::string msg = " Optional module not found: " + spec;
0 commit comments