@@ -16,6 +16,37 @@ type DropboxTokenResponse = {
1616 ...
1717} ;
1818
19+ type DropboxFileEntry = {
20+ + '.tag' : 'file' ,
21+ + 'name' : string ,
22+ + 'path_display' ?: ?string ,
23+ + 'server_modified' : string ,
24+ + 'size' : number ,
25+ ...
26+ } ;
27+
28+ type DropboxNonFileEntry = {
29+ + '.tag' : 'folder' | 'deleted' ,
30+ ...
31+ } ;
32+
33+ type DropboxListFolderResponse = {
34+ + entries : $ReadOnlyArray < DropboxFileEntry | DropboxNonFileEntry > ,
35+ + has_more : boolean ,
36+ + cursor : string ,
37+ ...
38+ } ;
39+
40+ type DropboxUploadSessionStartResponse = {
41+ + session_id : string ,
42+ ...
43+ } ;
44+
45+ type DropboxContentResponse < T > = {
46+ + accessToken : string ,
47+ + response : T ,
48+ } ;
49+
1950class DropboxRequestError extends Error {
2051 + status : number ;
2152 + responseText : string ;
@@ -42,9 +73,12 @@ class DropboxBackupStorageAdapter {
4273
4374 async listFiles ( ) : Promise < $ReadOnlyArray < StoredFileInfo >> {
4475 const fileEntries : StoredFileInfo [ ] = [ ] ;
45- let response = await this . rpcRequest ( 'files/list_folder' , {
46- path : this . directory ,
47- } ) ;
76+ let response = await this . rpcRequest < DropboxListFolderResponse > (
77+ 'files/list_folder' ,
78+ {
79+ path : this . directory ,
80+ } ,
81+ ) ;
4882 while ( true ) {
4983 for ( const entry of response . entries ) {
5084 if ( entry [ '.tag' ] !== 'file' ) {
@@ -59,16 +93,19 @@ class DropboxBackupStorageAdapter {
5993 if ( ! response . has_more ) {
6094 break ;
6195 }
62- response = await this . rpcRequest ( 'files/list_folder/continue' , {
63- cursor : response . cursor ,
64- } ) ;
96+ response = await this . rpcRequest < DropboxListFolderResponse > (
97+ 'files/list_folder/continue' ,
98+ {
99+ cursor : response . cursor ,
100+ } ,
101+ ) ;
65102 }
66103 return fileEntries ;
67104 }
68105
69106 async deleteFile ( filename : string ) : Promise < void > {
70107 try {
71- await this . rpcRequest ( 'files/delete_v2' , {
108+ await this . rpcRequest < mixed > ( 'files/delete_v2' , {
72109 path : this . filePath ( filename ) ,
73110 } ) ;
74111 } catch ( error ) {
@@ -99,7 +136,7 @@ class DropboxBackupStorageAdapter {
99136 } > {
100137 if ( ! sessionID ) {
101138 const { accessToken : currentAccessToken , response } =
102- await this . contentRequest (
139+ await this . contentRequest < DropboxUploadSessionStartResponse > (
103140 accessToken ,
104141 'files/upload_session/start' ,
105142 { close : false } ,
@@ -110,7 +147,7 @@ class DropboxBackupStorageAdapter {
110147 sessionID : response . session_id ,
111148 } ;
112149 }
113- const { accessToken : currentAccessToken } = await this . contentRequest (
150+ const { accessToken : currentAccessToken } = await this . contentRequest < null > (
114151 accessToken ,
115152 'files/upload_session/append_v2' ,
116153 {
@@ -136,20 +173,21 @@ class DropboxBackupStorageAdapter {
136173 chunk : Buffer ,
137174 ) : Promise < string > {
138175 if ( ! sessionID ) {
139- const { accessToken : currentAccessToken } = await this . contentRequest (
140- accessToken ,
141- 'files/upload' ,
142- {
143- path : this . filePath ( filename ) ,
144- mode : { '.tag' : 'overwrite' } ,
145- autorename : false ,
146- mute : true ,
147- } ,
148- chunk ,
149- ) ;
176+ const { accessToken : currentAccessToken } =
177+ await this . contentRequest < null > (
178+ accessToken ,
179+ 'files/upload' ,
180+ {
181+ path : this . filePath ( filename ) ,
182+ mode : { '.tag' : 'overwrite' } ,
183+ autorename : false ,
184+ mute : true ,
185+ } ,
186+ chunk ,
187+ ) ;
150188 return currentAccessToken ;
151189 }
152- const { accessToken : currentAccessToken } = await this . contentRequest (
190+ const { accessToken : currentAccessToken } = await this . contentRequest < null > (
153191 accessToken ,
154192 'files/upload_session/finish' ,
155193 {
@@ -198,7 +236,7 @@ class DropboxBackupStorageAdapter {
198236 return tokenResponse . access_token ;
199237 }
200238
201- async rpcRequest ( endpoint : string , payload : Object ) : Promise < any > {
239+ async rpcRequest < T > ( endpoint : string , payload : Object ) : Promise < T > {
202240 const accessToken = await this . refreshAccessToken ( ) ;
203241 const response = await nodeFetch (
204242 `https://api.dropboxapi.com/2/${ endpoint } ` ,
@@ -218,20 +256,17 @@ class DropboxBackupStorageAdapter {
218256 return await response . json ( ) ;
219257 }
220258
221- async contentRequest (
259+ async contentRequest < T > (
222260 accessToken : string ,
223261 endpoint : string ,
224262 args : Object ,
225263 content : Buffer ,
226- ) : Promise < {
227- + accessToken : string ,
228- + response : any ,
229- } > {
264+ ) : Promise < DropboxContentResponse < T >> {
230265 const tryContentRequest = async (
231266 currentAccessToken : string ,
232267 ) : Promise < {
233268 + accessToken : string ,
234- + response : any ,
269+ + responseText : string ,
235270 } > => {
236271 const response = await nodeFetch (
237272 `https://content.dropboxapi.com/2/${ endpoint } ` ,
@@ -260,10 +295,15 @@ class DropboxBackupStorageAdapter {
260295 const responseText = await response . text ( ) ;
261296 return {
262297 accessToken : currentAccessToken ,
263- response : responseText ? JSON . parse ( responseText ) : { } ,
298+ responseText ,
264299 } ;
265300 } ;
266- return await tryContentRequest ( accessToken ) ;
301+ const { accessToken : currentAccessToken , responseText } =
302+ await tryContentRequest ( accessToken ) ;
303+ return {
304+ accessToken : currentAccessToken ,
305+ response : JSON . parse ( responseText ?? 'null' ) ,
306+ } ;
267307 }
268308}
269309
0 commit comments