@@ -15,8 +15,6 @@ const {
15
15
ObjectDefineProperty,
16
16
ObjectSetPrototypeOf,
17
17
PromiseAll,
18
- PromiseResolve,
19
- PromisePrototypeThen,
20
18
ReflectApply,
21
19
RegExpPrototypeExec,
22
20
SafeArrayIterator,
@@ -111,14 +109,12 @@ let emittedSpecifierResolutionWarning = false;
111
109
* position in the hook chain.
112
110
* @param {string } meta.hookName The kind of hook the chain is (ex 'resolve')
113
111
* @param {boolean } meta.shortCircuited Whether a hook signaled a short-circuit.
114
- * @param {object } validators A wrapper function
112
+ * @param {(hookErrIdentifier, hookArgs) => void } validate A wrapper function
115
113
* containing all validation of a custom loader hook's intermediary output. Any
116
114
* validation within MUST throw.
117
- * @param {(hookErrIdentifier, hookArgs) => void } validators.validateArgs
118
- * @param {(hookErrIdentifier, output) => void } validators.validateOutput
119
115
* @returns {function next<HookName>(...hookArgs) } The next hook in the chain.
120
116
*/
121
- function nextHookFactory ( chain , meta , { validateArgs , validateOutput } ) {
117
+ function nextHookFactory ( chain , meta , validate ) {
122
118
// First, prepare the current
123
119
const { hookName } = meta ;
124
120
const {
@@ -141,7 +137,7 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) {
141
137
// factory generates the next link in the chain.
142
138
meta . hookIndex -- ;
143
139
144
- nextNextHook = nextHookFactory ( chain , meta , { validateArgs , validateOutput } ) ;
140
+ nextNextHook = nextHookFactory ( chain , meta , validate ) ;
145
141
} else {
146
142
// eslint-disable-next-line func-name-matching
147
143
nextNextHook = function chainAdvancedTooFar ( ) {
@@ -152,36 +148,21 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) {
152
148
}
153
149
154
150
return ObjectDefineProperty (
155
- ( ...args ) => {
151
+ async ( ...args ) => {
156
152
// Update only when hook is invoked to avoid fingering the wrong filePath
157
153
meta . hookErrIdentifier = `${ hookFilePath } '${ hookName } '` ;
158
154
159
- validateArgs ( `${ meta . hookErrIdentifier } hook's ${ nextHookName } ()` , args ) ;
160
-
161
- const outputErrIdentifier = `${ chain [ generatedHookIndex ] . url } '${ hookName } ' hook's ${ nextHookName } ()` ;
155
+ validate ( `${ meta . hookErrIdentifier } hook's ${ nextHookName } ()` , args ) ;
162
156
163
157
// Set when next<HookName> is actually called, not just generated.
164
158
if ( generatedHookIndex === 0 ) { meta . chainFinished = true ; }
165
159
166
160
ArrayPrototypePush ( args , nextNextHook ) ;
167
- const output = ReflectApply ( hook , undefined , args ) ;
168
-
169
- validateOutput ( outputErrIdentifier , output ) ;
161
+ const output = await ReflectApply ( hook , undefined , args ) ;
170
162
171
- function checkShortCircuited ( output ) {
172
- if ( output ?. shortCircuit === true ) { meta . shortCircuited = true ; }
173
-
174
- return output ;
175
- }
176
-
177
- if ( meta . isChainAsync ) {
178
- return PromisePrototypeThen (
179
- PromiseResolve ( output ) ,
180
- checkShortCircuited ,
181
- ) ;
182
- }
163
+ if ( output ?. shortCircuit === true ) { meta . shortCircuited = true ; }
164
+ return output ;
183
165
184
- return checkShortCircuited ( output ) ;
185
166
} ,
186
167
'name' ,
187
168
{ __proto__ : null , value : nextHookName } ,
@@ -440,11 +421,8 @@ class ESMLoader {
440
421
) ;
441
422
}
442
423
443
- const { format, url } = this . resolve (
444
- specifier ,
445
- parentURL ,
446
- importAssertionsForResolve ,
447
- ) ;
424
+ const { format, url } =
425
+ await this . resolve ( specifier , parentURL , importAssertionsForResolve ) ;
448
426
449
427
let job = this . moduleMap . get ( url , importAssertions . type ) ;
450
428
@@ -579,11 +557,10 @@ class ESMLoader {
579
557
hookErrIdentifier : '' ,
580
558
hookIndex : chain . length - 1 ,
581
559
hookName : 'load' ,
582
- isChainAsync : true ,
583
560
shortCircuited : false ,
584
561
} ;
585
562
586
- const validateArgs = ( hookErrIdentifier , { 0 : nextUrl , 1 : ctx } ) => {
563
+ const validate = ( hookErrIdentifier , { 0 : nextUrl , 1 : ctx } ) => {
587
564
if ( typeof nextUrl !== 'string' ) {
588
565
// non-strings can be coerced to a url string
589
566
// validateString() throws a less-specific error
@@ -609,22 +586,19 @@ class ESMLoader {
609
586
610
587
validateObject ( ctx , `${ hookErrIdentifier } context` ) ;
611
588
} ;
612
- const validateOutput = ( hookErrIdentifier , output ) => {
613
- if ( typeof output !== 'object' ) { // [2]
614
- throw new ERR_INVALID_RETURN_VALUE (
615
- 'an object' ,
616
- hookErrIdentifier ,
617
- output ,
618
- ) ;
619
- }
620
- } ;
621
589
622
- const nextLoad = nextHookFactory ( chain , meta , { validateArgs , validateOutput } ) ;
590
+ const nextLoad = nextHookFactory ( chain , meta , validate ) ;
623
591
624
592
const loaded = await nextLoad ( url , context ) ;
625
593
const { hookErrIdentifier } = meta ; // Retrieve the value after all settled
626
594
627
- validateOutput ( hookErrIdentifier , loaded ) ;
595
+ if ( typeof loaded !== 'object' ) { // [2]
596
+ throw new ERR_INVALID_RETURN_VALUE (
597
+ 'an object' ,
598
+ hookErrIdentifier ,
599
+ loaded ,
600
+ ) ;
601
+ }
628
602
629
603
if ( loaded ?. shortCircuit === true ) { meta . shortCircuited = true ; }
630
604
@@ -804,7 +778,7 @@ class ESMLoader {
804
778
* statement or expression.
805
779
* @returns {{ format: string, url: URL['href'] } }
806
780
*/
807
- resolve (
781
+ async resolve (
808
782
originalSpecifier ,
809
783
parentURL ,
810
784
importAssertions = ObjectCreate ( null )
@@ -828,43 +802,36 @@ class ESMLoader {
828
802
hookErrIdentifier : '' ,
829
803
hookIndex : chain . length - 1 ,
830
804
hookName : 'resolve' ,
831
- isChainAsync : false ,
832
805
shortCircuited : false ,
833
806
} ;
807
+
834
808
const context = {
835
809
conditions : DEFAULT_CONDITIONS ,
836
810
importAssertions,
837
811
parentURL,
838
812
} ;
813
+ const validate = ( hookErrIdentifier , { 0 : suppliedSpecifier , 1 : ctx } ) => {
839
814
840
- const validateArgs = ( hookErrIdentifier , { 0 : suppliedSpecifier , 1 : ctx } ) => {
841
815
validateString (
842
816
suppliedSpecifier ,
843
817
`${ hookErrIdentifier } specifier` ,
844
818
) ; // non-strings can be coerced to a url string
845
819
846
820
validateObject ( ctx , `${ hookErrIdentifier } context` ) ;
847
821
} ;
848
- const validateOutput = ( hookErrIdentifier , output ) => {
849
- if (
850
- typeof output !== 'object' || // [2]
851
- output === null ||
852
- ( output . url == null && typeof output . then === 'function' )
853
- ) {
854
- throw new ERR_INVALID_RETURN_VALUE (
855
- 'an object' ,
856
- hookErrIdentifier ,
857
- output ,
858
- ) ;
859
- }
860
- } ;
861
822
862
- const nextResolve = nextHookFactory ( chain , meta , { validateArgs , validateOutput } ) ;
823
+ const nextResolve = nextHookFactory ( chain , meta , validate ) ;
863
824
864
- const resolution = nextResolve ( originalSpecifier , context ) ;
825
+ const resolution = await nextResolve ( originalSpecifier , context ) ;
865
826
const { hookErrIdentifier } = meta ; // Retrieve the value after all settled
866
827
867
- validateOutput ( hookErrIdentifier , resolution ) ;
828
+ if ( typeof resolution !== 'object' ) { // [2]
829
+ throw new ERR_INVALID_RETURN_VALUE (
830
+ 'an object' ,
831
+ hookErrIdentifier ,
832
+ resolution ,
833
+ ) ;
834
+ }
868
835
869
836
if ( resolution ?. shortCircuit === true ) { meta . shortCircuited = true ; }
870
837
0 commit comments