diff --git a/packages/react-devtools-extensions/src/parseHookNames.js b/packages/react-devtools-extensions/src/parseHookNames.js index dc2b8b3c4bc92..9d183375e8052 100644 --- a/packages/react-devtools-extensions/src/parseHookNames.js +++ b/packages/react-devtools-extensions/src/parseHookNames.js @@ -27,7 +27,6 @@ import type {Thenable} from 'shared/ReactTypes'; import type {SourceConsumer} from './astUtils'; const SOURCE_MAP_REGEX = / ?sourceMappingURL=([^\s'"]+)/gm; -const ABSOLUTE_URL_REGEX = /^https?:\/\//i; const MAX_SOURCE_LENGTH = 100_000_000; type AST = mixed; @@ -282,14 +281,7 @@ function extractAndLoadSourceMaps( } let url = sourceMappingURLs[i].split('=')[1]; - if (ABSOLUTE_URL_REGEX.test(url)) { - const baseURL = url.slice(0, url.lastIndexOf('/')); - url = `${baseURL}/${url}`; - - if (!isValidUrl(url)) { - throw new Error(`Invalid source map URL "${url}"`); - } - } else if (!url.startsWith('/')) { + if (!url.startsWith('http') && !url.startsWith('/')) { // Resolve paths relative to the location of the file name const lastSlashIdx = runtimeSourceURL.lastIndexOf('/'); if (lastSlashIdx !== -1) { @@ -440,16 +432,6 @@ function findHookNames( return map; } -function isValidUrl(possibleURL: string): boolean { - try { - // eslint-disable-next-line no-new - new URL(possibleURL); - } catch (_) { - return false; - } - return true; -} - function loadSourceFiles( locationKeyToHookSourceData: Map, ): Promise<*> { diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index d56819a8ba0bd..57b3de2e08a49 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -3240,6 +3240,17 @@ export function attach( // Never dehydrate the "hooks" object at the top levels. return true; } + + if ( + path[path.length - 2] === 'hookSource' && + path[path.length - 1] === 'fileName' + ) { + // It's important to preserve the full file name (URL) for hook sources + // in case the user has enabled the named hooks feature. + // Otherwise the frontend may end up with a partial URL which it can't load. + return true; + } + if ( path[path.length - 1] === 'subHooks' || path[path.length - 2] === 'subHooks' diff --git a/packages/react-devtools-shared/src/hydration.js b/packages/react-devtools-shared/src/hydration.js index 2c2d696089371..0b936462d5fe2 100644 --- a/packages/react-devtools-shared/src/hydration.js +++ b/packages/react-devtools-shared/src/hydration.js @@ -160,7 +160,12 @@ export function dehydrate( }; case 'string': - return data.length <= 500 ? data : data.slice(0, 500) + '...'; + isPathAllowedCheck = isPathAllowed(path); + if (isPathAllowedCheck) { + return data; + } else { + return data.length <= 500 ? data : data.slice(0, 500) + '...'; + } case 'bigint': cleaned.push(path);