@@ -348,6 +348,69 @@ static void IsInsideNodeModules(const FunctionCallbackInfo<Value>& args) {
348
348
args.GetReturnValue ().Set (result);
349
349
}
350
350
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
+
351
414
void RegisterExternalReferences (ExternalReferenceRegistry* registry) {
352
415
registry->Register (GetPromiseDetails);
353
416
registry->Register (GetProxyDetails);
@@ -364,6 +427,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
364
427
registry->Register (fast_guess_handle_type_.GetTypeInfo ());
365
428
registry->Register (ParseEnv);
366
429
registry->Register (IsInsideNodeModules);
430
+ registry->Register (DefineLazyProperties);
431
+ registry->Register (DefineLazyPropertiesGetter);
367
432
}
368
433
369
434
void Initialize (Local<Object> target,
@@ -448,6 +513,7 @@ void Initialize(Local<Object> target,
448
513
}
449
514
450
515
SetMethod (context, target, " isInsideNodeModules" , IsInsideNodeModules);
516
+ SetMethod (context, target, " defineLazyProperties" , DefineLazyProperties);
451
517
SetMethodNoSideEffect (
452
518
context, target, " getPromiseDetails" , GetPromiseDetails);
453
519
SetMethodNoSideEffect (context, target, " getProxyDetails" , GetProxyDetails);
0 commit comments