Skip to content

Commit 152d5ca

Browse files
committed
feat: add pagination support for get playlist
1 parent fb018cc commit 152d5ca

File tree

5 files changed

+81
-20
lines changed

5 files changed

+81
-20
lines changed

src/modules/playlists/controllers/playlist.controller.ts

+26-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,21 @@ export class PlaylistController implements Routes {
4141
type: 'string',
4242
example: 'https://www.jiosaavn.com/featured/its-indie-english/AMoxtXyKHoU_',
4343
default: 'https://www.jiosaavn.com/featured/its-indie-english/AMoxtXyKHoU_'
44-
})
44+
}),
45+
page: z.string().pipe(z.coerce.number()).optional().openapi({
46+
title: 'Page Number',
47+
description: 'The page number of the songs to retrieve from the playlist',
48+
type: 'integer',
49+
example: 0,
50+
default: 0
51+
}),
52+
limit: z.string().pipe(z.coerce.number()).optional().openapi({
53+
title: 'Limit',
54+
description: 'Number of songs to retrieve per page',
55+
type: 'integer',
56+
example: 10,
57+
default: 10
58+
})
4559
})
4660
},
4761
responses: {
@@ -68,15 +82,23 @@ export class PlaylistController implements Routes {
6882
}
6983
}),
7084
async (ctx) => {
71-
const { id, link } = ctx.req.valid('query')
85+
const { id, link, page, limit } = ctx.req.valid('query')
7286

7387
if (!link && !id) {
7488
return ctx.json({ success: false, message: 'Either playlist ID or link is required' }, 400)
7589
}
7690

7791
const response = link
78-
? await this.playlistService.getPlaylistByLink(link)
79-
: await this.playlistService.getPlaylistById(id!)
92+
? await this.playlistService.getPlaylistByLink({
93+
token: link,
94+
page: page || 0,
95+
limit: limit || 10
96+
})
97+
: await this.playlistService.getPlaylistById({
98+
id: id!,
99+
page: page || 0,
100+
limit: limit || 10
101+
})
80102

81103
return ctx.json({ success: true, data: response })
82104
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { GetPlaylistByIdUseCase, GetPlaylistByLinkUseCase } from '#modules/playlists/use-cases'
1+
import {
2+
type GetPlaylistByIdArgs,
3+
GetPlaylistByIdUseCase,
4+
type GetPlaylistByLinkArgs,
5+
GetPlaylistByLinkUseCase
6+
} from '#modules/playlists/use-cases'
27

38
export class PlaylistService {
49
private readonly getPlaylistByIdUseCase: GetPlaylistByIdUseCase
@@ -9,11 +14,11 @@ export class PlaylistService {
914
this.getPlaylistByLinkUseCase = new GetPlaylistByLinkUseCase()
1015
}
1116

12-
getPlaylistById = (playlistId: string) => {
13-
return this.getPlaylistByIdUseCase.execute(playlistId)
17+
getPlaylistById = (args: GetPlaylistByIdArgs) => {
18+
return this.getPlaylistByIdUseCase.execute(args)
1419
}
1520

16-
getPlaylistByLink = (token: string) => {
17-
return this.getPlaylistByLinkUseCase.execute(token)
21+
getPlaylistByLink = (args: GetPlaylistByLinkArgs) => {
22+
return this.getPlaylistByLinkUseCase.execute(args)
1823
}
1924
}

src/modules/playlists/use-cases/get-playlist-by-id/get-playlist-by-id.use-case.spec.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import { beforeAll, describe, expect, test } from 'vitest'
2-
import { GetAlbumByIdUseCase } from '#modules/albums/use-cases'
2+
import { GetPlaylistByIdUseCase } from '#modules/playlists/use-cases'
33

44
describe('GetAlbumById', () => {
5-
let getAlbumByIdUseCase: GetAlbumByIdUseCase
5+
let getPlaylistByIdUseCase: GetPlaylistByIdUseCase
66

77
beforeAll(() => {
8-
getAlbumByIdUseCase = new GetAlbumByIdUseCase()
8+
getPlaylistByIdUseCase = new GetPlaylistByIdUseCase()
99
})
1010

1111
test('should get album by id and return an album', async () => {
12-
const album = await getAlbumByIdUseCase.execute('23241654')
12+
const album = await getPlaylistByIdUseCase.execute({
13+
id: '159470188',
14+
page: 1,
15+
limit: 5
16+
})
1317

1418
expect(album).toMatchSnapshot({
1519
playCount: expect.any(Number),
20+
songCount: expect.any(Number),
1621
songs: album.songs.map((song) => ({
1722
...song,
1823
playCount: expect.any(Number)

src/modules/playlists/use-cases/get-playlist-by-id/get-playlist-by-id.use-case.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,29 @@ import { useFetch } from '#common/helpers'
66
import { Endpoints } from '#common/constants'
77
import { createPlaylistPayload } from '#modules/playlists/helpers'
88

9-
export class GetPlaylistByIdUseCase implements IUseCase<string, z.infer<typeof PlaylistModel>> {
9+
export interface GetPlaylistByIdArgs {
10+
id: string
11+
limit: number
12+
page: number
13+
}
14+
15+
export class GetPlaylistByIdUseCase implements IUseCase<GetPlaylistByIdArgs, z.infer<typeof PlaylistModel>> {
1016
constructor() {}
1117

12-
async execute(id: string) {
13-
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.playlists.id, { listid: id })
18+
async execute({ id, limit, page }: GetPlaylistByIdArgs) {
19+
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.playlists.id, {
20+
listid: id,
21+
n: limit,
22+
p: page
23+
})
1424

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

17-
return createPlaylistPayload(response)
27+
const playlist = createPlaylistPayload(response)
28+
return {
29+
...playlist,
30+
songCount: playlist.songs?.length || 0,
31+
songs: playlist.songs?.slice(0, limit) || []
32+
}
1833
}
1934
}

src/modules/playlists/use-cases/get-playlist-by-link/get-playlist-by-link.use-case.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,31 @@ import { useFetch } from '#common/helpers'
66
import { Endpoints } from '#common/constants'
77
import { createPlaylistPayload } from '#modules/playlists/helpers'
88

9-
export class GetPlaylistByLinkUseCase implements IUseCase<string, z.infer<typeof PlaylistModel>> {
9+
export interface GetPlaylistByLinkArgs {
10+
token: string
11+
limit: number
12+
page: number
13+
}
14+
15+
export class GetPlaylistByLinkUseCase implements IUseCase<GetPlaylistByLinkArgs, z.infer<typeof PlaylistModel>> {
1016
constructor() {}
1117

12-
async execute(token: string) {
18+
async execute({ token, limit, page }: GetPlaylistByLinkArgs) {
1319
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>(Endpoints.albums.link, {
1420
token,
21+
n: limit,
22+
p: page,
1523
type: 'playlist'
1624
})
1725

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

20-
return createPlaylistPayload(response)
28+
const playlist = createPlaylistPayload(response)
29+
30+
return {
31+
...playlist,
32+
songCount: playlist.songs?.length,
33+
songs: playlist.songs?.slice(0, limit) || []
34+
}
2135
}
2236
}

0 commit comments

Comments
 (0)