@@ -17,13 +17,11 @@ const {
1717 RegExpPrototypeExec,
1818 SafeArrayIterator,
1919 SafeWeakMap,
20- StringPrototypeStartsWith,
2120 globalThis,
2221} = primordials ;
2322const { MessageChannel } = require ( 'internal/worker/io' ) ;
2423
2524const {
26- ERR_INTERNAL_ASSERTION ,
2725 ERR_INVALID_ARG_TYPE ,
2826 ERR_INVALID_ARG_VALUE ,
2927 ERR_INVALID_RETURN_PROPERTY_VALUE ,
@@ -50,10 +48,6 @@ const { defaultLoad } = require('internal/modules/esm/load');
5048const { translators } = require (
5149 'internal/modules/esm/translators' ) ;
5250const { getOptionValue } = require ( 'internal/options' ) ;
53- const {
54- fetchModule,
55- } = require ( 'internal/modules/esm/fetch_module' ) ;
56-
5751
5852/**
5953 * Prevent the specifier resolution warning from being printed twice
@@ -238,9 +232,7 @@ class ESMLoader {
238232 const module = new ModuleWrap ( url , undefined , source , 0 , 0 ) ;
239233 callbackMap . set ( module , {
240234 importModuleDynamically : ( specifier , { url } , importAssertions ) => {
241- return this . import ( specifier ,
242- this . getBaseURL ( url ) ,
243- importAssertions ) ;
235+ return this . import ( specifier , url , importAssertions ) ;
244236 }
245237 } ) ;
246238
@@ -256,43 +248,6 @@ class ESMLoader {
256248 } ;
257249 }
258250
259- /**
260- * Returns the url to use for the resolution of a given cache key url
261- * These are not guaranteed to be the same.
262- *
263- * In WHATWG HTTP spec for ESM the cache key is the non-I/O bound
264- * synchronous resolution using only string operations
265- * ~= resolveImportMap(new URL(specifier, importerHREF))
266- *
267- * The url used for subsequent resolution is the response URL after
268- * all redirects have been resolved.
269- *
270- * https://example.com/foo redirecting to https://example.com/bar
271- * would have a cache key of https://example.com/foo and baseURL
272- * of https://example.com/bar
273- *
274- * MUST BE SYNCHRONOUS for import.meta initialization
275- * MUST BE CALLED AFTER receiving the url body due to I/O
276- * @param {string } url
277- * @returns {string }
278- */
279- getBaseURL ( url ) {
280- if (
281- StringPrototypeStartsWith ( url , 'http:' ) ||
282- StringPrototypeStartsWith ( url , 'https:' )
283- ) {
284- // The request & response have already settled, so they are in
285- // fetchModule's cache, in which case, fetchModule returns
286- // immediately and synchronously
287- url = fetchModule ( new URL ( url ) , { parentURL : url } ) . resolvedHREF ;
288- // This should only occur if the module hasn't been fetched yet
289- if ( typeof url !== 'string' ) {
290- throw new ERR_INTERNAL_ASSERTION ( `Base url for module ${ url } not loaded.` ) ;
291- }
292- }
293- return url ;
294- }
295-
296251 /**
297252 * Get a (possibly still pending) module job from the cache,
298253 * or create one and return its Promise.
@@ -346,6 +301,7 @@ class ESMLoader {
346301 const moduleProvider = async ( url , isMain ) => {
347302 const {
348303 format : finalFormat ,
304+ responseURL,
349305 source,
350306 } = await this . load ( url , {
351307 format,
@@ -355,10 +311,10 @@ class ESMLoader {
355311 const translator = translators . get ( finalFormat ) ;
356312
357313 if ( ! translator ) {
358- throw new ERR_UNKNOWN_MODULE_FORMAT ( finalFormat , url ) ;
314+ throw new ERR_UNKNOWN_MODULE_FORMAT ( finalFormat , responseURL ) ;
359315 }
360316
361- return FunctionPrototypeCall ( translator , this , url , source , isMain ) ;
317+ return FunctionPrototypeCall ( translator , this , responseURL , source , isMain ) ;
362318 } ;
363319
364320 const inspectBrk = (
@@ -442,6 +398,29 @@ class ESMLoader {
442398 format,
443399 source,
444400 } = loaded ;
401+ let responseURL = loaded . responseURL ;
402+
403+ if ( responseURL === undefined ) {
404+ responseURL = url ;
405+ }
406+
407+ let responseURLObj ;
408+ if ( typeof responseURL === 'string' ) {
409+ try {
410+ responseURLObj = new URL ( responseURL ) ;
411+ } catch {
412+ // responseURLObj not defined will throw in next branch.
413+ }
414+ }
415+
416+ if ( responseURLObj ?. href !== responseURL ) {
417+ throw new ERR_INVALID_RETURN_PROPERTY_VALUE (
418+ 'undefined or a fully resolved URL string' ,
419+ hookErrIdentifier ,
420+ 'responseURL' ,
421+ responseURL ,
422+ ) ;
423+ }
445424
446425 if ( format == null ) {
447426 const dataUrl = RegExpPrototypeExec (
@@ -477,6 +456,7 @@ class ESMLoader {
477456
478457 return {
479458 format,
459+ responseURL,
480460 source,
481461 } ;
482462 }
0 commit comments