Skip to content
This repository has been archived by the owner on Dec 30, 2021. It is now read-only.

Commit

Permalink
Merge pull request #150 from kaimallea/next-dev
Browse files Browse the repository at this point in the history
Ship latest changes to next channel
  • Loading branch information
kaimallea committed Mar 28, 2021
2 parents dc24c4f + aa863ad commit 33e522b
Show file tree
Hide file tree
Showing 19 changed files with 360 additions and 107 deletions.
47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ If you don't have any credentials, you'll need to:
1. [Create an Imgur account](https://imgur.com/register)
1. [Register an application](https://api.imgur.com/#registerapp)

### **⚠️ For brevity, the rest of the examples will leave out the import and/or instantiation step.**

### Upload one or more images and videos

You can upload one or more files by simply passing a path to a file or array of paths to multiple files.
Expand Down Expand Up @@ -118,8 +120,6 @@ Acceptable key/values match what [the Imgur API expects](https://apidocs.imgur.c
Instances of `ImgurClient` emit `uploadProgress` events so that you can track progress with event listeners.

```ts
import { ImgurClient } from 'imgur';

const client = new ImgurClient({ accessToken: process.env.ACCESS_TOKEN });

client.on('uploadProgress', (progress) => console.log(progress));
Expand All @@ -143,3 +143,46 @@ The progress object looks like the following:
| `transferred` | total number of bytes transferred thus far |
| `total` | total number of bytes to be transferred |
| `id` | unique id for the media being transferred; useful when uploading multiple things concurrently |

### Delete an image

Requires an image hash or delete hash, which are obtained in an image upload response

```ts
client.delete('someImageHash');
```

### Update image information

Update the title and/or description of an image

```ts
client.updateImage({
imageHash: 'someImageHash',
title: 'A new title',
description: 'A new description',
});
```

Update multiple images at once:

```ts
client.updateImage([
{
imageHash: 'someImageHash',
title: 'A new title',
description: 'A new description',
},
{
imageHash: 'anotherImageHash',
title: 'A better title',
description: 'A better description',
},
]);
```

Favorite an image:

```ts
client.favoriteImage('someImageHash');
```
36 changes: 25 additions & 11 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { EventEmitter } from 'events';
import got, { ExtendOptions, Got } from 'got';
import { getAuthorizationHeader, Credentials } from './helpers';
import { getImage, upload, Payload } from './image';
import { IMGUR_API_PREFIX } from './helpers';

type ImgurApiResponse = {
data: Record<string, unknown>;
status: number;
success: boolean;
};
import { getAuthorizationHeader } from './getAuthorizationHeader';
import {
deleteImage,
favoriteImage,
getImage,
upload,
updateImage,
UpdateImagePayload,
} from './image';
import { IMGUR_API_PREFIX } from './common/endpoints';
import { Credentials, Payload } from './common/types';

const USERAGENT = 'imgur/next (https://github.com/kaimallea/node-imgur)';

Expand Down Expand Up @@ -44,11 +46,23 @@ export class ImgurClient extends EventEmitter {
return this.gotExtended.extend(options)(url);
}

async getImage(imageHash: string) {
deleteImage(imageHash: string) {
return deleteImage(this, imageHash);
}

favoriteImage(imageHash: string) {
return favoriteImage(this, imageHash);
}

getImage(imageHash: string) {
return getImage(this, imageHash);
}

async upload(payload: string | string[] | Payload | Payload[]) {
updateImage(payload: UpdateImagePayload | UpdateImagePayload[]) {
return updateImage(this, payload);
}

upload(payload: string | string[] | Payload | Payload[]) {
return upload(this, payload);
}
}
File renamed without changes.
47 changes: 47 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export interface AccessToken {
accessToken: string;
}

export interface ClientId {
clientId: string;
}

export interface Login extends ClientId {
username: string;
password: string;
}

export type Credentials = AccessToken | ClientId | Login;

export function isAccessToken(arg: any): arg is AccessToken {
return arg.accessToken !== undefined;
}

export function isClientId(arg: any): arg is ClientId {
return arg.clientId !== undefined;
}

export function isLogin(arg: any): arg is Login {
return (
arg.clientId !== undefined &&
arg.username !== undefined &&
arg.password !== undefined
);
}

export interface ImgurApiResponse {
data: Record<string, unknown> | string | boolean;
status: number;
success: boolean;
}

export interface Payload {
image?: string;
video?: string;
type?: 'file' | 'url' | 'base64';
name?: string;
title?: string;
description?: string;
album?: string;
disable_audio?: '1' | '0';
}
42 changes: 42 additions & 0 deletions src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createReadStream } from 'fs';
import FormData from 'form-data';
import { Payload } from './types';

export function isVideo(payload: string | Payload) {
if (typeof payload === 'string') {
return false;
}

return typeof payload.video !== 'undefined' && payload.video;
}

export function getSource(payload: string | Payload) {
if (typeof payload === 'string') {
return payload;
}

if (isVideo(payload)) {
return payload.video;
} else {
return payload.image;
}
}

export function createForm(payload: string | Payload) {
const form = new FormData();

if (typeof payload === 'string') {
form.append('image', createReadStream(payload));
return form;
}

for (const [key, value] of Object.entries(payload)) {
if (key === 'image' || key === 'video') {
if (!payload.type || payload.type === 'file')
form.append(key, createReadStream(value));
} else {
form.append(key, value);
}
}
return form;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ImgurClient } from '../client';
import { ImgurClient } from './client';
import { getAuthorizationHeader } from './getAuthorizationHeader';

test('returns provided access code in bearer header', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isAccessToken, isClientId, isLogin } from './credentials';
import { ImgurClient } from '../client';
import { IMGUR_API_PREFIX, AUTHORIZE_ENDPOINT } from '../helpers';
import { isAccessToken, isClientId, isLogin } from './common/types';
import { ImgurClient } from './client';
import { IMGUR_API_PREFIX, AUTHORIZE_ENDPOINT } from './common/endpoints';

export async function getAuthorizationHeader(client: ImgurClient) {
if (isAccessToken(client.credentials)) {
Expand Down
26 changes: 0 additions & 26 deletions src/helpers/credentials.ts

This file was deleted.

3 changes: 0 additions & 3 deletions src/helpers/index.ts

This file was deleted.

15 changes: 15 additions & 0 deletions src/image/deleteImage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ImgurClient } from '../client';
import { deleteImage } from './deleteImage';

test('delete works successfully', async () => {
const accessToken = 'abc123';
const client = new ImgurClient({ accessToken });
const response = await deleteImage(client, 'CEddrgP');
expect(response).toMatchInlineSnapshot(`
Object {
"data": true,
"status": 200,
"success": true,
}
`);
});
15 changes: 15 additions & 0 deletions src/image/deleteImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ImgurClient } from '../client';
import { IMAGE_ENDPOINT } from '../common/endpoints';

export interface DeleteResponse {
data: true;
success: true;
status: 200;
}

export async function deleteImage(client: ImgurClient, imageHash: string) {
const url = `${IMAGE_ENDPOINT}/${imageHash}`;
return (await client
.request(url, { method: 'DELETE' })
.json()) as DeleteResponse;
}
15 changes: 15 additions & 0 deletions src/image/favoriteImage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ImgurClient } from '../client';
import { favoriteImage } from './favoriteImage';

test('favorite works successfully', async () => {
const accessToken = 'abc123';
const client = new ImgurClient({ accessToken });
const response = await favoriteImage(client, 'CEddrgP');
expect(response).toMatchInlineSnapshot(`
Object {
"data": "favorited",
"status": 200,
"success": true,
}
`);
});
15 changes: 15 additions & 0 deletions src/image/favoriteImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ImgurClient } from '../client';
import { IMAGE_ENDPOINT } from '../common/endpoints';

type FavoriteResponse = {
data: 'favorited';
success: true;
status: 200;
};

export async function favoriteImage(client: ImgurClient, imageHash: string) {
const url = `${IMAGE_ENDPOINT}/${imageHash}/favorite`;
return (await client
.request(url, { method: 'POST' })
.json()) as FavoriteResponse;
}
11 changes: 4 additions & 7 deletions src/image/getImage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ImgurClient } from '../client';
import { IMAGE_ENDPOINT } from '../helpers';
import { IMAGE_ENDPOINT } from '../common/endpoints';

type ImageResponse = {
export interface ImageResponse {
data?: {
id?: string;
title?: string | null;
Expand Down Expand Up @@ -39,12 +39,9 @@ type ImageResponse = {
};
success?: boolean;
status?: number;
};
}

export async function getImage(
client: ImgurClient,
imageHash: string
): Promise<ImageResponse> {
export async function getImage(client: ImgurClient, imageHash: string) {
const url = `${IMAGE_ENDPOINT}/${imageHash}`;
return (await client.request(url).json()) as ImageResponse;
}
3 changes: 3 additions & 0 deletions src/image/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './deleteImage';
export * from './favoriteImage';
export * from './getImage';
export * from './updateImage';
export * from './upload';
Loading

0 comments on commit 33e522b

Please sign in to comment.