@@ -17,14 +17,12 @@ const {
17
17
RegExpPrototypeExec,
18
18
SafeArrayIterator,
19
19
SafeWeakMap,
20
- StringPrototypeStartsWith,
21
20
globalThis,
22
21
} = primordials ;
23
22
const { MessageChannel } = require ( 'internal/worker/io' ) ;
24
23
25
24
const {
26
25
ERR_LOADER_CHAIN_INCOMPLETE ,
27
- ERR_INTERNAL_ASSERTION ,
28
26
ERR_INVALID_ARG_TYPE ,
29
27
ERR_INVALID_ARG_VALUE ,
30
28
ERR_INVALID_RETURN_PROPERTY_VALUE ,
@@ -55,11 +53,6 @@ const { defaultLoad } = require('internal/modules/esm/load');
55
53
const { translators } = require (
56
54
'internal/modules/esm/translators' ) ;
57
55
const { getOptionValue } = require ( 'internal/options' ) ;
58
- const {
59
- fetchModule,
60
- inFetchCache,
61
- } = require ( 'internal/modules/esm/fetch_module' ) ;
62
-
63
56
64
57
/**
65
58
* @typedef {object } ExportedHooks
@@ -306,9 +299,7 @@ class ESMLoader {
306
299
const module = new ModuleWrap ( url , undefined , source , 0 , 0 ) ;
307
300
callbackMap . set ( module , {
308
301
importModuleDynamically : ( specifier , { url } , importAssertions ) => {
309
- return this . import ( specifier ,
310
- this . getBaseURL ( url ) ,
311
- importAssertions ) ;
302
+ return this . import ( specifier , url , importAssertions ) ;
312
303
}
313
304
} ) ;
314
305
@@ -324,55 +315,6 @@ class ESMLoader {
324
315
} ;
325
316
}
326
317
327
- /**
328
- * Returns the url to use for the resolution of a given cache key url
329
- * These are not guaranteed to be the same.
330
- *
331
- * In WHATWG HTTP spec for ESM the cache key is the non-I/O bound
332
- * synchronous resolution using only string operations
333
- * ~= resolveImportMap(new URL(specifier, importerHREF))
334
- *
335
- * The url used for subsequent resolution is the response URL after
336
- * all redirects have been resolved.
337
- *
338
- * https://example.com/foo redirecting to https://example.com/bar
339
- * would have a cache key of https://example.com/foo and baseURL
340
- * of https://example.com/bar
341
- *
342
- * ! MUST BE SYNCHRONOUS for import.meta initialization
343
- * ! MUST BE CALLED AFTER receiving the url body due to I/O
344
- * @param {URL['href'] } url
345
- * @returns {string|Promise<URL['href']> }
346
- */
347
- getBaseURL ( url ) {
348
- if ( getOptionValue ( '--experimental-network-imports' ) && (
349
- StringPrototypeStartsWith ( url , 'http:' ) ||
350
- StringPrototypeStartsWith ( url , 'https:' )
351
- ) ) {
352
- // When using network-imports, the request & response have already settled
353
- // so they are in fetchModule's cache, in which case, fetchModule returns
354
- // immediately and synchronously
355
- // Unless a custom loader bypassed the fetch cache, in which case we just
356
- // use the original url
357
- if ( inFetchCache ( url ) ) {
358
- const module = fetchModule ( new URL ( url ) , { parentURL : url } ) ;
359
- if ( typeof module ?. resolvedHREF === 'string' ) {
360
- return module . resolvedHREF ;
361
- }
362
- // Internal error
363
- throw new ERR_INTERNAL_ASSERTION (
364
- `Base url for module ${ url } not loaded.`
365
- ) ;
366
- } else {
367
- // A custom loader was used instead of network-imports.
368
- // Adding support for a response URL resolve return in custom loaders is
369
- // pending.
370
- return url ;
371
- }
372
- }
373
- return url ;
374
- }
375
-
376
318
/**
377
319
* Get a (possibly still pending) module job from the cache,
378
320
* or create one and return its Promise.
@@ -431,6 +373,7 @@ class ESMLoader {
431
373
const moduleProvider = async ( url , isMain ) => {
432
374
const {
433
375
format : finalFormat ,
376
+ responseURL,
434
377
source,
435
378
} = await this . load ( url , {
436
379
format,
@@ -440,10 +383,10 @@ class ESMLoader {
440
383
const translator = translators . get ( finalFormat ) ;
441
384
442
385
if ( ! translator ) {
443
- throw new ERR_UNKNOWN_MODULE_FORMAT ( finalFormat , url ) ;
386
+ throw new ERR_UNKNOWN_MODULE_FORMAT ( finalFormat , responseURL ) ;
444
387
}
445
388
446
- return FunctionPrototypeCall ( translator , this , url , source , isMain ) ;
389
+ return FunctionPrototypeCall ( translator , this , responseURL , source , isMain ) ;
447
390
} ;
448
391
449
392
const inspectBrk = (
@@ -607,6 +550,29 @@ class ESMLoader {
607
550
format,
608
551
source,
609
552
} = loaded ;
553
+ let responseURL = loaded . responseURL ;
554
+
555
+ if ( responseURL === undefined ) {
556
+ responseURL = url ;
557
+ }
558
+
559
+ let responseURLObj ;
560
+ if ( typeof responseURL === 'string' ) {
561
+ try {
562
+ responseURLObj = new URL ( responseURL ) ;
563
+ } catch {
564
+ // responseURLObj not defined will throw in next branch.
565
+ }
566
+ }
567
+
568
+ if ( responseURLObj ?. href !== responseURL ) {
569
+ throw new ERR_INVALID_RETURN_PROPERTY_VALUE (
570
+ 'undefined or a fully resolved URL string' ,
571
+ hookErrIdentifier ,
572
+ 'responseURL' ,
573
+ responseURL ,
574
+ ) ;
575
+ }
610
576
611
577
if ( format == null ) {
612
578
const dataUrl = RegExpPrototypeExec (
@@ -644,6 +610,7 @@ class ESMLoader {
644
610
645
611
return {
646
612
format,
613
+ responseURL,
647
614
source,
648
615
} ;
649
616
}
0 commit comments