dropbox-with-offline-refresh-token
Advanced tools
Comparing version 1.0.15 to 1.0.16
{ | ||
"name": "dropbox-with-offline-refresh-token", | ||
"version": "1.0.15", | ||
"version": "1.0.16", | ||
"type": "module", | ||
"description": "use can easily use the dropbox api without have to handle all the authentication stuff. all you need is a single offline refresh token.", | ||
@@ -5,0 +6,0 @@ "main": "target/lib/Client.js", |
@@ -0,5 +1,8 @@ | ||
import { Dropbox, DropboxResponseError } from "dropbox"; | ||
import { TokenResponse } from "./model/TokenResponse.js"; | ||
import axios from "axios"; | ||
import { Dropbox, DropboxResponseError } from "dropbox"; | ||
import { TokenResponse } from "./model/TokenResponse"; | ||
import Queue from "queue"; | ||
// const Queue = await (async () => await import('queue').then(res => res.default))() | ||
class Client { | ||
@@ -12,2 +15,3 @@ private refreshToken: string | ||
private client: Dropbox | undefined | ||
private jobQueue: Queue | ||
@@ -19,2 +23,7 @@ constructor(refreshToken: string, appKey: string, appSecret: string, withProfileMail: string) { | ||
this.withProfileMail = withProfileMail | ||
this.jobQueue = new Queue({ | ||
autostart: true, | ||
concurrency: 1 | ||
}) | ||
} | ||
@@ -45,2 +54,3 @@ | ||
const user = x.result.members.find(member => member.profile.email === this.withProfileMail) | ||
if (user === undefined) throw new Error(`did not find user with email ${this.withProfileMail}`) | ||
@@ -66,6 +76,15 @@ const selectUser = user.profile.team_member_id | ||
async execAsync<R>(lambda: (x: Dropbox) => Promise<R>): Promise<R> { | ||
if (this.client === undefined) await this.refreshAccessToken() | ||
return lambda(this.client) | ||
.catch(async (e): Promise<R> => this.handleDropboxError(e, () => lambda(this.client))) | ||
return new Promise<R>((res, rej) => { | ||
this.jobQueue.push(async () => { | ||
if (this.client === undefined) await this.refreshAccessToken() | ||
if (this.client === undefined) throw new Error('dropbox client was not set') | ||
return lambda(this.client as Dropbox) | ||
.catch(async (e): Promise<R> => this.handleDropboxError(e, () => lambda(this.client as Dropbox))) | ||
.then(res) | ||
.catch(rej) | ||
}) | ||
}) | ||
} | ||
@@ -77,6 +96,5 @@ | ||
if (!(e instanceof DropboxResponseError)) throw e | ||
console.debug(e.error?.error['.tag'] ?? e.error?.error?.reason?.['.tag'], e?.error?.error?.retry_after) | ||
do { | ||
const errorMsg = e.error?.error['.tag'] ?? e.error?.error?.reason['.tag'] | ||
const errorMsg = e.error?.error?.['.tag'] ?? e.error?.error?.reason?.['.tag'] | ||
if (typeof errorMsg !== 'string') { | ||
@@ -86,19 +104,23 @@ throw new Error(`could not parse the error: ${e.error}`) | ||
switch (errorMsg) { | ||
case 'expired_access_token': | ||
res = await this.refreshAccessToken.call(this) | ||
.then(onSolved) | ||
.catch((error: any) => void (e = error)) | ||
case 'too_many_write_operations': | ||
case 'too_many_requests': | ||
const retryAfter = e.error.error.retry_after ?? 1 | ||
res = await new Promise<R>((res) => setTimeout(() => res(onSolved.call(this)), retryAfter * 50)) | ||
.catch(error => void (e = error)) | ||
default: | ||
break | ||
if (errorMsg === 'expired_access_token') { | ||
res = await this.refreshAccessToken.call(this) | ||
.then(onSolved) | ||
.catch((error: any) => void (e = error)) | ||
} | ||
} while (++tries < 4 || res === null) | ||
else if (errorMsg === 'too_many_write_operations' || errorMsg === 'too_many_requests') { | ||
const retryAfter = e.error.error.retry_after ?? 1 | ||
res = await new Promise<R>((res) => setTimeout( | ||
() => res(onSolved.call(this)), | ||
retryAfter * 50 * tries | ||
)) | ||
.catch(error => void (e = error)) | ||
} | ||
else { | ||
break | ||
} | ||
} while (++tries < 20 || res === null) | ||
if (res === null) throw e | ||
return res | ||
return res as R | ||
} | ||
@@ -105,0 +127,0 @@ } |
@@ -8,2 +8,3 @@ import { Dropbox } from "dropbox"; | ||
private client; | ||
private jobQueue; | ||
constructor(refreshToken: string, appKey: string, appSecret: string, withProfileMail: string); | ||
@@ -10,0 +11,0 @@ private refreshAccessToken; |
@@ -1,5 +0,5 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const axios_1 = require("axios"); | ||
const dropbox_1 = require("dropbox"); | ||
import { Dropbox, DropboxResponseError } from "dropbox"; | ||
import axios from "axios"; | ||
import Queue from "queue"; | ||
// const Queue = await (async () => await import('queue').then(res => res.default))() | ||
class Client { | ||
@@ -11,5 +11,9 @@ constructor(refreshToken, appKey, appSecret, withProfileMail) { | ||
this.withProfileMail = withProfileMail; | ||
this.jobQueue = new Queue({ | ||
autostart: true, | ||
concurrency: 1 | ||
}); | ||
} | ||
async refreshAccessToken() { | ||
return axios_1.default.post(`https://api.dropbox.com/oauth2/token`, new URLSearchParams({ | ||
return axios.post(`https://api.dropbox.com/oauth2/token`, new URLSearchParams({ | ||
grant_type: 'refresh_token', | ||
@@ -21,3 +25,3 @@ refresh_token: this.refreshToken, | ||
.then(async ({ data: { access_token } }) => { | ||
const dbClient = new dropbox_1.Dropbox({ | ||
const dbClient = new Dropbox({ | ||
accessToken: access_token, | ||
@@ -31,2 +35,4 @@ }); | ||
const user = x.result.members.find(member => member.profile.email === this.withProfileMail); | ||
if (user === undefined) | ||
throw new Error(`did not find user with email ${this.withProfileMail}`); | ||
const selectUser = user.profile.team_member_id; | ||
@@ -38,3 +44,3 @@ const pathRoot = JSON.stringify({ | ||
}); | ||
const client = new dropbox_1.Dropbox({ | ||
const client = new Dropbox({ | ||
accessToken: access_token, | ||
@@ -49,33 +55,39 @@ selectUser, | ||
async execAsync(lambda) { | ||
if (this.client === undefined) | ||
await this.refreshAccessToken(); | ||
return lambda(this.client) | ||
.catch(async (e) => this.handleDropboxError(e, () => lambda(this.client))); | ||
return new Promise((res, rej) => { | ||
this.jobQueue.push(async () => { | ||
if (this.client === undefined) | ||
await this.refreshAccessToken(); | ||
if (this.client === undefined) | ||
throw new Error('dropbox client was not set'); | ||
return lambda(this.client) | ||
.catch(async (e) => this.handleDropboxError(e, () => lambda(this.client))) | ||
.then(res) | ||
.catch(rej); | ||
}); | ||
}); | ||
} | ||
async handleDropboxError(e, onSolved) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; | ||
let tries = 1; | ||
let res = null; | ||
if (!(e instanceof dropbox_1.DropboxResponseError)) | ||
if (!(e instanceof DropboxResponseError)) | ||
throw e; | ||
console.debug((_b = (_a = e.error) === null || _a === void 0 ? void 0 : _a.error['.tag']) !== null && _b !== void 0 ? _b : (_e = (_d = (_c = e.error) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.reason) === null || _e === void 0 ? void 0 : _e['.tag'], (_g = (_f = e === null || e === void 0 ? void 0 : e.error) === null || _f === void 0 ? void 0 : _f.error) === null || _g === void 0 ? void 0 : _g.retry_after); | ||
do { | ||
const errorMsg = (_j = (_h = e.error) === null || _h === void 0 ? void 0 : _h.error['.tag']) !== null && _j !== void 0 ? _j : (_l = (_k = e.error) === null || _k === void 0 ? void 0 : _k.error) === null || _l === void 0 ? void 0 : _l.reason['.tag']; | ||
const errorMsg = e.error?.error?.['.tag'] ?? e.error?.error?.reason?.['.tag']; | ||
if (typeof errorMsg !== 'string') { | ||
throw new Error(`could not parse the error: ${e.error}`); | ||
} | ||
switch (errorMsg) { | ||
case 'expired_access_token': | ||
res = await this.refreshAccessToken.call(this) | ||
.then(onSolved) | ||
.catch((error) => void (e = error)); | ||
case 'too_many_write_operations': | ||
case 'too_many_requests': | ||
const retryAfter = (_m = e.error.error.retry_after) !== null && _m !== void 0 ? _m : 1; | ||
res = await new Promise((res) => setTimeout(() => res(onSolved.call(this)), retryAfter * 50)) | ||
.catch(error => void (e = error)); | ||
default: | ||
break; | ||
if (errorMsg === 'expired_access_token') { | ||
res = await this.refreshAccessToken.call(this) | ||
.then(onSolved) | ||
.catch((error) => void (e = error)); | ||
} | ||
} while (++tries < 4 || res === null); | ||
else if (errorMsg === 'too_many_write_operations' || errorMsg === 'too_many_requests') { | ||
const retryAfter = e.error.error.retry_after ?? 1; | ||
res = await new Promise((res) => setTimeout(() => res(onSolved.call(this)), retryAfter * 50 * tries)) | ||
.catch(error => void (e = error)); | ||
} | ||
else { | ||
break; | ||
} | ||
} while (++tries < 20 || res === null); | ||
if (res === null) | ||
@@ -86,2 +98,2 @@ throw e; | ||
} | ||
exports.default = Client; | ||
export default Client; |
@@ -1,2 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
export {}; |
{ | ||
"compilerOptions": { | ||
"target": "es2017", | ||
"module": "commonjs", | ||
"outDir": "target", | ||
"module": "ESNext", // Or "ES2020", enables native ESM | ||
"target": "ES2020", // Or "ESNext", ensures ES module features are supported | ||
"moduleResolution": "node",// Use Node-style module resolution | ||
"esModuleInterop": true, // Enable compatibility with CommonJS and ES modules | ||
"allowSyntheticDefaultImports": true, // Allows using default imports for CommonJS modules | ||
"forceConsistentCasingInFileNames": true, | ||
"skipLibCheck": true, | ||
"strict": true, | ||
"outDir": "target", | ||
"rootDir": "src", | ||
"declaration": true | ||
} | ||
} | ||
} | ||
10453
239
Yes