diff --git a/dist/index.js b/dist/index.js index e3d25fe..27aa123 100644 --- a/dist/index.js +++ b/dist/index.js @@ -212,7 +212,7 @@ var SCDL = /** @class */ (function () { }; /** * Searches for tracks/playlists for the given query - * @param type - The type of resource, one of: 'tracks', 'people', 'albums', 'sets', 'all' + * @param type - The type of resource, one of: 'tracks', 'people', 'albums', 'playlists', 'all' * @param query - The keywords for the search * @param clientID - A Soundcloud Client ID, will find one if not provided * @returns SearchResponse @@ -231,6 +231,29 @@ var SCDL = /** @class */ (function () { }); }); }; + /** + * Finds related tracks/playlists/albums to the given track/playlist/album specified by ID + * @param type - 'tracks', 'people', 'albums', 'playlists' + * @param id - The ID of the resource + * @param limit - The number of results to return + * @param offset - Used for pagination, set to 0 if you will not use this feature. + * @param clientID - A Soundcloud Client ID, will find one if not provided + */ + SCDL.prototype.related = function (type, id, limit, offset, clientID) { + if (offset === void 0) { offset = 0; } + return __awaiter(this, void 0, void 0, function () { + var _a, _b; + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + _a = search_1.related; + _b = [type, id, limit, offset]; + return [4 /*yield*/, this._assignClientID(clientID)]; + case 1: return [2 /*return*/, _a.apply(void 0, _b.concat([_c.sent()]))]; + } + }); + }); + }; /** * Returns whether or not the given URL is a valid Soundcloud URL * @param url - URL of the Soundcloud track diff --git a/src/index.ts b/src/index.ts index 2cd0a71..3166ebe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,7 +8,7 @@ import isValidURL from './is-url' import STREAMING_PROTOCOLS, { _PROTOCOLS } from './protocols' import FORMATS, { _FORMATS } from './formats' -import { search, SoundcloudResource } from './search' +import { search, related, SoundcloudResource } from './search' /** @internal */ const download = async (url: string, clientID: string) => { @@ -95,7 +95,7 @@ export class SCDL { /** * Searches for tracks/playlists for the given query - * @param type - The type of resource, one of: 'tracks', 'people', 'albums', 'sets', 'all' + * @param type - The type of resource, one of: 'tracks', 'people', 'albums', 'playlists', 'all' * @param query - The keywords for the search * @param clientID - A Soundcloud Client ID, will find one if not provided * @returns SearchResponse @@ -104,6 +104,18 @@ export class SCDL { return search(type, query, await this._assignClientID(clientID)) } + /** + * Finds related tracks/playlists/albums to the given track/playlist/album specified by ID + * @param type - 'tracks', 'people', 'albums', 'playlists' + * @param id - The ID of the resource + * @param limit - The number of results to return + * @param offset - Used for pagination, set to 0 if you will not use this feature. + * @param clientID - A Soundcloud Client ID, will find one if not provided + */ + async related (type: SoundcloudResource, id: number, limit: number, offset = 0, clientID?: string) { + return related(type, id, limit, offset, await this._assignClientID(clientID)) + } + /** * Returns whether or not the given URL is a valid Soundcloud URL * @param url - URL of the Soundcloud track diff --git a/src/search.ts b/src/search.ts index f4bf441..50df3e6 100644 --- a/src/search.ts +++ b/src/search.ts @@ -12,6 +12,13 @@ export type SearchResponse = { query_urn: string } +export type RelatedResponse = { + collection: T[] + next_href: string, + query_urn: string, + variant: string +} + export type SearchResponseAll = SearchResponse export type SoundcloudResource = 'tracks' | 'people' | 'albums' | 'playlists' @@ -23,7 +30,7 @@ export const search = async (type: SoundcloudResource | 'all', query: string, cl } /** @internal */ -export const related = async (type: SoundcloudResource, id: number, limit = 10, offset = 0, clientID: string): Promise> => { +export const related = async (type: SoundcloudResource, id: number, limit = 10, offset = 0, clientID: string): Promise> => { const { data } = await axios.get(`https://api-v2.soundcloud.com/${type}/${id}/related?client_id=${clientID}&offset=${offset}&limit=${limit}`) - return data as SearchResponse + return data as RelatedResponse } diff --git a/tests/related.test.js b/tests/related.test.js new file mode 100644 index 0000000..e773773 --- /dev/null +++ b/tests/related.test.js @@ -0,0 +1,34 @@ +/** + * @jest-environment node + */ + +import scdl, { search } from '../' + +describe('related()', () => { + const limit = 10 + let searchResponse + + beforeAll(async () => { + try { + searchResponse = await scdl.related('tracks', 170286204, limit, 0) + } catch (err) { + console.log(err) + process.exit(1) + } + }) + + it('returns a valid SearchResponse object', () => { + const keys = ['collection', 'next_href', 'variant', 'query_urn'].forEach(key => expect(searchResponse[key]).toBeDefined()) + }) + + it('resource count returned is equal to limit', () => { + expect(searchResponse.collection.length).toEqual(limit) + }) + + it('resource returned corresponds to type parameter', () => { + searchResponse.collection.forEach(track => { + expect(track.title).toBeDefined() + expect(track.media).toBeDefined() + }) + }) +})