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