@@ -2042,7 +2042,7 @@ function createRequire(filenameOrURL) {
20422042}
20432043
20442044/**
2045- * Normalize the parent URL/path for cache clearing.
2045+ * Normalize the parent URL for cache clearing.
20462046 * @param {string|URL|undefined } parentURL
20472047 * @returns {{ parentURL: string|undefined, parentPath: string|undefined } }
20482048 */
@@ -2060,18 +2060,10 @@ function normalizeClearCacheParent(parentURL) {
20602060 }
20612061
20622062 validateString ( parentURL , 'options.parentURL' ) ;
2063- if ( path . isAbsolute ( parentURL ) ) {
2064- return {
2065- __proto__ : null ,
2066- parentURL : pathToFileURL ( parentURL ) . href ,
2067- parentPath : parentURL ,
2068- } ;
2069- }
2070-
20712063 const url = URLParse ( parentURL ) ;
20722064 if ( ! url ) {
20732065 throw new ERR_INVALID_ARG_VALUE ( 'options.parentURL' , parentURL ,
2074- 'must be an absolute path or URL' ) ;
2066+ 'must be a URL' ) ;
20752067 }
20762068
20772069 const parentPath =
@@ -2131,7 +2123,11 @@ function resolveClearCacheFilename(specifier, parentPath) {
21312123 }
21322124
21332125 const parent = parentPath ? createParentModuleForClearCache ( parentPath ) : null ;
2134- return Module . _resolveFilename ( request , parent , false ) ;
2126+ const { filename, format } = resolveForCJSWithHooks ( request , parent , false , false ) ;
2127+ if ( format === 'builtin' ) {
2128+ return null ;
2129+ }
2130+ return filename ;
21352131}
21362132
21372133/**
@@ -2165,17 +2161,20 @@ function resolveClearCacheURL(specifier, parentURL, importAttributes) {
21652161/**
21662162 * Remove path cache entries that resolve to a filename.
21672163 * @param {string } filename
2164+ * @param {Set<string>|null } [existingKeys]
21682165 * @returns {boolean } true if any entries were deleted.
21692166 */
2170- function deletePathCacheEntries ( filename ) {
2167+ function deletePathCacheEntries ( filename , existingKeys = null ) {
21712168 const cache = Module . _pathCache ;
21722169 const keys = ObjectKeys ( cache ) ;
21732170 let deleted = false ;
21742171 for ( let i = 0 ; i < keys . length ; i ++ ) {
21752172 const key = keys [ i ] ;
21762173 if ( cache [ key ] === filename ) {
2174+ if ( existingKeys === null || existingKeys . has ( key ) ) {
2175+ deleted = true ;
2176+ }
21772177 delete cache [ key ] ;
2178- deleted = true ;
21792178 }
21802179 }
21812180 return deleted ;
@@ -2184,91 +2183,179 @@ function deletePathCacheEntries(filename) {
21842183/**
21852184 * Remove relative resolve cache entries that resolve to a filename.
21862185 * @param {string } filename
2186+ * @param {Set<string>|null } [existingKeys]
21872187 * @returns {boolean } true if any entries were deleted.
21882188 */
2189- function deleteRelativeResolveCacheEntries ( filename ) {
2189+ function deleteRelativeResolveCacheEntries ( filename , existingKeys = null ) {
21902190 const keys = ObjectKeys ( relativeResolveCache ) ;
21912191 let deleted = false ;
21922192 for ( let i = 0 ; i < keys . length ; i ++ ) {
21932193 const key = keys [ i ] ;
21942194 if ( relativeResolveCache [ key ] === filename ) {
2195+ if ( existingKeys === null || existingKeys . has ( key ) ) {
2196+ deleted = true ;
2197+ }
21952198 delete relativeResolveCache [ key ] ;
2199+ }
2200+ }
2201+ return deleted ;
2202+ }
2203+
2204+ /**
2205+ * Remove cached module references from parent children arrays.
2206+ * @param {Module } targetModule
2207+ * @returns {boolean } true if any references were removed.
2208+ */
2209+ function deleteModuleFromParents ( targetModule ) {
2210+ const keys = ObjectKeys ( Module . _cache ) ;
2211+ let deleted = false ;
2212+ for ( let i = 0 ; i < keys . length ; i ++ ) {
2213+ const cachedModule = Module . _cache [ keys [ i ] ] ;
2214+ const children = cachedModule ?. children ;
2215+ if ( ! ArrayIsArray ( children ) ) {
2216+ continue ;
2217+ }
2218+ const index = ArrayPrototypeIndexOf ( children , targetModule ) ;
2219+ if ( index !== - 1 ) {
2220+ ArrayPrototypeSplice ( children , index , 1 ) ;
21962221 deleted = true ;
21972222 }
21982223 }
21992224 return deleted ;
22002225}
22012226
2227+ /**
2228+ * Resolve a file path for a file URL, stripping search/hash.
2229+ * @param {string } url
2230+ * @returns {string|null }
2231+ */
2232+ function getFilePathFromClearCacheURL ( url ) {
2233+ const parsedURL = URLParse ( url ) ;
2234+ if ( ! parsedURL || parsedURL . protocol !== 'file:' ) {
2235+ return null ;
2236+ }
2237+
2238+ if ( parsedURL . search !== '' || parsedURL . hash !== '' ) {
2239+ parsedURL . search = '' ;
2240+ parsedURL . hash = '' ;
2241+ }
2242+
2243+ try {
2244+ return fileURLToPath ( parsedURL ) ;
2245+ } catch {
2246+ return null ;
2247+ }
2248+ }
2249+
2250+ /**
2251+ * Remove load cache entries for a URL and its file-path variants.
2252+ * @param {import('internal/modules/esm/module_map').LoadCache } loadCache
2253+ * @param {string } url
2254+ * @returns {boolean } true if any entries were deleted.
2255+ */
2256+ function deleteLoadCacheEntries ( loadCache , url ) {
2257+ let deleted = loadCache . deleteAll ( url ) ;
2258+ const filename = getFilePathFromClearCacheURL ( url ) ;
2259+ if ( ! filename ) {
2260+ return deleted ;
2261+ }
2262+
2263+ const urls = [ ] ;
2264+ for ( const entry of loadCache ) {
2265+ ArrayPrototypePush ( urls , entry [ 0 ] ) ;
2266+ }
2267+
2268+ for ( let i = 0 ; i < urls . length ; i ++ ) {
2269+ const cachedURL = urls [ i ] ;
2270+ if ( cachedURL === url ) {
2271+ continue ;
2272+ }
2273+ const cachedFilename = getFilePathFromClearCacheURL ( cachedURL ) ;
2274+ if ( cachedFilename === filename ) {
2275+ loadCache . deleteAll ( cachedURL ) ;
2276+ deleted = true ;
2277+ }
2278+ }
2279+
2280+ return deleted ;
2281+ }
2282+
22022283/**
22032284 * Clear CommonJS and/or ESM module cache entries.
22042285 * @param {string|URL } specifier
22052286 * @param {object } [options]
2206- * @param {'all'|'cjs '|'esm ' } [options.mode]
2287+ * @param {'all'|'commonjs '|'module ' } [options.mode]
22072288 * @param {string|URL } [options.parentURL]
2208- * @param {string } [options.type]
22092289 * @param {Record<string, string> } [options.importAttributes]
2210- * @returns {{ cjs : boolean, esm : boolean } }
2290+ * @returns {{ commonjs : boolean, module : boolean } }
22112291 */
22122292function clearCache ( specifier , options = kEmptyObject ) {
22132293 const isSpecifierURL = isURL ( specifier ) ;
22142294 if ( ! isSpecifierURL ) {
22152295 validateString ( specifier , 'specifier' ) ;
22162296 }
2297+ const specifierKey = isSpecifierURL ? specifier . href : specifier ;
22172298
22182299 validateObject ( options , 'options' ) ;
22192300 const mode = options . mode === undefined ? 'all' : options . mode ;
2220- validateOneOf ( mode , 'options.mode' , [ 'all' , 'cjs' , 'esm' ] ) ;
2221-
2222- if ( options . importAttributes !== undefined && options . type !== undefined ) {
2223- throw new ERR_INVALID_ARG_VALUE ( 'options.importAttributes' , options . importAttributes ,
2224- 'cannot be used with options.type' ) ;
2225- }
2301+ validateOneOf ( mode , 'options.mode' , [ 'all' , 'commonjs' , 'module' ] ) ;
22262302
2227- let importAttributes = options . importAttributes ;
2228- if ( options . type !== undefined ) {
2229- validateString ( options . type , 'options.type' ) ;
2230- importAttributes = { __proto__ : null , type : options . type } ;
2231- } else if ( importAttributes !== undefined ) {
2303+ const importAttributes = options . importAttributes ;
2304+ if ( importAttributes !== undefined ) {
22322305 validateObject ( importAttributes , 'options.importAttributes' ) ;
22332306 }
22342307
22352308 const { parentURL, parentPath } = normalizeClearCacheParent ( options . parentURL ) ;
2236- const result = { __proto__ : null , cjs : false , esm : false } ;
2309+ const result = { __proto__ : null , commonjs : false , module : false } ;
22372310
2238- if ( mode !== 'esm' ) {
2311+ if ( mode !== 'module' ) {
2312+ const pathCacheKeys = new SafeSet ( ObjectKeys ( Module . _pathCache ) ) ;
2313+ const relativeResolveCacheKeys = new SafeSet ( ObjectKeys ( relativeResolveCache ) ) ;
22392314 try {
22402315 const filename = resolveClearCacheFilename ( specifier , parentPath ) ;
22412316 if ( filename ) {
22422317 let deleted = false ;
2243- if ( Module . _cache [ filename ] !== undefined ) {
2318+ const cachedModule = Module . _cache [ filename ] ;
2319+ if ( cachedModule !== undefined ) {
22442320 delete Module . _cache [ filename ] ;
22452321 deleted = true ;
2322+ if ( deleteModuleFromParents ( cachedModule ) ) {
2323+ deleted = true ;
2324+ }
22462325 }
2247- if ( deletePathCacheEntries ( filename ) ) {
2326+ if ( deletePathCacheEntries ( filename , pathCacheKeys ) ) {
22482327 deleted = true ;
22492328 }
2250- if ( deleteRelativeResolveCacheEntries ( filename ) ) {
2329+ if ( deleteRelativeResolveCacheEntries ( filename , relativeResolveCacheKeys ) ) {
22512330 deleted = true ;
22522331 }
2253- result . cjs = deleted ;
2332+ result . commonjs = deleted ;
22542333 }
22552334 } catch ( err ) {
2256- if ( mode === 'cjs ' ) {
2335+ if ( mode === 'commonjs ' ) {
22572336 throw err ;
22582337 }
22592338 }
22602339 }
22612340
2262- if ( mode !== 'cjs ' ) {
2341+ if ( mode !== 'commonjs ' ) {
22632342 try {
22642343 const url = resolveClearCacheURL ( specifier , parentURL , importAttributes ) ;
22652344 const cascadedLoader =
22662345 require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
2267- const loadDeleted = cascadedLoader . loadCache . deleteAll ( url ) ;
2268- const resolveDeleted = cascadedLoader . deleteResolveCache ( url ) ;
2269- result . esm = loadDeleted || resolveDeleted ;
2346+ const loadDeleted = deleteLoadCacheEntries ( cascadedLoader . loadCache , url ) ;
2347+ let resolveDeleted = cascadedLoader . deleteResolveCacheEntry (
2348+ specifierKey ,
2349+ parentURL ,
2350+ importAttributes ?? kEmptyObject ,
2351+ ) ;
2352+ const resolvedPath = getFilePathFromClearCacheURL ( url ) ;
2353+ if ( resolvedPath ) {
2354+ resolveDeleted = cascadedLoader . deleteResolveCacheByFilename ( resolvedPath ) || resolveDeleted ;
2355+ }
2356+ result . module = loadDeleted || resolveDeleted ;
22702357 } catch ( err ) {
2271- if ( mode === 'esm ' ) {
2358+ if ( mode === 'module ' ) {
22722359 throw err ;
22732360 }
22742361 }
0 commit comments