Skip to content

Commit

Permalink
feat: search playlists
Browse files Browse the repository at this point in the history
  • Loading branch information
sumitkolhe committed Mar 16, 2024
1 parent 3c4e831 commit 2d52b33
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 7 deletions.
7 changes: 4 additions & 3 deletions src/modules/artists/controllers/artist.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
import { ArtistService } from '../services'
import { ArtistAlbumModel, ArtistModel, ArtistSongModel } from '../models'
import { OpenAPIHono, createRoute } from '@hono/zod-openapi'
import { z } from 'zod'
import { ArtistAlbumModel, ArtistModel, ArtistSongModel } from '#modules/artists/models'
import { ArtistService } from '#modules/artists/services'

export class ArtistController {
public controller: OpenAPIHono
Expand Down
69 changes: 68 additions & 1 deletion src/modules/search/controllers/search.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi'
import { SearchService } from '#modules/search/services'
import { SearchAlbumModel, SearchArtistModel, SearchModel, SearchSongModel } from '#modules/search/models'
import {
SearchAlbumModel,
SearchArtistModel,
SearchModel,
SearchPlaylistModel,
SearchSongModel
} from '#modules/search/models'

export class SearchController {
public controller: OpenAPIHono
Expand Down Expand Up @@ -238,5 +244,66 @@ export class SearchController {
return ctx.json({ success: true, data: result })
}
)

this.controller.openapi(
createRoute({
method: 'get',
path: '/search/playlists',
tags: ['Search'],
summary: 'Search for playlists',
description: 'Search for playlists based on the provided query',
operationId: 'searchPlaylists',
request: {
query: z.object({
query: z.string().openapi({
title: 'Search query',
description: 'Search query for playlists',
type: 'string',
example: 'Indie'
}),
page: z.string().pipe(z.coerce.number()).optional().openapi({
title: 'Page Number',
description: 'The page number of the search results to retrieve',
type: 'integer',
example: 0,
default: 0
}),
limit: z.string().pipe(z.coerce.number()).optional().openapi({
title: 'Limit',
description: 'Number of search results per page',
type: 'integer',
example: 10,
default: 10
})
})
},
responses: {
200: {
description: 'Successful response with playlist search results',
content: {
'application/json': {
schema: z.object({
success: z.boolean().openapi({
description: 'Indicates whether the playlist search was successful',
type: 'boolean',
example: true
}),
data: SearchPlaylistModel.openapi({
description: 'Search results for playlist'
})
})
}
}
}
}
}),
async (ctx) => {
const { query, page, limit } = ctx.req.valid('query')

const result = await this.searchService.searchPlaylists({ query, page: page || 0, limit: limit || 10 })

return ctx.json({ success: true, data: result })
}
)
}
}
1 change: 1 addition & 0 deletions src/modules/search/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './search.model'
export * from './search-artist.model'
export * from './search-song.model'
export * from './search-album.model'
export * from './search-playlist.model'
14 changes: 14 additions & 0 deletions src/modules/search/models/search-playlist.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { z } from 'zod'
import { PlaylistAPIResponseModel, PlaylistModel } from '#modules/playlists/models'

export const SearchPlaylistAPIResponseModel = z.object({
total: z.number(),
start: z.number(),
results: z.array(PlaylistAPIResponseModel)
})

export const SearchPlaylistModel = z.object({
total: z.number(),
start: z.number(),
results: z.array(PlaylistModel)
})
8 changes: 8 additions & 0 deletions src/modules/search/services/search.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
SearchAllUseCase,
type SearchArtistsArgs,
SearchArtistsUseCase,
type SearchPlaylistsArgs,
SearchPlaylistsUseCase,
type SearchSongsArgs,
SearchSongsUseCase
} from '#modules/search/use-cases'
Expand All @@ -13,12 +15,14 @@ export class SearchService {
private readonly searchSongsUseCase: SearchSongsUseCase
private readonly searchAlbumsUseCase: SearchAlbumsUseCase
private readonly searchArtistsUseCase: SearchArtistsUseCase
private readonly searchPlaylistsUseCase: SearchPlaylistsUseCase

constructor() {
this.searchAllUseCase = new SearchAllUseCase()
this.searchSongsUseCase = new SearchSongsUseCase()
this.searchAlbumsUseCase = new SearchAlbumsUseCase()
this.searchArtistsUseCase = new SearchArtistsUseCase()
this.searchPlaylistsUseCase = new SearchPlaylistsUseCase()
}

searchAll = (query: string) => {
Expand All @@ -36,4 +40,8 @@ export class SearchService {
searchArtists = (args: SearchArtistsArgs) => {
return this.searchArtistsUseCase.execute(args)
}

searchPlaylists = (args: SearchPlaylistsArgs) => {
return this.searchPlaylistsUseCase.execute(args)
}
}
1 change: 1 addition & 0 deletions src/modules/search/use-cases/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './search-all'
export * from './search-albums'
export * from './search-songs'
export * from './search-artists'
export * from './search-playlists'
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { HTTPException } from 'hono/http-exception'
import { Endpoints } from '../../../../common/constants'
import { useFetch } from '../../../../common/helpers'
import type { IUseCase } from '#common/types'
import type { z } from 'zod'
import type { IUseCase } from '#common/types'
import type { SearchAlbumAPIResponseModel, SearchAlbumModel } from '#modules/search/models'
import { Endpoints } from '#common/constants'
import { useFetch } from '#common/helpers'
import { createAlbumPayload } from '#modules/albums/helpers'

export interface SearchAlbumsArgs {
Expand Down
1 change: 1 addition & 0 deletions src/modules/search/use-cases/search-playlists/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './search-playlists.use-case'
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { HTTPException } from 'hono/http-exception'
import type { IUseCase } from '#common/types'
import type { z } from 'zod'
import type { SearchPlaylistAPIResponseModel, SearchPlaylistModel } from '#modules/search/models'
import { useFetch } from '#common/helpers'
import { Endpoints } from '#common/constants'
import { createPlaylistPayload } from '#modules/playlists/helpers'

export interface SearchPlaylistsArgs {
query: string
page: number
limit: number
}

export class SearchPlaylistsUseCase implements IUseCase<SearchPlaylistsArgs, z.infer<typeof SearchPlaylistModel>> {
constructor() {}

async execute({ query, limit, page }: SearchPlaylistsArgs): Promise<z.infer<typeof SearchPlaylistModel>> {
const response = await useFetch<z.infer<typeof SearchPlaylistAPIResponseModel>>(Endpoints.search.playlists, {
q: query,
p: page,
n: limit
})

if (!response) throw new HTTPException(404, { message: 'playlist not found' })

return {
total: response.total,
start: response.start,
results: response.results?.map(createPlaylistPayload).slice(0, limit) || []
}
}
}

0 comments on commit 2d52b33

Please sign in to comment.