Skip to content
This repository has been archived by the owner on Aug 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #162 from unsplash/feature/topics
Browse files Browse the repository at this point in the history
Add topics endpoints
  • Loading branch information
samijaber authored Jan 29, 2021
2 parents 7e146e6 + c7adee3 commit 7f32e51
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 0 deletions.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ NOTE: All of the method arguments described here are in the first parameter. See
- [Photos](https://github.com/unsplash/unsplash-js#photos)
- [Users](https://github.com/unsplash/unsplash-js#users)
- [Collections](https://github.com/unsplash/unsplash-js#collections)
- [Topics](https://github.com/unsplash/unsplash-js#topics)

---

Expand Down Expand Up @@ -617,3 +618,70 @@ Lists collections related to the provided one. [See endpoint docs 🚀](https://
```js
unsplash.collections.getRelated({ collectionId: 'abc123' });
```

---

## Topics

### topics.list(arguments, additionalFetchOptions)

Get a single page from the list of all topics. [See endpoint docs 🚀](https://unsplash.com/documentation#list-topics)

**Arguments**

| Argument | Type | Opt/Required | Notes | Default |
| --------------------- | --------------- | ------------ | ------------------------------------------ | ---------- |
| **`topicIdsOrSlugs`** | _Array<string>_ | Optional | | [] |
| **`page`** | _number_ | Optional | | 1 |
| **`perPage`** | _number_ | Optional | | 10 |
| **`orderBy`** | _string_ | Optional | `latest`, `oldest`, `featured`, `position` | `position` |

**Example**

```js
unsplash.topics.list({
page: 1,
perPage: 10,
topicIdsOrSlugs: ['fashion', 'architecture', '6sMVjTLSkeQ'],
});
```

---

### topics.get(arguments, additionalFetchOptions)

Retrieve a single topic. [See endpoint docs 🚀](https://unsplash.com/documentation#get-a-topic)

**Arguments**

| Argument | Type | Opt/Required |
| ------------------- | -------- | ------------ |
| **`topicIdOrSlug`** | _string_ | Required |

**Example**

```js
unsplash.topics.get({ topicIdOrSlug: 'abc123' });
```

---

### topics.getPhotos(arguments, additionalFetchOptions)

Retrieve a topic’s photos. [See endpoint docs 🚀](https://unsplash.com/documentation#get-a-topics-photos)

**Arguments**

| Argument | Type | Opt/Required | Notes | Default |
| ------------------- | -------- | ------------ | ----------------------------------- | -------- |
| **`topicIdOrSlug`** | _string_ | Required | | |
| **`page`** | _number_ | Optional | | 1 |
| **`perPage`** | _number_ | Optional | | 10 |
| **`orderBy`** | _string_ | Optional | `latest`, `oldest`, `popular` | `latest` |
| **`orientation`** | _string_ | Optional | `landscape`, `portrait`, `squarish` | |

**Example**

```js
unsplash.topics.getPhotos({ topicIdOrSlug: 'abc123' });
```
2 changes: 2 additions & 0 deletions src/helpers/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export const createRequestHandler = <Args>(
};
};

export const createRequestGenerator = <Args, T>(handlers: RequestGenerator<Args, T>) => handlers;

/**
* Initial parameters that apply to all calls
*/
Expand Down
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as collections from './methods/collections';
import * as photos from './methods/photos';
import * as search from './methods/search';
import * as users from './methods/users';
import * as topics from './methods/topics';

import * as _internals from './internals';

Expand Down Expand Up @@ -32,6 +33,11 @@ export const createApi = flow(initMakeRequest, makeRequest => ({
list: makeRequest(collections.list),
getRelated: makeRequest(collections.getRelated),
},
topics: {
list: makeRequest(topics.list),
get: makeRequest(topics.get),
getPhotos: makeRequest(topics.getPhotos),
},
}));

export { Language, ColorId, ContentFilter, SearchOrderBy } from './methods/search/types/request';
Expand Down
64 changes: 64 additions & 0 deletions src/methods/topics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { handleFeedResponse } from '../../helpers/feed';
import { compactDefined, flow } from '../../helpers/fp';
import * as Query from '../../helpers/query';
import { createRequestGenerator } from '../../helpers/request';
import { castResponse } from '../../helpers/response';
import { OrientationParam, PaginationParams } from '../../types/request';
import * as Photo from '../photos/types';
import * as Topic from './types';

type TopicIdOrSlug = {
topicIdOrSlug: string;
};

const BASE_TOPIC_PATH = '/topics';
const getTopicPath = ({ topicIdOrSlug }: TopicIdOrSlug) => `${BASE_TOPIC_PATH}/${topicIdOrSlug}`;
const getTopicPhotosPath = flow(getTopicPath, topicPath => `${topicPath}/photos`);

type TopicOrderBy = 'latest' | 'oldest' | 'position' | 'featured';

export const list = createRequestGenerator({
handleRequest: ({
page,
perPage,
orderBy,
topicIdsOrSlugs,
}: Omit<PaginationParams, 'orderBy'> & {
/**
* default: `position`
*/
orderBy?: TopicOrderBy;
topicIdsOrSlugs?: string[];
}) => ({
pathname: BASE_TOPIC_PATH,
query: compactDefined({
...Query.getFeedParams({ page, perPage }),
ids: topicIdsOrSlugs?.join(','),
order_by: orderBy,
}),
}),
handleResponse: handleFeedResponse<Topic.Basic>(),
});

export const get = createRequestGenerator({
handleRequest: ({ topicIdOrSlug }: TopicIdOrSlug) => ({
pathname: getTopicPath({ topicIdOrSlug }),
query: {},
}),
handleResponse: castResponse<Topic.Full>(),
});

export const getPhotos = createRequestGenerator({
handleRequest: ({
topicIdOrSlug,
orientation,
...feedParams
}: TopicIdOrSlug & PaginationParams & OrientationParam) => ({
pathname: getTopicPhotosPath({ topicIdOrSlug }),
query: compactDefined({
...Query.getFeedParams(feedParams),
orientation,
}),
}),
handleResponse: handleFeedResponse<Photo.Basic>(),
});
31 changes: 31 additions & 0 deletions src/methods/topics/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { NonEmptyArray } from '../../helpers/typescript';
import { Entity } from '../../types/entities';

import * as Photo from '../photos/types';
import * as User from '../users/types';

export interface Basic extends Entity {
cover_photo: Photo.Basic | null;
current_user_contributions: Photo.VeryBasic[];
description: string | null;
ends_at: string | null;
featured: boolean;
links: {
self: string;
html: string;
photos: string;
};
owners: NonEmptyArray<User.Basic>;
preview_photos: Photo.VeryBasic[] | null;
published_at: string;
starts_at: string;
status: 'open' | 'closed';
slug: string;
title: string;
total_photos: number;
updated_at: string;
}

export interface Full extends Basic {
top_contributors: User.Basic[];
}
45 changes: 45 additions & 0 deletions tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,51 @@ Object {
}
`;

exports[`requestParams topics get: Correcty builds request arguments 1`] = `
Object {
"pathname": "/topics/topic123",
"query": Object {},
}
`;

exports[`requestParams topics getPhotos: Correcty builds request arguments 1`] = `
Object {
"pathname": "/topics/topic123/photos",
"query": Object {},
}
`;

exports[`requestParams topics getPhotos: Correcty builds request arguments 2`] = `
Object {
"pathname": "/topics/topic123/photos",
"query": Object {
"order_by": "latest",
"orientation": "portrait",
"page": 123,
"per_page": 4,
},
}
`;

exports[`requestParams topics list: Correcty builds request arguments 1`] = `
Object {
"pathname": "/topics",
"query": Object {},
}
`;

exports[`requestParams topics list: Correcty builds request arguments 2`] = `
Object {
"pathname": "/topics",
"query": Object {
"ids": "topic123",
"order_by": "position",
"page": 2,
"per_page": 13,
},
}
`;

exports[`requestParams users get: Correcty builds request arguments 1`] = `
Object {
"headers": Object {},
Expand Down
26 changes: 26 additions & 0 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as collections from '../src/methods/collections';
import * as photos from '../src/methods/photos';
import * as search from '../src/methods/search';
import * as users from '../src/methods/users';
import * as topics from '../src/methods/topics';
import { createApi } from '../src';
import { OrderBy } from '../src/types/request';
import { Language } from '../src/methods/search/types/request';
Expand Down Expand Up @@ -63,6 +64,7 @@ const PHOTO_ID = 'abc123';
const USERNAME = 'usernametest';
const SEARCH_QUERY = 'cat';
const COLLECTION_ID = 'collection123';
const TOPIC_ID_OR_SLUG = 'topic123';

type Api = ReturnType<typeof createApi>;
type Section = keyof Api;
Expand Down Expand Up @@ -138,6 +140,30 @@ const paramsTests: { [S in Section]: Record<keyof Api[S], CompleteRequestParams[
],
getRelated: [collections.getRelated.handleRequest({ collectionId: COLLECTION_ID })],
},
topics: {
get: [topics.get.handleRequest({ topicIdOrSlug: TOPIC_ID_OR_SLUG })],
getPhotos: [
topics.getPhotos.handleRequest({
topicIdOrSlug: TOPIC_ID_OR_SLUG,
}),
topics.getPhotos.handleRequest({
topicIdOrSlug: TOPIC_ID_OR_SLUG,
orientation: 'portrait',
page: 123,
perPage: 4,
orderBy: OrderBy.LATEST,
}),
],
list: [
topics.list.handleRequest({}),
topics.list.handleRequest({
orderBy: 'position',
topicIdsOrSlugs: [TOPIC_ID_OR_SLUG],
page: 2,
perPage: 13,
}),
],
},
};

describe('requestParams', () => {
Expand Down

0 comments on commit 7f32e51

Please sign in to comment.