@@ -68,14 +68,7 @@ export async function bundleThemeExtension(
6868 options . stdout . write ( `Bundling theme extension ${ extension . localIdentifier } ...` )
6969 const files = await themeExtensionFiles ( extension )
7070
71- await Promise . all (
72- files . map ( function ( filepath ) {
73- const relativePathName = relativePath ( extension . directory , filepath )
74- const outputFile = joinPath ( extension . outputPath , relativePathName )
75- if ( filepath === outputFile ) return
76- return copyFile ( filepath , outputFile )
77- } ) ,
78- )
71+ await copyFiles ( files , extension . directory , extension . outputPath )
7972}
8073
8174export async function copyFilesForExtension (
@@ -93,14 +86,8 @@ export async function copyFilesForExtension(
9386 ignore : ignored ,
9487 } )
9588
96- await Promise . all (
97- files . map ( function ( filepath ) {
98- const relativePathName = relativePath ( extension . directory , filepath )
99- const outputFile = joinPath ( extension . outputPath , relativePathName )
100- if ( filepath === outputFile ) return
101- return copyFile ( filepath , outputFile )
102- } ) ,
103- )
89+ await copyFiles ( files , extension . directory , extension . outputPath )
90+
10491 options . stdout . write ( `${ extension . localIdentifier } successfully built` )
10592}
10693
@@ -121,6 +108,41 @@ function onResult(result: Awaited<ReturnType<typeof esBuild>> | null, options: B
121108 }
122109}
123110
111+ async function copyFiles ( files : string [ ] , directory : string , outputPath : string ) : Promise < void > {
112+ const results = await Promise . allSettled (
113+ files . map ( async function ( filepath ) {
114+ const relativePathName = relativePath ( directory , filepath )
115+ const outputFile = joinPath ( outputPath , relativePathName )
116+ if ( filepath === outputFile ) return { status : 'skipped' , filepath}
117+
118+ try {
119+ await copyFile ( filepath , outputFile )
120+ return { status : 'success' , filepath}
121+ // eslint-disable-next-line no-catch-all/no-catch-all
122+ } catch ( error ) {
123+ // Log warning but don't fail the entire process
124+ // We intentionally catch all errors here to continue copying other files
125+ outputDebug ( `Failed to copy file ${ filepath } : ${ error } ` )
126+ return { status : 'failed' , filepath, error}
127+ }
128+ } ) ,
129+ )
130+
131+ // Report any failures as warnings
132+ const failures = results . filter ( ( result ) => {
133+ return result . status === 'rejected' || ( result . status === 'fulfilled' && result . value ?. status === 'failed' )
134+ } )
135+
136+ if ( failures . length > 0 ) {
137+ const failedFiles = failures . map ( ( failure ) => {
138+ if ( failure . status === 'rejected' ) return 'unknown file'
139+ const value = ( failure as PromiseFulfilledResult < { status : string ; filepath : string } > ) . value
140+ return value . filepath
141+ } )
142+ outputDebug ( `Warning: ${ failures . length } file(s) could not be copied: ${ failedFiles . join ( ', ' ) } ` )
143+ }
144+ }
145+
124146export function getESBuildOptions ( options : BundleOptions , processEnv = process . env ) : Parameters < typeof esContext > [ 0 ] {
125147 const validEnvs = pickBy ( processEnv , ( value , key ) => EsbuildEnvVarRegex . test ( key ) && value )
126148
0 commit comments