@@ -348,6 +348,69 @@ static void IsInsideNodeModules(const FunctionCallbackInfo<Value>& args) {
348348  args.GetReturnValue ().Set (result);
349349}
350350
351+ static  void  DefineLazyPropertiesGetter (
352+     Local<v8::Name> name, const  v8::PropertyCallbackInfo<Value>& info) {
353+   Realm* realm = Realm::GetCurrent (info);
354+   Isolate* isolate = realm->isolate ();
355+   auto  context = isolate->GetCurrentContext ();
356+   Local<Value> arg = info.Data ();
357+   Local<Value> require_result;
358+   if  (!realm->builtin_module_require ()
359+            ->Call (context, Null (isolate), 1 , &arg)
360+            .ToLocal (&require_result)) {
361+     //  V8 will have scheduled an error to be thrown.
362+     return ;
363+   }
364+   Local<Value> ret;
365+   if  (!require_result.As <v8::Object>()->Get (context, name).ToLocal (&ret)) {
366+     //  V8 will have scheduled an error to be thrown.
367+     return ;
368+   }
369+   info.GetReturnValue ().Set (ret);
370+ }
371+ static  void  DefineLazyProperties (const  FunctionCallbackInfo<Value>& args) {
372+   //  target: object, id: string, keys: string[][, enumerable = true]
373+   CHECK_GE (args.Length (), 3 );
374+   //  target: Object where to define the lazy properties.
375+   CHECK (args[0 ]->IsObject ());
376+   //  id: Internal module to lazy-load where the API to expose are implemented.
377+   CHECK (args[1 ]->IsString ());
378+   //  keys: Keys to map from `require(id)` and `target`.
379+   CHECK (args[2 ]->IsArray ());
380+   //  enumerable: Whether the property should be enumerable.
381+   CHECK (args.Length () == 3  || args[3 ]->IsBoolean ());
382+ 
383+   Environment* env = Environment::GetCurrent (args);
384+   Isolate* isolate = env->isolate ();
385+   auto  context = isolate->GetCurrentContext ();
386+ 
387+   auto  target = args[0 ].As <Object>();
388+   Local<Value> id = args[1 ];
389+   v8::PropertyAttribute attribute =
390+       args.Length () == 3  || args[3 ]->IsTrue () ? v8::None : v8::DontEnum;
391+ 
392+   const  Local<Array> keys = args[2 ].As <Array>();
393+   size_t  length = keys->Length ();
394+   for  (size_t  i = 0 ; i < length; i++) {
395+     Local<Value> key;
396+     if  (!keys->Get (context, i).ToLocal (&key)) {
397+       //  V8 will have scheduled an error to be thrown.
398+       return ;
399+     }
400+     CHECK (key->IsString ());
401+     if  (target
402+             ->SetLazyDataProperty (context,
403+                                   key.As <String>(),
404+                                   DefineLazyPropertiesGetter,
405+                                   id,
406+                                   attribute)
407+             .IsNothing ()) {
408+       //  V8 will have scheduled an error to be thrown.
409+       return ;
410+     };
411+   }
412+ }
413+ 
351414void  RegisterExternalReferences (ExternalReferenceRegistry* registry) {
352415  registry->Register (GetPromiseDetails);
353416  registry->Register (GetProxyDetails);
@@ -364,6 +427,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
364427  registry->Register (fast_guess_handle_type_.GetTypeInfo ());
365428  registry->Register (ParseEnv);
366429  registry->Register (IsInsideNodeModules);
430+   registry->Register (DefineLazyProperties);
431+   registry->Register (DefineLazyPropertiesGetter);
367432}
368433
369434void  Initialize (Local<Object> target,
@@ -448,6 +513,7 @@ void Initialize(Local<Object> target,
448513  }
449514
450515  SetMethod (context, target, " isInsideNodeModules"  , IsInsideNodeModules);
516+   SetMethod (context, target, " defineLazyProperties"  , DefineLazyProperties);
451517  SetMethodNoSideEffect (
452518      context, target, " getPromiseDetails"  , GetPromiseDetails);
453519  SetMethodNoSideEffect (context, target, " getProxyDetails"  , GetProxyDetails);
0 commit comments