@@ -54,7 +54,31 @@ class RestSASServerAdapter implements ContentAdapter {
5454 await session . setup ( true ) ;
5555
5656 this . sessionId = session ?. sessionId ( ) ;
57- this . fileSystemApi = FileSystemApi ( getApiConfig ( ) ) ;
57+ // This proxies all calls to the fileSystem api to reconnect
58+ // if we ever get a 401 (unauthorized)
59+ this . fileSystemApi = new Proxy ( FileSystemApi ( getApiConfig ( ) ) , {
60+ get : function ( target , property ) {
61+ if ( typeof target [ property ] === "function" ) {
62+ return new Proxy ( target [ property ] , {
63+ apply : async function ( target , _this , argList ) {
64+ try {
65+ return await target ( ...argList ) ;
66+ } catch ( error ) {
67+ if ( error . response ?. status !== 401 ) {
68+ throw error ;
69+ }
70+
71+ await this . connect ( ) ;
72+
73+ return await target ( ...argList ) ;
74+ }
75+ } ,
76+ } ) ;
77+ }
78+
79+ return target [ property ] ;
80+ } ,
81+ } ) ;
5882 }
5983
6084 public connected ( ) : boolean {
@@ -155,18 +179,42 @@ class RestSASServerAdapter implements ContentAdapter {
155179 ] ;
156180 }
157181
158- const { data } = await this . fileSystemApi . getDirectoryMembers ( {
159- sessionId : this . sessionId ,
160- directoryPath : this . trimComputePrefix (
161- getLink ( parentItem . links , "GET" , "getDirectoryMembers" ) . uri ,
162- ) . replace ( "/members" , "" ) ,
163- } ) ;
182+ const allItems = [ ] ;
183+ const limit = 100 ;
184+ let start = 0 ;
185+ let totalItemCount = 0 ;
186+ do {
187+ const response = await this . fileSystemApi . getDirectoryMembers ( {
188+ sessionId : this . sessionId ,
189+ directoryPath : this . trimComputePrefix (
190+ getLink ( parentItem . links , "GET" , "getDirectoryMembers" ) . uri ,
191+ ) . replace ( "/members" , "" ) ,
192+ limit,
193+ start,
194+ } ) ;
195+ totalItemCount = response . data . count ;
164196
165- // TODO (sas-server) We need to paginate and sort results
166- return data . items . map ( ( childItem : FileProperties , index ) => ( {
167- ...this . filePropertiesToContentItem ( childItem ) ,
168- uid : `${ parentItem . uid } /${ index } ` ,
169- } ) ) ;
197+ allItems . push (
198+ ...response . data . items . map ( ( childItem : FileProperties , index ) => ( {
199+ ...this . filePropertiesToContentItem ( childItem ) ,
200+ uid : `${ parentItem . uid } /${ index + start } ` ,
201+ } ) ) ,
202+ ) ;
203+
204+ start += limit ;
205+ } while ( start < totalItemCount ) ;
206+
207+ return allItems . sort ( ( a , b ) => {
208+ const aIsDirectory = a . fileStat ?. type === FileType . Directory ;
209+ const bIsDirectory = b . fileStat ?. type === FileType . Directory ;
210+ if ( aIsDirectory && ! bIsDirectory ) {
211+ return - 1 ;
212+ } else if ( ! aIsDirectory && bIsDirectory ) {
213+ return 1 ;
214+ } else {
215+ return a . name . localeCompare ( b . name ) ;
216+ }
217+ } ) ;
170218 }
171219
172220 public async getContentOfItem ( item : ContentItem ) : Promise < string > {
@@ -204,14 +252,15 @@ class RestSASServerAdapter implements ContentAdapter {
204252 }
205253
206254 public async getItemOfUri ( uri : Uri ) : Promise < ContentItem > {
207- const resourceId = getResourceId ( uri ) ;
208-
209- const { data } = await this . fileSystemApi . getFileorDirectoryProperties ( {
255+ const fileOrDirectoryPath = this . trimComputePrefix ( getResourceId ( uri ) ) ;
256+ const response = await this . fileSystemApi . getFileorDirectoryProperties ( {
210257 sessionId : this . sessionId ,
211- fileOrDirectoryPath : this . trimComputePrefix ( resourceId ) ,
258+ fileOrDirectoryPath,
212259 } ) ;
213260
214- return this . filePropertiesToContentItem ( data ) ;
261+ this . updateFileMetadata ( fileOrDirectoryPath , response ) ;
262+
263+ return this . filePropertiesToContentItem ( response . data ) ;
215264 }
216265
217266 public async getParentOfItem (
@@ -262,7 +311,25 @@ class RestSASServerAdapter implements ContentAdapter {
262311 item : ContentItem ,
263312 targetParentFolderUri : string ,
264313 ) : Promise < boolean > {
265- throw new Error ( "Method not implemented." ) ;
314+ const currentFilePath = this . trimComputePrefix ( item . uri ) ;
315+ const newFilePath = this . trimComputePrefix ( targetParentFolderUri ) ;
316+ const { etag } = await this . getFileInfo ( currentFilePath ) ;
317+ const params = {
318+ sessionId : this . sessionId ,
319+ fileOrDirectoryPath : currentFilePath ,
320+ ifMatch : etag ,
321+ fileProperties : {
322+ name : item . name ,
323+ path : newFilePath . split ( "~fs~" ) . join ( "/" ) ,
324+ } ,
325+ } ;
326+
327+ const response =
328+ await this . fileSystemApi . updateFileOrDirectoryOnSystem ( params ) ;
329+ delete this . fileMetadataMap [ currentFilePath ] ;
330+ this . updateFileMetadata ( newFilePath , response ) ;
331+
332+ return ! ! this . filePropertiesToContentItem ( response . data ) ;
266333 }
267334
268335 public async recycleItem (
@@ -285,7 +352,6 @@ class RestSASServerAdapter implements ContentAdapter {
285352 ) : Promise < ContentItem | undefined > {
286353 const filePath = this . trimComputePrefix ( item . uri ) ;
287354
288- const isDirectory = item . fileStat ?. type === FileType . Directory ;
289355 const parsedFilePath = filePath . split ( "~fs~" ) ;
290356 parsedFilePath . pop ( ) ;
291357 const path = parsedFilePath . join ( "/" ) ;
@@ -294,7 +360,7 @@ class RestSASServerAdapter implements ContentAdapter {
294360 sessionId : this . sessionId ,
295361 fileOrDirectoryPath : filePath ,
296362 ifMatch : "" ,
297- fileProperties : { name : newName , path, isDirectory } ,
363+ fileProperties : { name : newName , path } ,
298364 } ) ;
299365
300366 this . updateFileMetadata ( filePath , response ) ;
@@ -308,7 +374,7 @@ class RestSASServerAdapter implements ContentAdapter {
308374
309375 public async updateContentOfItem ( uri : Uri , content : string ) : Promise < void > {
310376 const filePath = this . trimComputePrefix ( getResourceId ( uri ) ) ;
311- const { etag } = this . getFileInfo ( filePath ) ;
377+ const { etag } = await this . getFileInfo ( filePath ) ;
312378
313379 const response = await this . fileSystemApi . updateFileContentOnSystem ( {
314380 sessionId : this . sessionId ,
@@ -388,12 +454,26 @@ class RestSASServerAdapter implements ContentAdapter {
388454 this . fileMetadataMap [ id ] = {
389455 etag : headers . etag ,
390456 } ;
457+
458+ return this . fileMetadataMap [ id ] ;
391459 }
392460
393- private getFileInfo ( resourceId : string ) {
394- if ( resourceId in this . fileMetadataMap ) {
395- return this . fileMetadataMap [ resourceId ] ;
461+ private async getFileInfo ( path : string ) {
462+ if ( path in this . fileMetadataMap ) {
463+ return this . fileMetadataMap [ path ] ;
396464 }
465+
466+ // If we don't have file metadata stored, lets attempt to fetch it
467+ try {
468+ const response = await this . fileSystemApi . getFileorDirectoryProperties ( {
469+ sessionId : this . sessionId ,
470+ fileOrDirectoryPath : path ,
471+ } ) ;
472+ return this . updateFileMetadata ( path , response ) ;
473+ } catch ( e ) {
474+ // Intentionally blank
475+ }
476+
397477 return {
398478 etag : "" ,
399479 } ;
0 commit comments