@@ -31,6 +31,7 @@ const {
31
31
ERR_INVALID_RETURN_PROPERTY_VALUE ,
32
32
ERR_INVALID_RETURN_VALUE ,
33
33
ERR_LOADER_CHAIN_INCOMPLETE ,
34
+ ERR_METHOD_NOT_IMPLEMENTED ,
34
35
ERR_UNKNOWN_BUILTIN_MODULE ,
35
36
ERR_WORKER_UNSERIALIZABLE_ERROR ,
36
37
} = require ( 'internal/errors' ) . codes ;
@@ -65,7 +66,7 @@ const {
65
66
let debug = require ( 'internal/util/debuglog' ) . debuglog ( 'esm' , ( fn ) => {
66
67
debug = fn ;
67
68
} ) ;
68
-
69
+ let importMetaInitializer ;
69
70
70
71
/**
71
72
* @typedef {object } ExportedHooks
@@ -82,7 +83,6 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
82
83
83
84
// [2] `validate...()`s throw the wrong error
84
85
85
-
86
86
class Hooks {
87
87
#chains = {
88
88
/**
@@ -121,20 +121,20 @@ class Hooks {
121
121
// Cache URLs we've already validated to avoid repeated validation
122
122
#validatedUrls = new SafeSet ( ) ;
123
123
124
+ allowImportMetaResolve = false ;
125
+
124
126
/**
125
127
* Import and register custom/user-defined module loader hook(s).
126
128
* @param {string } urlOrSpecifier
127
129
* @param {string } parentURL
128
130
*/
129
131
async register ( urlOrSpecifier , parentURL ) {
130
132
const moduleLoader = require ( 'internal/process/esm_loader' ) . esmLoader ;
131
-
132
133
const keyedExports = await moduleLoader . import (
133
134
urlOrSpecifier ,
134
135
parentURL ,
135
136
kEmptyObject ,
136
137
) ;
137
-
138
138
this . addCustomLoader ( urlOrSpecifier , keyedExports ) ;
139
139
}
140
140
@@ -152,13 +152,15 @@ class Hooks {
152
152
} = pluckHooks ( exports ) ;
153
153
154
154
if ( globalPreload ) {
155
- ArrayPrototypePush ( this . #chains. globalPreload , { fn : globalPreload , url } ) ;
155
+ ArrayPrototypePush ( this . #chains. globalPreload , { __proto__ : null , fn : globalPreload , url } ) ;
156
156
}
157
157
if ( resolve ) {
158
- ArrayPrototypePush ( this . #chains. resolve , { fn : resolve , url } ) ;
158
+ const next = this . #chains. resolve [ this . #chains. resolve . length - 1 ] ;
159
+ ArrayPrototypePush ( this . #chains. resolve , { __proto__ : null , fn : resolve , url, next } ) ;
159
160
}
160
161
if ( load ) {
161
- ArrayPrototypePush ( this . #chains. load , { fn : load , url } ) ;
162
+ const next = this . #chains. load [ this . #chains. load . length - 1 ] ;
163
+ ArrayPrototypePush ( this . #chains. load , { __proto__ : null , fn : load , url, next } ) ;
162
164
}
163
165
}
164
166
@@ -235,7 +237,6 @@ class Hooks {
235
237
chainFinished : null ,
236
238
context,
237
239
hookErrIdentifier : '' ,
238
- hookIndex : chain . length - 1 ,
239
240
hookName : 'resolve' ,
240
241
shortCircuited : false ,
241
242
} ;
@@ -258,7 +259,7 @@ class Hooks {
258
259
}
259
260
} ;
260
261
261
- const nextResolve = nextHookFactory ( chain , meta , { validateArgs, validateOutput } ) ;
262
+ const nextResolve = nextHookFactory ( chain [ chain . length - 1 ] , meta , { validateArgs, validateOutput } ) ;
262
263
263
264
const resolution = await nextResolve ( originalSpecifier , context ) ;
264
265
const { hookErrIdentifier } = meta ; // Retrieve the value after all settled
@@ -335,6 +336,10 @@ class Hooks {
335
336
} ;
336
337
}
337
338
339
+ resolveSync ( _originalSpecifier , _parentURL , _importAssertions ) {
340
+ throw new ERR_METHOD_NOT_IMPLEMENTED ( 'resolveSync()' ) ;
341
+ }
342
+
338
343
/**
339
344
* Provide source that is understood by one of Node's translators.
340
345
*
@@ -351,7 +356,6 @@ class Hooks {
351
356
chainFinished : null ,
352
357
context,
353
358
hookErrIdentifier : '' ,
354
- hookIndex : chain . length - 1 ,
355
359
hookName : 'load' ,
356
360
shortCircuited : false ,
357
361
} ;
@@ -393,7 +397,7 @@ class Hooks {
393
397
}
394
398
} ;
395
399
396
- const nextLoad = nextHookFactory ( chain , meta , { validateArgs, validateOutput } ) ;
400
+ const nextLoad = nextHookFactory ( chain [ chain . length - 1 ] , meta , { validateArgs, validateOutput } ) ;
397
401
398
402
const loaded = await nextLoad ( url , context ) ;
399
403
const { hookErrIdentifier } = meta ; // Retrieve the value after all settled
@@ -468,6 +472,16 @@ class Hooks {
468
472
source,
469
473
} ;
470
474
}
475
+
476
+ forceLoadHooks ( ) {
477
+ // No-op
478
+ }
479
+
480
+ importMetaInitialize ( meta , context , loader ) {
481
+ importMetaInitializer ??= require ( 'internal/modules/esm/initialize_import_meta' ) . initializeImportMeta ;
482
+ meta = importMetaInitializer ( meta , context , loader ) ;
483
+ return meta ;
484
+ }
471
485
}
472
486
ObjectSetPrototypeOf ( Hooks . prototype , null ) ;
473
487
@@ -717,46 +731,39 @@ function pluckHooks({
717
731
* A utility function to iterate through a hook chain, track advancement in the
718
732
* chain, and generate and supply the `next<HookName>` argument to the custom
719
733
* hook.
720
- * @param {KeyedHook[] } chain The whole hook chain.
734
+ * @param {Hook } current The (currently) first hook in the chain (this shifts
735
+ * on every call).
721
736
* @param {object } meta Properties that change as the current hook advances
722
737
* along the chain.
723
738
* @param {boolean } meta.chainFinished Whether the end of the chain has been
724
739
* reached AND invoked.
725
740
* @param {string } meta.hookErrIdentifier A user-facing identifier to help
726
741
* pinpoint where an error occurred. Ex "file:///foo.mjs 'resolve'".
727
- * @param {number } meta.hookIndex A non-negative integer tracking the current
728
- * position in the hook chain.
729
742
* @param {string } meta.hookName The kind of hook the chain is (ex 'resolve')
730
743
* @param {boolean } meta.shortCircuited Whether a hook signaled a short-circuit.
731
744
* @param {(hookErrIdentifier, hookArgs) => void } validate A wrapper function
732
745
* containing all validation of a custom loader hook's intermediary output. Any
733
746
* validation within MUST throw.
734
747
* @returns {function next<HookName>(...hookArgs) } The next hook in the chain.
735
748
*/
736
- function nextHookFactory ( chain , meta , { validateArgs, validateOutput } ) {
749
+ function nextHookFactory ( current , meta , { validateArgs, validateOutput } ) {
737
750
// First, prepare the current
738
751
const { hookName } = meta ;
739
752
const {
740
753
fn : hook ,
741
754
url : hookFilePath ,
742
- } = chain [ meta . hookIndex ] ;
755
+ next,
756
+ } = current ;
743
757
744
758
// ex 'nextResolve'
745
759
const nextHookName = `next${
746
760
StringPrototypeToUpperCase ( hookName [ 0 ] ) +
747
761
StringPrototypeSlice ( hookName , 1 )
748
762
} `;
749
763
750
- // When hookIndex is 0, it's reached the default, which does not call next()
751
- // so feed it a noop that blows up if called, so the problem is obvious.
752
- const generatedHookIndex = meta . hookIndex ;
753
764
let nextNextHook ;
754
- if ( meta . hookIndex > 0 ) {
755
- // Now, prepare the next: decrement the pointer so the next call to the
756
- // factory generates the next link in the chain.
757
- meta . hookIndex -- ;
758
-
759
- nextNextHook = nextHookFactory ( chain , meta , { validateArgs, validateOutput } ) ;
765
+ if ( next ) {
766
+ nextNextHook = nextHookFactory ( next , meta , { validateArgs, validateOutput } ) ;
760
767
} else {
761
768
// eslint-disable-next-line func-name-matching
762
769
nextNextHook = function chainAdvancedTooFar ( ) {
@@ -773,17 +780,16 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) {
773
780
774
781
validateArgs ( `${ meta . hookErrIdentifier } hook's ${ nextHookName } ()` , arg0 , context ) ;
775
782
776
- const outputErrIdentifier = `${ chain [ generatedHookIndex ] . url } '${ hookName } ' hook's ${ nextHookName } ()` ;
783
+ const outputErrIdentifier = `${ hookFilePath } '${ hookName } ' hook's ${ nextHookName } ()` ;
777
784
778
785
// Set when next<HookName> is actually called, not just generated.
779
- if ( generatedHookIndex === 0 ) { meta . chainFinished = true ; }
786
+ if ( ! next ) { meta . chainFinished = true ; }
780
787
781
788
if ( context ) { // `context` has already been validated, so no fancy check needed.
782
789
ObjectAssign ( meta . context , context ) ;
783
790
}
784
791
785
792
const output = await hook ( arg0 , meta . context , nextNextHook ) ;
786
-
787
793
validateOutput ( outputErrIdentifier , output ) ;
788
794
789
795
if ( output ?. shortCircuit === true ) { meta . shortCircuited = true ; }
0 commit comments