From 825832150ccac9a2642a4d101278cfb6372876c5 Mon Sep 17 00:00:00 2001 From: Ken Eucker Date: Wed, 5 Jan 2022 09:38:10 -0800 Subject: [PATCH] feat(src): adds rapid api support using new fields: rapidApiKey and rapidApiHost --- example/index.js | 1 + src/client.ts | 23 +++++++++++++++++++---- src/common/types.ts | 19 ++++++++++++++++--- src/common/utils.ts | 12 +++++++++--- src/getAuthorizationHeader.ts | 18 +++++++++--------- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/example/index.js b/example/index.js index 2ac08245..d9b369c5 100644 --- a/example/index.js +++ b/example/index.js @@ -17,6 +17,7 @@ const imgur = new ImgurClient({ const run = async (client) => { await getAuthorizationHeader(client).then(console.log) + console.log(client.credentials) const imageStream = createReadStream(join(__dirname, 'small.jpg')); const videoStream = createReadStream(join(__dirname, 'small.mp4')); diff --git a/src/client.ts b/src/client.ts index 2e56db1a..d6612b6e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -17,9 +17,10 @@ import { SearchGalleryOptions, } from './gallery'; import { getAlbum } from './album'; -import { getAlbums, getAlbumsIds } from './account'; +import { getAccount, getAlbums, getAlbumsIds } from './account'; import { IMGUR_API_PREFIX } from './common/endpoints'; import { + AccountData, AlbumData, Credentials, GalleryData, @@ -31,14 +32,17 @@ import { const USERAGENT = 'imgur (https://github.com/keneucker/imgur)'; import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios'; - export type { Credentials as ImgurCredentials, ImgurApiResponse }; export class ImgurClient extends EventEmitter { private plainFetcher: AxiosInstance; private fetcher: AxiosInstance; - constructor(readonly credentials: Credentials) { + constructor(public credentials: Credentials) { super(); + + this.credentials.rapidApiHost = credentials.rapidApiKey?.length + ? credentials.rapidApiHost ?? 'imgur-apiv3.p.rapidapi.com' + : credentials.rapidApiHost; const headers = typeof window !== 'undefined' ? {} @@ -52,7 +56,9 @@ export class ImgurClient extends EventEmitter { responseType: 'json', }); this.fetcher = axios.create({ - baseURL: IMGUR_API_PREFIX, + baseURL: credentials.rapidApiKey?.length + ? `https://${this.credentials.rapidApiHost}` + : IMGUR_API_PREFIX, headers, responseType: 'json', }); @@ -60,6 +66,11 @@ export class ImgurClient extends EventEmitter { async (config: AxiosRequestConfig) => { config.headers = config.headers ? config.headers : {}; config.headers.authorization = await getAuthorizationHeader(this); + + if (credentials.rapidApiKey?.length) { + config.headers['x-rapidapi-host'] = credentials.rapidApiHost; + config.headers['x-rapidapi-key'] = credentials.rapidApiKey; + } return config; }, (e: Error) => Promise.reject(e) @@ -86,6 +97,10 @@ export class ImgurClient extends EventEmitter { return getAlbum(this, albumHash); } + getAccount(account: string): Promise> { + return getAccount(this, account); + } + getAlbums( account: string, page?: number diff --git a/src/common/types.ts b/src/common/types.ts index 64dce9e5..3a088297 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,14 +1,27 @@ export interface AccessToken { - accessToken: string; + accessToken?: string; refreshToken?: string; } +export interface RapidApiKey { + rapidApiHost?: string; + rapidApiKey?: string; +} + export interface ClientId { - clientId: string; + clientId?: string; clientSecret?: string; } -export type Credentials = AccessToken | ClientId; +export interface Credentials extends AccessToken, ClientId, RapidApiKey {} + +export interface ImgurTokenResponse { + account_username?: string; + access_token: string; + refresh_token: string; + token_type?: string; + expires_in?: number; +} export function isAccessToken(arg: unknown): arg is AccessToken { return (arg as AccessToken).accessToken !== undefined; diff --git a/src/common/utils.ts b/src/common/utils.ts index b700477e..a8aa96ee 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -53,7 +53,11 @@ export function getImgurApiResponseFromResponse( const getResponseData = (d) => Array.isArray(d) ? d.map((t) => (responseIsError ? t.detail : t.data)) : d; - if (typeof response === 'string') { + if (typeof response === 'undefined') { + data = 'response was empty'; + status = 500; + success = false; + } else if (typeof response === 'string') { data = response as string; status = 500; success = false; @@ -70,8 +74,10 @@ export function getImgurApiResponseFromResponse( response.data.status; data = getResponseData( responseIsError - ? response.data.errors ?? response.data.data.error.message - : response.data.data ?? response.data + ? response.data.errors ?? + response.data.data.error.message ?? + response.data.data.error + : response.data.data ?? response.data.message ?? response.data ); } diff --git a/src/getAuthorizationHeader.ts b/src/getAuthorizationHeader.ts index 7fb38730..95ed627b 100644 --- a/src/getAuthorizationHeader.ts +++ b/src/getAuthorizationHeader.ts @@ -1,8 +1,9 @@ import { - AccessToken, isAccessToken, isRefreshToken, isClientId, + ImgurTokenResponse, + Credentials, } from './common/types'; import { ImgurClient } from './client'; import { IMGUR_API_PREFIX, TOKEN_ENDPOINT } from './common/endpoints'; @@ -14,8 +15,9 @@ export async function getAuthorizationHeader( return `Bearer ${client.credentials.accessToken}`; } + const { clientId, clientSecret, refreshToken } = client.credentials; + if (isRefreshToken(client.credentials)) { - const { clientId, clientSecret, refreshToken } = client.credentials; const options: Record = { url: TOKEN_ENDPOINT, baseURL: IMGUR_API_PREFIX, @@ -28,22 +30,20 @@ export async function getAuthorizationHeader( }, }; const response = await client.plainRequest(options); - const authorization: any = response.data; - if (response.status === 200 && authorization) { + if (response.status === 200 && response.data) { const { access_token: accessToken, refresh_token: refreshToken } = - authorization; + response.data as ImgurTokenResponse; - (client.credentials as unknown as AccessToken).accessToken = accessToken; - (client.credentials as unknown as AccessToken).refreshToken = - refreshToken; + (client.credentials as Credentials).accessToken = accessToken; + (client.credentials as Credentials).refreshToken = refreshToken; return `Bearer ${accessToken}`; } } if (isClientId(client.credentials)) { - return `Client-ID ${client.credentials.clientId}`; + return `Client-ID ${clientId}`; } return null;