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

Commit

Permalink
feat: add search.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
vaaski committed Feb 19, 2021
1 parent ef6be53 commit ec688c4
Show file tree
Hide file tree
Showing 4 changed files with 417 additions and 5 deletions.
17 changes: 14 additions & 3 deletions demo.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { playlist, resolve, user, util } from "./src"
import { playlist, resolve, user, util, search } from "./src"
import { writeFileSync } from "fs"
import { getClientIDv2 } from "./src/util"
import { join } from "path"
Expand All @@ -25,12 +25,19 @@ const examplePlaylistID = Number(process.env.EXAMPLE_PLAYLIST_ID) || 0
const exampleUserURL = process.env.EXAMPLE_USER_URL || ""
const exampleUserID = Number(process.env.EXAMPLE_USER_ID) || 0
const exampleTrackURL = process.env.EXAMPLE_TRACK_URL || ""
const exampleSearchTerm = "noisia"

!(async () => {
try {
console.log("start")
const startTime = Date.now()

// const out1 = await search(exampleSearchTerm, { limit: 2 })
// const out2 = await out1.next?.()
// const out = [...out1.collection, ...(out2?.collection || [])]

// const out = await util.ensureMin(await search(exampleSearchTerm, { limit: 1 }), 10)

// const out1 = await user.tracks(exampleUserID, { limit: 5 })
// const out2 = await out1.next?.()
// const out = [...out1.collection, ...(out2?.collection || [])]
Expand All @@ -41,17 +48,21 @@ const exampleTrackURL = process.env.EXAMPLE_TRACK_URL || ""

// const out = await util.ensureMin(await user.tracks("space-laces", { limit: 10 }), 10)

const out = await search(exampleSearchTerm)
// const out = await search.users(exampleSearchTerm)
// const out = await search.albums(exampleSearchTerm)
// const out = await search.playlists(exampleSearchTerm)
// const out = await user.tracks(exampleUserID, { limit: 2 })
// const out = await user.likes(exampleUserID, { limit: 2 })
// const out = await user(exampleUserID)
// const out = await user(exampleUserURL)
// const out = await playlist(examplePlaylistURL)
// const out = await playlist(examplePlaylistID)
// const out = await getClientIDv2()
// const out = await resolve("noisia/deep-down")
// const out = await resolve(exampleUserURL)
// const out = await resolve(exampleTrackURL)
// const out = await resolve(examplePlaylistURL)
const out = await resolve.browser("/noisia/sets/noisia-radio", client_id)
// const out = await resolve.browser(exampleUserURL, client_id)
// const out = await resolve.browser(exampleTrackURL, client_id)
// const out = await resolve.browser(examplePlaylistURL, client_id)

Expand Down
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import resolve from "./resolve"
import playlist from "./playlist"
import user from "./user"
import search from "./search"
import { ensureMin, getClientIDv2 } from "./util"

const util = { ensureMin, getClientIDv2 }

export default { resolve, playlist, user, util }
export { resolve, playlist, user, util }
export default { resolve, playlist, user, util, search }
export { resolve, playlist, user, util, search }
73 changes: 73 additions & 0 deletions src/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import type { PaginatedOptions } from "../types"
import type { Search, SearchResult } from "../types/search"

import ky from "ky-universal"
import {
APIv2,
defaultLimit,
getClientIDv2,
PaginatedResponse,
paginateNext,
urlify,
} from "./util"

const searchFactory = (urlPath: string) => async (
query: string,
{ limit = defaultLimit, client_id }: PaginatedOptions = {}
): Promise<PaginatedResponse<SearchResult[]>> => {
if (!client_id) client_id = await getClientIDv2()

const url = urlify(urlPath, APIv2)
const searchParams = {
client_id,
limit,
q: query,
}
const req = await ky(url, { searchParams })
const data = (await req.json()) as Search

const ret: PaginatedResponse<SearchResult[]> = data

/* istanbul ignore next */
if (data.next_href) ret.next = paginateNext(data.next_href, searchParams)

return ret
}

export type SearchFunction = (
query: string,
options?: PaginatedOptions
) => Promise<PaginatedResponse<SearchResult[]>>

export interface OpensoundcloudSearch {
(query: string, options?: PaginatedOptions): Promise<PaginatedResponse<SearchResult[]>>
users: SearchFunction
tracks: SearchFunction
albums: SearchFunction
playlists: SearchFunction
}

/**
* Search tracks, users and playlists.
*
* You can provide a v2 client_id to save one scrape request (recommended).
* Uses `util.getClientIDv2` to find a client_id if none is provided.
* @param query search query
* @param options Optional options object.
* @param options.limit Limit the amount of tracks returned. Defaults to 50.
* @param options.client_id client_id for APIv2.
*/
// @ts-expect-error not sure how to fix this, but the other functions get
// declared right below
const search: OpensoundcloudSearch = searchFactory("search")

search.users = searchFactory("search/users")
search.tracks = searchFactory("search/tracks")
search.albums = searchFactory("search/albums")
search.playlists = searchFactory("search/playlists_without_albums")

// TODO write tests
// TODO write jsdoc
// TODO write docs

export default search
Loading

0 comments on commit ec688c4

Please sign in to comment.