@@ -9,12 +9,12 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
99 private device : Mobile . IDevice ,
1010 private $logger : ILogger ,
1111 private $iosDeviceOperations : IIOSDeviceOperations ,
12- private $fs : IFileSystem
12+ private $fs : IFileSystem ,
1313 ) { }
1414
1515 public async listFiles (
1616 devicePath : string ,
17- appIdentifier : string
17+ appIdentifier : string ,
1818 ) : Promise < void > {
1919 if ( ! devicePath ) {
2020 devicePath = "." ;
@@ -31,10 +31,33 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
3131 this . $logger . info ( children . join ( EOL ) ) ;
3232 }
3333
34+ public async getDirectoryEntries (
35+ devicePath : string ,
36+ appIdentifier : string ,
37+ ) : Promise < string [ ] | null > {
38+ try {
39+ const result = await this . $iosDeviceOperations . listDirectory ( [
40+ {
41+ deviceId : this . device . deviceInfo . identifier ,
42+ path : devicePath ,
43+ appId : appIdentifier ,
44+ } ,
45+ ] ) ;
46+ const entries =
47+ result ?. [ this . device . deviceInfo . identifier ] ?. [ 0 ] ?. response ;
48+ return Array . isArray ( entries ) ? entries : null ;
49+ } catch ( err ) {
50+ this . $logger . trace (
51+ `Unable to list directory '${ devicePath } ' for application ${ appIdentifier } : ${ err . message } ` ,
52+ ) ;
53+ return null ;
54+ }
55+ }
56+
3457 public async getFile (
3558 deviceFilePath : string ,
3659 appIdentifier : string ,
37- outputFilePath ?: string
60+ outputFilePath ?: string ,
3861 ) : Promise < void > {
3962 if ( outputFilePath ) {
4063 await this . $iosDeviceOperations . downloadFiles ( [
@@ -50,14 +73,14 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
5073
5174 const fileContent = await this . getFileContent (
5275 deviceFilePath ,
53- appIdentifier
76+ appIdentifier ,
5477 ) ;
5578 this . $logger . info ( fileContent ) ;
5679 }
5780
5881 public async getFileContent (
5982 deviceFilePath : string ,
60- appIdentifier : string
83+ appIdentifier : string ,
6184 ) : Promise < string > {
6285 const result = await this . $iosDeviceOperations . readFiles ( [
6386 {
@@ -73,7 +96,7 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
7396 public async putFile (
7497 localFilePath : string ,
7598 deviceFilePath : string ,
76- appIdentifier : string
99+ appIdentifier : string ,
77100 ) : Promise < void > {
78101 await this . uploadFilesCore ( [
79102 {
@@ -86,7 +109,7 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
86109
87110 public async deleteFile (
88111 deviceFilePath : string ,
89- appIdentifier : string
112+ appIdentifier : string ,
90113 ) : Promise < void > {
91114 await this . $iosDeviceOperations . deleteFiles (
92115 [
@@ -98,25 +121,25 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
98121 ] ,
99122 ( err : IOSDeviceLib . IDeviceError ) => {
100123 this . $logger . trace (
101- `Error while deleting file: ${ deviceFilePath } : ${ err . message } with code: ${ err . code } `
124+ `Error while deleting file: ${ deviceFilePath } : ${ err . message } with code: ${ err . code } ` ,
102125 ) ;
103126
104127 if ( err . code !== IOSDeviceFileSystem . AFC_DELETE_FILE_NOT_FOUND_ERROR ) {
105128 this . $logger . warn (
106- `Cannot delete file: ${ deviceFilePath } . Reason: ${ err . message } `
129+ `Cannot delete file: ${ deviceFilePath } . Reason: ${ err . message } ` ,
107130 ) ;
108131 }
109- }
132+ } ,
110133 ) ;
111134 }
112135
113136 public async transferFiles (
114137 deviceAppData : Mobile . IDeviceAppData ,
115- localToDevicePaths : Mobile . ILocalToDevicePathData [ ]
138+ localToDevicePaths : Mobile . ILocalToDevicePathData [ ] ,
116139 ) : Promise < Mobile . ILocalToDevicePathData [ ] > {
117140 const filesToUpload : Mobile . ILocalToDevicePathData [ ] = _ . filter (
118141 localToDevicePaths ,
119- ( l ) => this . $fs . getFsStats ( l . getLocalPath ( ) ) . isFile ( )
142+ ( l ) => this . $fs . getFsStats ( l . getLocalPath ( ) ) . isFile ( ) ,
120143 ) ;
121144 const files : IOSDeviceLib . IFileData [ ] = filesToUpload . map ( ( l ) => ( {
122145 source : l . getLocalPath ( ) ,
@@ -137,29 +160,43 @@ export class IOSDeviceFileSystem implements Mobile.IDeviceFileSystem {
137160 public async transferDirectory (
138161 deviceAppData : Mobile . IDeviceAppData ,
139162 localToDevicePaths : Mobile . ILocalToDevicePathData [ ] ,
140- projectFilesPath : string
163+ projectFilesPath : string ,
141164 ) : Promise < Mobile . ILocalToDevicePathData [ ] > {
142165 await this . transferFiles ( deviceAppData , localToDevicePaths ) ;
143166 return localToDevicePaths ;
144167 }
145168
146169 public async updateHashesOnDevice (
147170 hashes : IStringDictionary ,
148- appIdentifier : string
171+ appIdentifier : string ,
149172 ) : Promise < void > {
150173 return ;
151174 }
152175
153176 private async uploadFilesCore (
154- filesToUpload : IOSDeviceLib . IUploadFilesData [ ]
177+ filesToUpload : IOSDeviceLib . IUploadFilesData [ ] ,
155178 ) : Promise < void > {
156179 await this . $iosDeviceOperations . uploadFiles (
157180 filesToUpload ,
158181 ( err : IOSDeviceLib . IDeviceError ) => {
159- if ( err . deviceId === this . device . deviceInfo . identifier ) {
182+ // Previously an error whose deviceId did not exactly match was
183+ // dropped on the floor — including errors with NO deviceId at
184+ // all (some ios-device-lib error paths don't attribute one).
185+ // That left "Successfully synced" printed over a failed
186+ // transfer and the app silently running stale JavaScript.
187+ // Rethrow unless the error is positively attributed to a
188+ // DIFFERENT device; surface even those at warn level so a
189+ // failed upload is never invisible.
190+ if (
191+ ! err . deviceId ||
192+ err . deviceId === this . device . deviceInfo . identifier
193+ ) {
160194 throw err ;
161195 }
162- }
196+ this . $logger . warn (
197+ `File upload error reported for another device (${ err . deviceId } ): ${ err . message } ` ,
198+ ) ;
199+ } ,
163200 ) ;
164201 }
165202}
0 commit comments