Created
January 4, 2020 01:09
-
-
Save worldlee78/d57a5f6a20edb7f4bd207375871f48f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable camelcase,@typescript-eslint/camelcase */ | |
/* Imports ==================================================================== */ | |
import RNFetchBlob, { FetchBlobResponse } from 'rn-fetch-blob'; | |
import base64 from 'base-64'; | |
import moment from 'moment'; | |
import shittyQs from 'shitty-qs'; | |
import utf8 from './utf8'; | |
import { CloudAuthSuccessResponse } from '../../data'; | |
import { Linking } from 'react-native'; | |
/* Interfaces ================================================================= */ | |
export interface DropBoxDownloadOptions { | |
path: string; | |
accessToken: string; | |
} | |
export interface DropBoxMoveOptions { | |
fromPath: string; | |
toPath: string; | |
accessToken: string; | |
} | |
export interface DropBoxResponse { | |
metadata: { | |
'.tag': string; | |
name: string; | |
id: string; | |
client_modified: string; | |
server_modified: string; | |
rev: string; | |
size: number; | |
path_lower: string; | |
path_display: string; | |
sharing_info: { | |
read_only: boolean; | |
parent_shared_folder_id: string; | |
modified_by: string; | |
}; | |
property_groups: Array<{ | |
template_id: string; | |
fields: Array<{ | |
name: string; | |
value: string; | |
}>; | |
}>; | |
has_explicit_shared_members: boolean; | |
content_hash: string; | |
}; | |
} | |
export interface DropBoxDeleteOptions { | |
path: string; | |
accessToken: string; | |
} | |
export interface DropBoxExistsOptions { | |
accessToken: string; | |
path: string; | |
} | |
export interface DropBoxUploadOptions { | |
path: string; | |
accessToken: string; | |
content: any; | |
} | |
export interface DropBoxUploadResponse { | |
name: string; | |
id: string; | |
client_modified: string; | |
server_modified: string; | |
rev: string; | |
size: number; | |
path_lower: string; | |
path_display: string; | |
sharing_info: { | |
read_only: boolean; | |
parent_shared_folder_id: string; | |
modified_by: string; | |
}; | |
property_groups: Array<{ | |
template_id: string; | |
fields: Array<{ | |
name: string; | |
value: string; | |
}>; | |
}>; | |
has_explicit_shared_members: boolean; | |
content_hash: string; | |
} | |
export interface DropBoxListOptions { | |
accessToken: string; | |
path?: string; | |
recursive?: boolean; | |
include_media_info?: boolean; | |
include_deleted?: boolean; | |
include_has_explicit_shared_members?: boolean; | |
include_mounted_folders?: boolean; | |
} | |
export interface DropBoxListFileEntry { | |
'.tag': 'file'; | |
name: string; | |
id: string; | |
client_modified: string; | |
server_modified: string; | |
rev: string; | |
size: number; | |
path_lower: string; | |
path_display: string; | |
sharing_info: { | |
read_only: boolean; | |
parent_shared_folder_id: string; | |
modified_by: string; | |
}; | |
property_groups: [ | |
{ | |
template_id: string; | |
fields: [ | |
{ | |
name: string; | |
value: string; | |
}, | |
]; | |
}, | |
]; | |
has_explicit_shared_members: boolean; | |
content_hash: string; | |
} | |
export interface DropBoxListFolderEntry { | |
'.tag': 'folder'; | |
name: string; | |
id: string; | |
path_lower: string; | |
path_display: string; | |
sharing_info: { | |
read_only: boolean; | |
parent_shared_folder_id: string; | |
traverse_only: boolean; | |
no_access: boolean; | |
}; | |
property_groups: [ | |
{ | |
template_id: string; | |
fields: [ | |
{ | |
name: string; | |
value: string; | |
}, | |
]; | |
}, | |
]; | |
} | |
export type DropBoxListEntry = DropBoxListFileEntry | DropBoxListFolderEntry; | |
export interface DropBoxListResponse { | |
entries: DropBoxListFileEntry[]; | |
cursor: string; | |
has_more: boolean; | |
} | |
export interface DropBoxAuthComplete { | |
scheme: string; | |
route: string; | |
query: Record<string, any>; | |
params: Record<string, any>; | |
} | |
/* Dropbox API ================================================================ */ | |
class DropBox { | |
clientKey: string; | |
state: string | null; | |
constructor(clientKey: string) { | |
this.clientKey = clientKey; | |
this.state = null; | |
} | |
completeAuth(url: string): Promise<CloudAuthSuccessResponse> { | |
return new Promise((resolve, reject) => { | |
// @ts-ignore | |
const [, queryString] = url.match(/#(.*)/); | |
const query = shittyQs(queryString); | |
if (moment().format('YYYYMMDD') === query.state) { | |
if (query.access_token) { | |
resolve({ | |
accessToken: query.access_token, | |
accountId: query.account_id, | |
}); | |
} else { | |
// Should be 'access_denied' | |
reject(new Error(`${query.error}, ${query.error_description}`)); | |
} | |
} else { | |
reject(new Error(`security_error, The response from DropBox was invalid and there might have been altered.`)); | |
} | |
}); | |
} | |
auth(): Promise<void> { | |
const state = moment().format('YYYYMMDD'); | |
return Linking.openURL( | |
[ | |
'https://www.dropbox.com/1/oauth2/authorize', | |
'?response_type=token', | |
`&client_id=${this.clientKey}`, | |
'&redirect_uri=bbbook://oauth2', | |
`&state=${state}`, | |
].join(''), | |
); | |
} | |
downloadRequest(options: DropBoxDownloadOptions): Promise<any> { | |
const path = options.path; | |
const accessToken = options.accessToken; | |
return RNFetchBlob.fetch('GET', 'https://content.dropboxapi.com/2/files/download', { | |
Authorization: `Bearer ${accessToken}`, | |
'Dropbox-API-Arg': JSON.stringify({ | |
path: path, | |
}), | |
}).then((response: FetchBlobResponse) => { | |
if (response.respInfo && response.respInfo.status === 401) { | |
return null; | |
} else if (response.respInfo && response.respInfo.status !== 200) { | |
throw new Error(response.data); | |
} | |
return response.json(); | |
}); | |
} | |
moveRequest(options: DropBoxMoveOptions): Promise<any> { | |
const { fromPath, toPath, accessToken } = options; | |
return RNFetchBlob.fetch( | |
'POST', | |
'https://api.dropboxapi.com/2/files/move_v2', | |
{ | |
Authorization: `Bearer ${accessToken}`, | |
'Content-Type': 'application/json', | |
}, | |
JSON.stringify({ | |
from_path: fromPath, // eslint-disable-line | |
to_path: toPath, // eslint-disable-line | |
}), | |
).then((response: FetchBlobResponse) => { | |
if (response.respInfo && response.respInfo.status === 401) { | |
return null; | |
} else if (response.respInfo && response.respInfo.status !== 200) { | |
throw new Error(response.data); | |
} | |
return response.json(); | |
}); | |
} | |
deleteRequest(options: DropBoxDeleteOptions): Promise<boolean | null> { | |
const { path, accessToken } = options; | |
return RNFetchBlob.fetch( | |
'POST', | |
'https://api.dropboxapi.com/2/files/delete_v2', | |
{ | |
Authorization: `Bearer ${accessToken}`, | |
'Content-Type': 'application/json', | |
}, | |
JSON.stringify({ | |
path: path, | |
}), | |
).then((response: FetchBlobResponse) => { | |
if (response.respInfo && response.respInfo.status === 401) { | |
return null; | |
} else if (response.respInfo && response.respInfo.status !== 200) { | |
throw new Error(response.data); | |
} | |
return true; | |
}); | |
} | |
exists(options: DropBoxExistsOptions): Promise<boolean | null> { | |
const { accessToken, path } = options; | |
return RNFetchBlob.fetch( | |
'POST', | |
'https://api.dropboxapi.com/2/files/get_metadata', | |
{ | |
Authorization: `Bearer ${accessToken}`, | |
'Content-Type': 'application/json', | |
}, | |
JSON.stringify({ | |
path: path, | |
include_media_info: false, // eslint-disable-line | |
include_deleted: false, // eslint-disable-line | |
include_has_explicit_shared_members: false, // eslint-disable-line | |
}), | |
).then((response: FetchBlobResponse) => { | |
if (response.respInfo && response.respInfo.status === 401) { | |
return null; | |
} else if (response.respInfo && response.respInfo.status === 409) { | |
return false; | |
} else if (response.respInfo && response.respInfo.status !== 200) { | |
throw new Error(response.data); | |
} | |
return true; | |
}); | |
} | |
listFolder(options: DropBoxListOptions): Promise<any> { | |
const accessToken = options.accessToken; | |
const path = options.path || ''; | |
const recursive = options.recursive || false; | |
const include_media_info = options.include_media_info || false; | |
const include_deleted = options.include_deleted || false; | |
const include_has_explicit_shared_members = options.include_has_explicit_shared_members || false; | |
const include_mounted_folders = options.include_mounted_folders || true; | |
return RNFetchBlob.fetch( | |
'POST', | |
'https://api.dropboxapi.com/2/files/list_folder', | |
{ | |
Authorization: `Bearer ${accessToken}`, | |
'Content-Type': 'application/json', | |
}, | |
JSON.stringify({ | |
path, | |
recursive, | |
include_media_info, | |
include_deleted, | |
include_has_explicit_shared_members, | |
include_mounted_folders, | |
}), | |
).then((response: any) => JSON.parse(response.data)); | |
} | |
uploadRequest(options: DropBoxUploadOptions): Promise<FetchBlobResponse> { | |
const path = options.path; | |
const accessToken = options.accessToken; | |
const bytes = utf8.encode(options.content); | |
const content = base64.encode(bytes); | |
return RNFetchBlob.fetch( | |
'POST', | |
'https://content.dropboxapi.com/2/files/upload', | |
{ | |
Authorization: `Bearer ${accessToken}`, | |
'Dropbox-API-Arg': JSON.stringify({ | |
path: path, | |
mode: 'overwrite', | |
mute: true, | |
}), | |
'Content-Type': 'application/octet-stream', | |
}, | |
content, | |
); | |
} | |
} | |
export default DropBox; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment