@@ -2033,7 +2033,7 @@ function createRequire(filenameOrURL) {
20332033}
20342034
20352035/**
2036- * Normalize the parent URL/path for cache clearing.
2036+ * Normalize the parent URL for cache clearing.
20372037 * @param {string|URL|undefined } parentURL
20382038 * @returns {{ parentURL: string|undefined, parentPath: string|undefined } }
20392039 */
@@ -2051,18 +2051,10 @@ function normalizeClearCacheParent(parentURL) {
20512051 }
20522052
20532053 validateString ( parentURL , 'options.parentURL' ) ;
2054- if ( path . isAbsolute ( parentURL ) ) {
2055- return {
2056- __proto__ : null ,
2057- parentURL : pathToFileURL ( parentURL ) . href ,
2058- parentPath : parentURL ,
2059- } ;
2060- }
2061-
20622054 const url = URLParse ( parentURL ) ;
20632055 if ( ! url ) {
20642056 throw new ERR_INVALID_ARG_VALUE ( 'options.parentURL' , parentURL ,
2065- 'must be an absolute path or URL' ) ;
2057+ 'must be a URL' ) ;
20662058 }
20672059
20682060 const parentPath =
@@ -2122,7 +2114,11 @@ function resolveClearCacheFilename(specifier, parentPath) {
21222114 }
21232115
21242116 const parent = parentPath ? createParentModuleForClearCache ( parentPath ) : null ;
2125- return Module . _resolveFilename ( request , parent , false ) ;
2117+ const { filename, format } = resolveForCJSWithHooks ( request , parent , false , false ) ;
2118+ if ( format === 'builtin' ) {
2119+ return null ;
2120+ }
2121+ return filename ;
21262122}
21272123
21282124/**
@@ -2156,17 +2152,20 @@ function resolveClearCacheURL(specifier, parentURL, importAttributes) {
21562152/**
21572153 * Remove path cache entries that resolve to a filename.
21582154 * @param {string } filename
2155+ * @param {Set<string>|null } [existingKeys]
21592156 * @returns {boolean } true if any entries were deleted.
21602157 */
2161- function deletePathCacheEntries ( filename ) {
2158+ function deletePathCacheEntries ( filename , existingKeys = null ) {
21622159 const cache = Module . _pathCache ;
21632160 const keys = ObjectKeys ( cache ) ;
21642161 let deleted = false ;
21652162 for ( let i = 0 ; i < keys . length ; i ++ ) {
21662163 const key = keys [ i ] ;
21672164 if ( cache [ key ] === filename ) {
2165+ if ( existingKeys === null || existingKeys . has ( key ) ) {
2166+ deleted = true ;
2167+ }
21682168 delete cache [ key ] ;
2169- deleted = true ;
21702169 }
21712170 }
21722171 return deleted ;
@@ -2175,91 +2174,179 @@ function deletePathCacheEntries(filename) {
21752174/**
21762175 * Remove relative resolve cache entries that resolve to a filename.
21772176 * @param {string } filename
2177+ * @param {Set<string>|null } [existingKeys]
21782178 * @returns {boolean } true if any entries were deleted.
21792179 */
2180- function deleteRelativeResolveCacheEntries ( filename ) {
2180+ function deleteRelativeResolveCacheEntries ( filename , existingKeys = null ) {
21812181 const keys = ObjectKeys ( relativeResolveCache ) ;
21822182 let deleted = false ;
21832183 for ( let i = 0 ; i < keys . length ; i ++ ) {
21842184 const key = keys [ i ] ;
21852185 if ( relativeResolveCache [ key ] === filename ) {
2186+ if ( existingKeys === null || existingKeys . has ( key ) ) {
2187+ deleted = true ;
2188+ }
21862189 delete relativeResolveCache [ key ] ;
2190+ }
2191+ }
2192+ return deleted ;
2193+ }
2194+
2195+ /**
2196+ * Remove cached module references from parent children arrays.
2197+ * @param {Module } targetModule
2198+ * @returns {boolean } true if any references were removed.
2199+ */
2200+ function deleteModuleFromParents ( targetModule ) {
2201+ const keys = ObjectKeys ( Module . _cache ) ;
2202+ let deleted = false ;
2203+ for ( let i = 0 ; i < keys . length ; i ++ ) {
2204+ const cachedModule = Module . _cache [ keys [ i ] ] ;
2205+ const children = cachedModule ?. children ;
2206+ if ( ! ArrayIsArray ( children ) ) {
2207+ continue ;
2208+ }
2209+ const index = ArrayPrototypeIndexOf ( children , targetModule ) ;
2210+ if ( index !== - 1 ) {
2211+ ArrayPrototypeSplice ( children , index , 1 ) ;
21872212 deleted = true ;
21882213 }
21892214 }
21902215 return deleted ;
21912216}
21922217
2218+ /**
2219+ * Resolve a file path for a file URL, stripping search/hash.
2220+ * @param {string } url
2221+ * @returns {string|null }
2222+ */
2223+ function getFilePathFromClearCacheURL ( url ) {
2224+ const parsedURL = URLParse ( url ) ;
2225+ if ( ! parsedURL || parsedURL . protocol !== 'file:' ) {
2226+ return null ;
2227+ }
2228+
2229+ if ( parsedURL . search !== '' || parsedURL . hash !== '' ) {
2230+ parsedURL . search = '' ;
2231+ parsedURL . hash = '' ;
2232+ }
2233+
2234+ try {
2235+ return fileURLToPath ( parsedURL ) ;
2236+ } catch {
2237+ return null ;
2238+ }
2239+ }
2240+
2241+ /**
2242+ * Remove load cache entries for a URL and its file-path variants.
2243+ * @param {import('internal/modules/esm/module_map').LoadCache } loadCache
2244+ * @param {string } url
2245+ * @returns {boolean } true if any entries were deleted.
2246+ */
2247+ function deleteLoadCacheEntries ( loadCache , url ) {
2248+ let deleted = loadCache . deleteAll ( url ) ;
2249+ const filename = getFilePathFromClearCacheURL ( url ) ;
2250+ if ( ! filename ) {
2251+ return deleted ;
2252+ }
2253+
2254+ const urls = [ ] ;
2255+ for ( const entry of loadCache ) {
2256+ ArrayPrototypePush ( urls , entry [ 0 ] ) ;
2257+ }
2258+
2259+ for ( let i = 0 ; i < urls . length ; i ++ ) {
2260+ const cachedURL = urls [ i ] ;
2261+ if ( cachedURL === url ) {
2262+ continue ;
2263+ }
2264+ const cachedFilename = getFilePathFromClearCacheURL ( cachedURL ) ;
2265+ if ( cachedFilename === filename ) {
2266+ loadCache . deleteAll ( cachedURL ) ;
2267+ deleted = true ;
2268+ }
2269+ }
2270+
2271+ return deleted ;
2272+ }
2273+
21932274/**
21942275 * Clear CommonJS and/or ESM module cache entries.
21952276 * @param {string|URL } specifier
21962277 * @param {object } [options]
2197- * @param {'all'|'cjs '|'esm ' } [options.mode]
2278+ * @param {'all'|'commonjs '|'module ' } [options.mode]
21982279 * @param {string|URL } [options.parentURL]
2199- * @param {string } [options.type]
22002280 * @param {Record<string, string> } [options.importAttributes]
2201- * @returns {{ cjs : boolean, esm : boolean } }
2281+ * @returns {{ commonjs : boolean, module : boolean } }
22022282 */
22032283function clearCache ( specifier , options = kEmptyObject ) {
22042284 const isSpecifierURL = isURL ( specifier ) ;
22052285 if ( ! isSpecifierURL ) {
22062286 validateString ( specifier , 'specifier' ) ;
22072287 }
2288+ const specifierKey = isSpecifierURL ? specifier . href : specifier ;
22082289
22092290 validateObject ( options , 'options' ) ;
22102291 const mode = options . mode === undefined ? 'all' : options . mode ;
2211- validateOneOf ( mode , 'options.mode' , [ 'all' , 'cjs' , 'esm' ] ) ;
2212-
2213- if ( options . importAttributes !== undefined && options . type !== undefined ) {
2214- throw new ERR_INVALID_ARG_VALUE ( 'options.importAttributes' , options . importAttributes ,
2215- 'cannot be used with options.type' ) ;
2216- }
2292+ validateOneOf ( mode , 'options.mode' , [ 'all' , 'commonjs' , 'module' ] ) ;
22172293
2218- let importAttributes = options . importAttributes ;
2219- if ( options . type !== undefined ) {
2220- validateString ( options . type , 'options.type' ) ;
2221- importAttributes = { __proto__ : null , type : options . type } ;
2222- } else if ( importAttributes !== undefined ) {
2294+ const importAttributes = options . importAttributes ;
2295+ if ( importAttributes !== undefined ) {
22232296 validateObject ( importAttributes , 'options.importAttributes' ) ;
22242297 }
22252298
22262299 const { parentURL, parentPath } = normalizeClearCacheParent ( options . parentURL ) ;
2227- const result = { __proto__ : null , cjs : false , esm : false } ;
2300+ const result = { __proto__ : null , commonjs : false , module : false } ;
22282301
2229- if ( mode !== 'esm' ) {
2302+ if ( mode !== 'module' ) {
2303+ const pathCacheKeys = new SafeSet ( ObjectKeys ( Module . _pathCache ) ) ;
2304+ const relativeResolveCacheKeys = new SafeSet ( ObjectKeys ( relativeResolveCache ) ) ;
22302305 try {
22312306 const filename = resolveClearCacheFilename ( specifier , parentPath ) ;
22322307 if ( filename ) {
22332308 let deleted = false ;
2234- if ( Module . _cache [ filename ] !== undefined ) {
2309+ const cachedModule = Module . _cache [ filename ] ;
2310+ if ( cachedModule !== undefined ) {
22352311 delete Module . _cache [ filename ] ;
22362312 deleted = true ;
2313+ if ( deleteModuleFromParents ( cachedModule ) ) {
2314+ deleted = true ;
2315+ }
22372316 }
2238- if ( deletePathCacheEntries ( filename ) ) {
2317+ if ( deletePathCacheEntries ( filename , pathCacheKeys ) ) {
22392318 deleted = true ;
22402319 }
2241- if ( deleteRelativeResolveCacheEntries ( filename ) ) {
2320+ if ( deleteRelativeResolveCacheEntries ( filename , relativeResolveCacheKeys ) ) {
22422321 deleted = true ;
22432322 }
2244- result . cjs = deleted ;
2323+ result . commonjs = deleted ;
22452324 }
22462325 } catch ( err ) {
2247- if ( mode === 'cjs ' ) {
2326+ if ( mode === 'commonjs ' ) {
22482327 throw err ;
22492328 }
22502329 }
22512330 }
22522331
2253- if ( mode !== 'cjs ' ) {
2332+ if ( mode !== 'commonjs ' ) {
22542333 try {
22552334 const url = resolveClearCacheURL ( specifier , parentURL , importAttributes ) ;
22562335 const cascadedLoader =
22572336 require ( 'internal/modules/esm/loader' ) . getOrInitializeCascadedLoader ( ) ;
2258- const loadDeleted = cascadedLoader . loadCache . deleteAll ( url ) ;
2259- const resolveDeleted = cascadedLoader . deleteResolveCache ( url ) ;
2260- result . esm = loadDeleted || resolveDeleted ;
2337+ const loadDeleted = deleteLoadCacheEntries ( cascadedLoader . loadCache , url ) ;
2338+ let resolveDeleted = cascadedLoader . deleteResolveCacheEntry (
2339+ specifierKey ,
2340+ parentURL ,
2341+ importAttributes ?? kEmptyObject ,
2342+ ) ;
2343+ const resolvedPath = getFilePathFromClearCacheURL ( url ) ;
2344+ if ( resolvedPath ) {
2345+ resolveDeleted = cascadedLoader . deleteResolveCacheByFilename ( resolvedPath ) || resolveDeleted ;
2346+ }
2347+ result . module = loadDeleted || resolveDeleted ;
22612348 } catch ( err ) {
2262- if ( mode === 'esm ' ) {
2349+ if ( mode === 'module ' ) {
22632350 throw err ;
22642351 }
22652352 }
0 commit comments