@@ -35,6 +35,7 @@ using v8::Null;
3535using  v8::Object;
3636using  v8::ObjectTemplate;
3737using  v8::Primitive;
38+ using  v8::PropertyCallbackInfo;
3839using  v8::String;
3940using  v8::Undefined;
4041using  v8::Value;
@@ -594,6 +595,76 @@ void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
594595      isolate, v8::Null (isolate), names.data (), values.data (), names.size ()));
595596}
596597
598+ static  void  PathHelpersLazyGetter (Local<v8::Name> name,
599+                                   const  PropertyCallbackInfo<Value>& info) {
600+   Isolate* isolate = info.GetIsolate ();
601+   //  This getter has no JavaScript function representation and is not
602+   //  invoked in the creation context.
603+   //  When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
604+   //  returns a nullptr and retrieve the creation context via `this` object and
605+   //  get the creation Realm.
606+   Local<Value> receiver_val = info.This ();
607+   if  (!receiver_val->IsObject ()) {
608+     THROW_ERR_INVALID_INVOCATION (isolate);
609+     return ;
610+   }
611+   Local<Object> receiver = receiver_val.As <Object>();
612+   Local<Context> context;
613+   if  (!receiver->GetCreationContext ().ToLocal (&context)) {
614+     THROW_ERR_INVALID_INVOCATION (isolate);
615+     return ;
616+   }
617+   Environment* env = Environment::GetCurrent (context);
618+ 
619+   node::Utf8Value url (isolate, info.Data ());
620+   auto  file_url = ada::parse (url.ToStringView ());
621+   CHECK (file_url);
622+   auto  file_path = url::FileURLToPath (env, *file_url);
623+   CHECK (file_path.has_value ());
624+   std::string_view ret_view = file_path.value ();
625+ 
626+   node::Utf8Value utf8name (isolate, name);
627+   auto  plain_name = utf8name.ToStringView ();
628+   if  (plain_name == " dirname" 
629+ #ifdef  _WIN32
630+ #define  PATH_SEPARATOR  ' \\ ' 
631+ #else 
632+ #define  PATH_SEPARATOR  ' /' 
633+ #endif 
634+     auto  index = ret_view.rfind (PATH_SEPARATOR);
635+     CHECK (index != std::string_view::npos);
636+     ret_view.remove_suffix (ret_view.size () - index);
637+ #undef  PATH_SEPARATOR
638+   }
639+   Local<Value> ret;
640+   if  (!ToV8Value (context, ret_view, isolate).ToLocal (&ret)) {
641+     return ;
642+   }
643+   info.GetReturnValue ().Set (ret);
644+ }
645+ void  InitImportMetaPathHelpers (const  FunctionCallbackInfo<Value>& args) {
646+   //  target, url, shouldSetDirnameAndFilename, resolve
647+   CHECK_GE (args.Length (), 2 );
648+   CHECK (args[0 ]->IsObject ());
649+   CHECK (args[1 ]->IsString ());
650+ 
651+   Isolate* isolate = args.GetIsolate ();
652+   Local<Context> context = isolate->GetCurrentContext ();
653+   Environment* env = Environment::GetCurrent (context);
654+ 
655+   auto  target = args[0 ].As <Object>();
656+ 
657+   //  N.B.: Order is important to keep keys in alphabetical order.
658+   if  (target
659+           ->SetLazyDataProperty (
660+               context, env->dirname_string (), PathHelpersLazyGetter, args[1 ])
661+           .IsNothing () ||
662+       target
663+           ->SetLazyDataProperty (
664+               context, env->filename_string (), PathHelpersLazyGetter, args[1 ])
665+           .IsNothing ())
666+     return ;
667+ }
597668void  SaveCompileCacheEntry (const  FunctionCallbackInfo<Value>& args) {
598669  Isolate* isolate = args.GetIsolate ();
599670  Local<Context> context = isolate->GetCurrentContext ();
@@ -627,6 +698,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
627698  SetMethod (isolate, target, " flushCompileCache" 
628699  SetMethod (isolate, target, " getCompileCacheEntry" 
629700  SetMethod (isolate, target, " saveCompileCacheEntry" 
701+   SetMethod (isolate, target, " setLazyPathHelpers" 
630702}
631703
632704void  BindingData::CreatePerContextProperties (Local<Object> target,
@@ -682,6 +754,7 @@ void BindingData::RegisterExternalReferences(
682754  registry->Register (FlushCompileCache);
683755  registry->Register (GetCompileCacheEntry);
684756  registry->Register (SaveCompileCacheEntry);
757+   registry->Register (InitImportMetaPathHelpers);
685758}
686759
687760}  //  namespace modules
0 commit comments