| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1030,8 +1030,7 @@ function wrapSafe(filename, content, cjsModuleInstance) { | |||
| 1030 | 1030 | displayErrors: true, | |
| 1031 | 1031 | importModuleDynamically: async (specifier, _, importAssertions) => { | |
| 1032 | 1032 | const loader = asyncESM.esmLoader; | |
| 1033 | - return loader.import(specifier, | ||
| 1034 | - loader.getBaseURL(normalizeReferrerURL(filename)), | ||
| 1033 | + return loader.import(specifier, normalizeReferrerURL(filename), | ||
| 1035 | 1034 | importAssertions); | |
| 1036 | 1035 | }, | |
| 1037 | 1036 | }); | |
@@ -1047,8 +1046,7 @@ function wrapSafe(filename, content, cjsModuleInstance) { | |||
| 1047 | 1046 | filename, | |
| 1048 | 1047 | importModuleDynamically(specifier, _, importAssertions) { | |
| 1049 | 1048 | const loader = asyncESM.esmLoader; | |
| 1050 | - return loader.import(specifier, | ||
| 1051 | - loader.getBaseURL(normalizeReferrerURL(filename)), | ||
| 1049 | + return loader.import(specifier, normalizeReferrerURL(filename), | ||
| 1052 | 1050 | importAssertions); | |
| 1053 | 1051 | }, | |
| 1054 | 1052 | }); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -238,17 +238,6 @@ function fetchModule(parsed, { parentURL }) { | |||
| 238 | 238 | return fetchWithRedirects(parsed); | |
| 239 | 239 | } | |
| 240 | 240 | ||
| 241 | - /** | ||
| 242 | - * Checks if the given canonical URL exists in the fetch cache | ||
| 243 | - * | ||
| 244 | - * @param {string} key | ||
| 245 | - * @returns {boolean} | ||
| 246 | - */ | ||
| 247 | - function inFetchCache(key) { | ||
| 248 | - return cacheForGET.has(key); | ||
| 249 | - } | ||
| 250 | - | ||
| 251 | 241 | module.exports = { | |
| 252 | 242 | fetchModule, | |
| 253 | - inFetchCache, | ||
| 254 | 243 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -26,15 +26,13 @@ function createImportMetaResolve(defaultParentUrl) { | |||
| 26 | 26 | * @param {{url: string}} context | |
| 27 | 27 | */ | |
| 28 | 28 | function initializeImportMeta(meta, context) { | |
| 29 | - let url = context.url; | ||
| 29 | + const { url } = context; | ||
| 30 | 30 | ||
| 31 | 31 | // Alphabetical | |
| 32 | 32 | if (experimentalImportMetaResolve) { | |
| 33 | 33 | meta.resolve = createImportMetaResolve(url); | |
| 34 | 34 | } | |
| 35 | 35 | ||
| 36 | - url = asyncESM.esmLoader.getBaseURL(url); | ||
| 37 | - | ||
| 38 | 36 | meta.url = url; | |
| 39 | 37 | } | |
| 40 | 38 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,8 +1,67 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | + const { | ||
| 4 | + ArrayPrototypePush, | ||
| 5 | + RegExpPrototypeExec, | ||
| 6 | + decodeURIComponent, | ||
| 7 | + } = primordials; | ||
| 8 | + | ||
| 3 | 9 | const { defaultGetFormat } = require('internal/modules/esm/get_format'); | |
| 4 | - const { defaultGetSource } = require('internal/modules/esm/get_source'); | ||
| 5 | 10 | const { validateAssertions } = require('internal/modules/esm/assert'); | |
| 11 | + const { getOptionValue } = require('internal/options'); | ||
| 12 | + const { fetchModule } = require('internal/modules/esm/fetch_module'); | ||
| 13 | + | ||
| 14 | + // Do not eagerly grab .manifest, it may be in TDZ | ||
| 15 | + const policy = getOptionValue('--experimental-policy') ? | ||
| 16 | + require('internal/process/policy') : | ||
| 17 | + null; | ||
| 18 | + const experimentalNetworkImports = | ||
| 19 | + getOptionValue('--experimental-network-imports'); | ||
| 20 | + | ||
| 21 | + const { Buffer: { from: BufferFrom } } = require('buffer'); | ||
| 22 | + | ||
| 23 | + const { readFile: readFileAsync } = require('internal/fs/promises').exports; | ||
| 24 | + const { URL } = require('internal/url'); | ||
| 25 | + const { | ||
| 26 | + ERR_INVALID_URL, | ||
| 27 | + ERR_UNSUPPORTED_ESM_URL_SCHEME, | ||
| 28 | + } = require('internal/errors').codes; | ||
| 29 | + | ||
| 30 | + const DATA_URL_PATTERN = /^[^/]+\/[^,;]+(?:[^,]*?)(;base64)?,([\s\S]*)$/; | ||
| 31 | + | ||
| 32 | + async function getSource(url, context) { | ||
| 33 | + const parsed = new URL(url); | ||
| 34 | + let responseURL = url; | ||
| 35 | + let source; | ||
| 36 | + if (parsed.protocol === 'file:') { | ||
| 37 | + source = await readFileAsync(parsed); | ||
| 38 | + } else if (parsed.protocol === 'data:') { | ||
| 39 | + const match = RegExpPrototypeExec(DATA_URL_PATTERN, parsed.pathname); | ||
| 40 | + if (!match) { | ||
| 41 | + throw new ERR_INVALID_URL(url); | ||
| 42 | + } | ||
| 43 | + const { 1: base64, 2: body } = match; | ||
| 44 | + source = BufferFrom(decodeURIComponent(body), base64 ? 'base64' : 'utf8'); | ||
| 45 | + } else if (experimentalNetworkImports && ( | ||
| 46 | + parsed.protocol === 'https:' || | ||
| 47 | + parsed.protocol === 'http:' | ||
| 48 | + )) { | ||
| 49 | + const res = await fetchModule(parsed, context); | ||
| 50 | + source = await res.body; | ||
| 51 | + responseURL = res.resolvedHREF; | ||
| 52 | + } else { | ||
| 53 | + const supportedSchemes = ['file', 'data']; | ||
| 54 | + if (experimentalNetworkImports) { | ||
| 55 | + ArrayPrototypePush(supportedSchemes, 'http', 'https'); | ||
| 56 | + } | ||
| 57 | + throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, supportedSchemes); | ||
| 58 | + } | ||
| 59 | + if (policy?.manifest) { | ||
| 60 | + policy.manifest.assertIntegrity(parsed, source); | ||
| 61 | + } | ||
| 62 | + return { responseURL, source }; | ||
| 63 | + } | ||
| 64 | + | ||
| 6 | 65 | ||
| 7 | 66 | /** | |
| 8 | 67 | * Node.js default load hook. | |
@@ -11,6 +70,7 @@ const { validateAssertions } = require('internal/modules/esm/assert'); | |||
| 11 | 70 | * @returns {object} | |
| 12 | 71 | */ | |
| 13 | 72 | async function defaultLoad(url, context) { | |
| 73 | + let responseURL = url; | ||
| 14 | 74 | const { importAssertions } = context; | |
| 15 | 75 | let { | |
| 16 | 76 | format, | |
@@ -29,11 +89,12 @@ async function defaultLoad(url, context) { | |||
| 29 | 89 | ) { | |
| 30 | 90 | source = null; | |
| 31 | 91 | } else if (source == null) { | |
| 32 | - source = await defaultGetSource(url, context); | ||
| 92 | + ({ responseURL, source } = await getSource(url, context)); | ||
| 33 | 93 | } | |
| 34 | 94 | ||
| 35 | 95 | return { | |
| 36 | 96 | format, | |
| 97 | + responseURL, | ||
| 37 | 98 | source, | |
| 38 | 99 | }; | |
| 39 | 100 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -76,12 +76,7 @@ class ModuleJob { | |||
| 76 | 76 | // these `link` callbacks depending on each other. | |
| 77 | 77 | const dependencyJobs = []; | |
| 78 | 78 | const promises = this.module.link(async (specifier, assertions) => { | |
| 79 | - const base = await this.loader.getBaseURL(url); | ||
| 80 | - const baseURL = typeof base === 'string' ? | ||
| 81 | - base : | ||
| 82 | - base.resolvedHREF; | ||
| 83 | - | ||
| 84 | - const jobPromise = this.loader.getModuleJob(specifier, baseURL, assertions); | ||
| 79 | + const jobPromise = this.loader.getModuleJob(specifier, url, assertions); | ||
| 85 | 80 | ArrayPrototypePush(dependencyJobs, jobPromise); | |
| 86 | 81 | const job = await jobPromise; | |
| 87 | 82 | return job.modulePromise; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -103,9 +103,7 @@ function errPath(url) { | |||
| 103 | 103 | } | |
| 104 | 104 | ||
| 105 | 105 | async function importModuleDynamically(specifier, { url }, assertions) { | |
| 106 | - return asyncESM.esmLoader.import(specifier, | ||
| 107 | - asyncESM.esmLoader.getBaseURL(url), | ||
| 108 | - assertions); | ||
| 106 | + return asyncESM.esmLoader.import(specifier, url, assertions); | ||
| 109 | 107 | } | |
| 110 | 108 | ||
| 111 | 109 | // Strategy for loading a standard JavaScript module. | |
@@ -116,9 +114,7 @@ translators.set('module', async function moduleStrategy(url, source, isMain) { | |||
| 116 | 114 | debug(`Translating StandardModule ${url}`); | |
| 117 | 115 | const module = new ModuleWrap(url, undefined, source, 0, 0); | |
| 118 | 116 | moduleWrap.callbackMap.set(module, { | |
| 119 | - initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { | ||
| 120 | - url: wrap.url | ||
| 121 | - }), | ||
| 117 | + initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }), | ||
| 122 | 118 | importModuleDynamically, | |
| 123 | 119 | }); | |
| 124 | 120 | return module; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments