Skip to content

Commit

Permalink
refactor: use destructuring for fetch response
Browse files Browse the repository at this point in the history
  • Loading branch information
sumitkolhe committed Mar 31, 2024
1 parent 1266b92 commit dc2fba8
Show file tree
Hide file tree
Showing 20 changed files with 68 additions and 64 deletions.
4 changes: 2 additions & 2 deletions src/common/helpers/fetch.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const useFetch = async <T>({
endpoint: EndpointValue
params: Record<string, string | number>
context?: 'android' | 'web6dot0'
}): Promise<T> => {
}): Promise<{ data: T; ok: Response['ok'] }> => {
const url = new URL('https://www.jiosaavn.com/api.php')

url.searchParams.append('__call', endpoint.toString())
Expand All @@ -24,5 +24,5 @@ export const useFetch = async <T>({
const response = await fetch(url.toString())
const data = await response.json()

return data as T
return { data: data as T, ...response }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ export class GetAlbumByIdUseCase implements IUseCase<string, z.infer<typeof Albu
constructor() {}

async execute(id: string) {
const response = await useFetch<z.infer<typeof AlbumAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof AlbumAPIResponseModel>>({
endpoint: Endpoints.albums.id,
params: { albumid: id }
})

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

return createAlbumPayload(response)
return createAlbumPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ export class GetAlbumByLinkUseCase implements IUseCase<string, z.infer<typeof Al
constructor() {}

async execute(token: string) {
const response = await useFetch<z.infer<typeof AlbumAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof AlbumAPIResponseModel>>({
endpoint: Endpoints.albums.link,
params: {
token,
type: 'album'
}
})

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

return createAlbumPayload(response)
return createAlbumPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class GetArtistAlbumsUseCase implements IUseCase<GetArtistAlbumsArgs, z.i
constructor() {}

async execute({ artistId, page, sortOrder, sortBy }: GetArtistAlbumsArgs) {
const response = await useFetch<z.infer<typeof ArtistAlbumAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof ArtistAlbumAPIResponseModel>>({
endpoint: Endpoints.artists.albums,
params: {
artistId,
Expand All @@ -27,11 +27,11 @@ export class GetArtistAlbumsUseCase implements IUseCase<GetArtistAlbumsArgs, z.i
}
})

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

return {
total: response.topAlbums.total,
albums: response.topAlbums.albums.map((album) => createAlbumPayload(album))
total: data.topAlbums.total,
albums: data.topAlbums.albums.map((album) => createAlbumPayload(album))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class GetArtistByIdUseCase implements IUseCase<GetArtistByIdArgs, z.infer
constructor() {}

async execute({ artistId, page, songCount, albumCount, sortBy, sortOrder }: GetArtistByIdArgs) {
const response = await useFetch<z.infer<typeof ArtistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof ArtistAPIResponseModel>>({
endpoint: Endpoints.artists.id,
params: {
artistId,
Expand All @@ -31,8 +31,8 @@ export class GetArtistByIdUseCase implements IUseCase<GetArtistByIdArgs, z.infer
}
})

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

return createArtistPayload(response)
return createArtistPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class GetArtistByLinkUseCase implements IUseCase<GetArtistByLinkArgs, z.i
constructor() {}

async execute({ token, page, songCount, albumCount, sortBy, sortOrder }: GetArtistByLinkArgs) {
const response = await useFetch<z.infer<typeof ArtistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof ArtistAPIResponseModel>>({
endpoint: Endpoints.artists.link,
params: {
token,
Expand All @@ -32,8 +32,8 @@ export class GetArtistByLinkUseCase implements IUseCase<GetArtistByLinkArgs, z.i
}
})

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

return createArtistPayload(response)
return createArtistPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class GetArtistSongsUseCase implements IUseCase<GetArtistSongsArgs, z.inf
constructor() {}

async execute({ artistId, page, sortOrder, sortBy }: GetArtistSongsArgs) {
const response = await useFetch<z.infer<typeof ArtistSongAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof ArtistSongAPIResponseModel>>({
endpoint: Endpoints.artists.songs,
params: {
artistId,
Expand All @@ -27,11 +27,11 @@ export class GetArtistSongsUseCase implements IUseCase<GetArtistSongsArgs, z.inf
}
})

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

return {
total: response.topSongs.total,
songs: response.topSongs.songs.map((song) => createSongPayload(song))
total: data.topSongs.total,
songs: data.topSongs.songs.map((song) => createSongPayload(song))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class GetPlaylistByIdUseCase implements IUseCase<GetPlaylistByIdArgs, z.i
constructor() {}

async execute({ id, limit, page }: GetPlaylistByIdArgs) {
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>({
endpoint: Endpoints.playlists.id,
params: {
listid: id,
Expand All @@ -25,9 +25,9 @@ export class GetPlaylistByIdUseCase implements IUseCase<GetPlaylistByIdArgs, z.i
}
})

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

const playlist = createPlaylistPayload(response)
const playlist = createPlaylistPayload(data)
return {
...playlist,
songCount: playlist?.songs?.length || null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class GetPlaylistByLinkUseCase implements IUseCase<GetPlaylistByLinkArgs,
constructor() {}

async execute({ token, limit, page }: GetPlaylistByLinkArgs) {
const response = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof PlaylistAPIResponseModel>>({
endpoint: Endpoints.albums.link,
params: {
token,
Expand All @@ -26,9 +26,9 @@ export class GetPlaylistByLinkUseCase implements IUseCase<GetPlaylistByLinkArgs,
}
})

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

const playlist = createPlaylistPayload(response)
const playlist = createPlaylistPayload(data)

return {
...playlist,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class SearchAlbumsUseCase implements IUseCase<SearchAlbumsArgs, z.infer<t
constructor() {}

async execute({ query, limit, page }: SearchAlbumsArgs): Promise<z.infer<typeof SearchAlbumModel>> {
const response = await useFetch<z.infer<typeof SearchAlbumAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof SearchAlbumAPIResponseModel>>({
endpoint: Endpoints.search.albums,
params: {
q: query,
Expand All @@ -24,6 +24,6 @@ export class SearchAlbumsUseCase implements IUseCase<SearchAlbumsArgs, z.infer<t
}
})

return createSearchAlbumPayload(response)
return createSearchAlbumPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import { createSearchPayload } from '#modules/search/helpers'

export class SearchAllUseCase implements IUseCase<string, z.infer<typeof SearchModel>> {
async execute(query: string): Promise<z.infer<typeof SearchModel>> {
const response = await useFetch<z.infer<typeof SearchAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof SearchAPIResponseModel>>({
endpoint: Endpoints.search.all,
params: { query }
})

if (!response) throw new HTTPException(404, { message: `no results found for ${query}` })
if (!data) throw new HTTPException(404, { message: `no results found for ${query}` })

return createSearchPayload(response)
return createSearchPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class SearchArtistsUseCase implements IUseCase<SearchArtistsArgs, z.infer
constructor() {}

async execute({ query, limit, page }: SearchArtistsArgs): Promise<z.infer<typeof SearchArtistModel>> {
const response = await useFetch<z.infer<typeof SearchArtistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof SearchArtistAPIResponseModel>>({
endpoint: Endpoints.search.artists,
params: {
q: query,
Expand All @@ -25,12 +25,12 @@ export class SearchArtistsUseCase implements IUseCase<SearchArtistsArgs, z.infer
}
})

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

return {
total: response.total,
start: response.start,
results: response.results?.map(createArtistMapPayload).slice(0, limit) || []
total: data.total,
start: data.start,
results: data.results?.map(createArtistMapPayload).slice(0, limit) || []
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class SearchPlaylistsUseCase implements IUseCase<SearchPlaylistsArgs, z.i
constructor() {}

async execute({ query, limit, page }: SearchPlaylistsArgs): Promise<z.infer<typeof SearchPlaylistModel>> {
const response = await useFetch<z.infer<typeof SearchPlaylistAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof SearchPlaylistAPIResponseModel>>({
endpoint: Endpoints.search.playlists,
params: {
q: query,
Expand All @@ -25,8 +25,8 @@ export class SearchPlaylistsUseCase implements IUseCase<SearchPlaylistsArgs, z.i
}
})

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

return createSearchPlaylistPayload(response)
return createSearchPlaylistPayload(data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class SearchSongsUseCase implements IUseCase<SearchSongsArgs, z.infer<typ
constructor() {}

async execute({ query, limit, page }: SearchSongsArgs): Promise<z.infer<typeof SearchSongModel>> {
const response = await useFetch<z.infer<typeof SearchSongAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof SearchSongAPIResponseModel>>({
endpoint: Endpoints.search.songs,
params: {
q: query,
Expand All @@ -25,9 +25,9 @@ export class SearchSongsUseCase implements IUseCase<SearchSongsArgs, z.infer<typ
})

return {
total: response.total,
start: response.start,
results: response.results?.map(createSongPayload).slice(0, limit) || []
total: data.total,
start: data.start,
results: data.results?.map(createSongPayload).slice(0, limit) || []
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ export class CreateSongStationUseCase implements IUseCase<string, string> {
async execute(songId: string) {
const encodedSongId = JSON.stringify([encodeURIComponent(songId)])

const response = await useFetch<{ stationid: string }>({
const { data, ok } = await useFetch<{ stationid: string }>({
endpoint: Endpoints.songs.station,
params: {
entity_id: encodedSongId,
entity_type: 'queue'
}
})

if (!response || !response.stationid) throw new HTTPException(500, { message: 'could not create station' })
if (!data || !data.stationid || !ok) throw new HTTPException(500, { message: 'could not create station' })

return response.stationid
return data.stationid
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ describe('GetSongById', () => {
expect(() => SongModel.parse(song[0])).not.toThrow()
})

it('should return a song by id and include lyrics', async () => {
const song = await getSongById.execute({ songIds: 'L91uYhUm', includeLyrics: true })
it('should return multiple songs by ids', async () => {
const song = await getSongById.execute({ songIds: '3IoDK8qI,K1P4T0jI' })

expect(() => SongModel.parse(song[0])).not.toThrow()
})

it('should throw 404 error when song is not found', async () => {
await expect(getSongById.execute({ songIds: 'invalid-id' })).rejects.toThrow(HTTPException)
})

it('should return a song by id and include lyrics', async () => {
const song = await getSongById.execute({ songIds: 'K1P4T0jI', includeLyrics: true })

expect(() => SongModel.parse(song[0])).not.toThrow()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@ export class GetSongByIdUseCase implements IUseCase<GetSongByIdArgs, z.infer<typ
}

async execute({ songIds, includeLyrics }: GetSongByIdArgs) {
const response = await useFetch<{ songs: z.infer<typeof SongAPIResponseModel> }>({
const { data } = await useFetch<{ songs: z.infer<typeof SongAPIResponseModel>[] }>({
endpoint: Endpoints.songs.id,
params: {
pids: songIds
}
})

const songsResponse = Object.values(response) || []
if (!data.songs?.length) throw new HTTPException(404, { message: 'song not found' })

if (!songsResponse?.length) throw new HTTPException(404, { message: 'song not found' })

const songs = songsResponse.map((song) => createSongPayload(song as any))
const songs = data.songs.map((song) => createSongPayload(song))

if (includeLyrics) {
await Promise.all(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ export class GetSongByLinkUseCase implements IUseCase<string, z.infer<typeof Son
constructor() {}

async execute(token: string) {
const response = await useFetch<{ songs: z.infer<typeof SongAPIResponseModel>[] }>({
const { data } = await useFetch<{ songs: z.infer<typeof SongAPIResponseModel>[] }>({
endpoint: Endpoints.songs.link,
params: {
token,
type: 'song'
}
})

if (!response.songs?.length) throw new HTTPException(404, { message: 'song not found' })
if (!data.songs?.length) throw new HTTPException(404, { message: 'song not found' })

return response.songs.map((song) => createSongPayload(song))
return data.songs.map((song) => createSongPayload(song))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ export class GetSongLyricsUseCase implements IUseCase<string, z.infer<typeof Lyr
constructor() {}

async execute(songId: string) {
const response = await useFetch<z.infer<typeof LyricsAPIResponseModel>>({
const { data } = await useFetch<z.infer<typeof LyricsAPIResponseModel>>({
endpoint: Endpoints.songs.lyrics,
params: {
lyrics_id: songId
}
})

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

return createSongLyricsPayload(response)
return createSongLyricsPayload(data)
}
}
Loading

0 comments on commit dc2fba8

Please sign in to comment.