1- import type { ILogger , OutputCleanContext , OutputCleanupDeclarations , OutputCleanupPathDeclaration , OutputPlugin , PluginOptions } from '../plugins/plugin-core'
1+ import type { ILogger , OutputCleanContext , OutputCleanupDeclarations , OutputCleanupPathDeclaration , OutputFileDeclaration , OutputPlugin , PluginOptions } from '../plugins/plugin-core'
22import type { ProtectedPathRule , ProtectionMode , ProtectionRuleMatcher } from '../ProtectedDeletionGuard'
33import * as fs from 'node:fs'
44import * as path from 'node:path'
@@ -130,14 +130,18 @@ async function collectPluginCleanupDeclarations(
130130
131131async function collectPluginCleanupSnapshot (
132132 plugin : OutputPlugin ,
133- cleanCtx : OutputCleanContext
133+ cleanCtx : OutputCleanContext ,
134+ predeclaredOutputs ?: ReadonlyMap < OutputPlugin , readonly OutputFileDeclaration [ ] >
134135) : Promise < {
135136 readonly plugin : OutputPlugin
136137 readonly outputs : Awaited < ReturnType < OutputPlugin [ 'declareOutputFiles' ] > >
137138 readonly cleanup : OutputCleanupDeclarations
138139} > {
140+ const existingOutputDeclarations = predeclaredOutputs ?. get ( plugin )
139141 const [ outputs , cleanup ] = await Promise . all ( [
140- plugin . declareOutputFiles ( { ...cleanCtx , dryRun : true } ) ,
142+ existingOutputDeclarations != null
143+ ? Promise . resolve ( existingOutputDeclarations )
144+ : plugin . declareOutputFiles ( { ...cleanCtx , dryRun : true } ) ,
141145 collectPluginCleanupDeclarations ( plugin , cleanCtx )
142146 ] )
143147
@@ -258,7 +262,8 @@ function logCleanupProtectionConflicts(
258262 */
259263export async function collectDeletionTargets (
260264 outputPlugins : readonly OutputPlugin [ ] ,
261- cleanCtx : OutputCleanContext
265+ cleanCtx : OutputCleanContext ,
266+ predeclaredOutputs ?: ReadonlyMap < OutputPlugin , readonly OutputFileDeclaration [ ] >
262267) : Promise < {
263268 filesToDelete : string [ ]
264269 dirsToDelete : string [ ]
@@ -272,7 +277,9 @@ export async function collectDeletionTargets(
272277 const excludeScanGlobSet = new Set < string > ( DEFAULT_CLEANUP_SCAN_EXCLUDE_GLOBS )
273278 const outputPathOwners = new Map < string , string [ ] > ( )
274279
275- const pluginSnapshots = await Promise . all ( outputPlugins . map ( async plugin => collectPluginCleanupSnapshot ( plugin , cleanCtx ) ) )
280+ const pluginSnapshots = await Promise . all (
281+ outputPlugins . map ( async plugin => collectPluginCleanupSnapshot ( plugin , cleanCtx , predeclaredOutputs ) )
282+ )
276283
277284 const addDeletePath = ( rawPath : string , kind : 'file' | 'directory' ) : void => {
278285 if ( kind === 'directory' ) deleteDirs . add ( resolveAbsolutePath ( rawPath ) )
@@ -491,19 +498,22 @@ function logCleanupPlanDiagnostics(
491498export async function performCleanup (
492499 outputPlugins : readonly OutputPlugin [ ] ,
493500 cleanCtx : OutputCleanContext ,
494- logger : ILogger
501+ logger : ILogger ,
502+ predeclaredOutputs ?: ReadonlyMap < OutputPlugin , readonly OutputFileDeclaration [ ] >
495503) : Promise < CleanupResult > {
496- const outputs = await collectAllPluginOutputs ( outputPlugins , cleanCtx ) // Collect outputs for logging
497- logger . debug ( 'Collected outputs for cleanup' , {
498- projectDirs : outputs . projectDirs . length ,
499- projectFiles : outputs . projectFiles . length ,
500- globalDirs : outputs . globalDirs . length ,
501- globalFiles : outputs . globalFiles . length
502- } )
504+ if ( predeclaredOutputs != null ) {
505+ const outputs = await collectAllPluginOutputs ( outputPlugins , cleanCtx , predeclaredOutputs )
506+ logger . debug ( 'Collected outputs for cleanup' , {
507+ projectDirs : outputs . projectDirs . length ,
508+ projectFiles : outputs . projectFiles . length ,
509+ globalDirs : outputs . globalDirs . length ,
510+ globalFiles : outputs . globalFiles . length
511+ } )
512+ }
503513
504514 let targets : Awaited < ReturnType < typeof collectDeletionTargets > >
505515 try {
506- targets = await collectDeletionTargets ( outputPlugins , cleanCtx )
516+ targets = await collectDeletionTargets ( outputPlugins , cleanCtx , predeclaredOutputs )
507517 }
508518 catch ( error ) {
509519 if ( error instanceof CleanupProtectionConflictError ) {
0 commit comments