Skip to content

Instantly share code, notes, and snippets.

@worldlee78
Created January 4, 2020 01:09
Show Gist options
  • Save worldlee78/d57a5f6a20edb7f4bd207375871f48f2 to your computer and use it in GitHub Desktop.
Save worldlee78/d57a5f6a20edb7f4bd207375871f48f2 to your computer and use it in GitHub Desktop.
/* 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