✨ get top singles and videos when fetching an artist
This commit is contained in:
parent
d60878c8ac
commit
27df842c98
|
|
@ -30,6 +30,8 @@ interface AlbumDetailed {
|
||||||
|
|
||||||
[ArtistFull#topAlbums](./ArtistFull.html)
|
[ArtistFull#topAlbums](./ArtistFull.html)
|
||||||
|
|
||||||
|
[ArtistFull#topSingles](./ArtistFull.html)
|
||||||
|
|
||||||
[SearchResult](../types/SearchResult.html)
|
[SearchResult](../types/SearchResult.html)
|
||||||
|
|
||||||
[YTMusic#searchAlbums](../ytmusic/searchAlbums.html)
|
[YTMusic#searchAlbums](../ytmusic/searchAlbums.html)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
| description | `string` | Description |
|
| description | `string` | Description |
|
||||||
| topSongs | `Omit<`[SongDetailed](./SongDetailed.html)`, "duration">[]` | Top Songs from Artist |
|
| topSongs | `Omit<`[SongDetailed](./SongDetailed.html)`, "duration">[]` | Top Songs from Artist |
|
||||||
| topAlbums | [AlbumDetailed](./AlbumDetailed.html)`[]` | Top Albums from Artist |
|
| topAlbums | [AlbumDetailed](./AlbumDetailed.html)`[]` | Top Albums from Artist |
|
||||||
|
| topSingles | [AlbumDetailed](./AlbumDetailed.html)`[]` | Top Singles from Artist |
|
||||||
|
| topVideos | `Omit<`[VideoDetailed](./VideoDetailed.html)`, "duration">[]` | Top Videos from Artist |
|
||||||
|
|
||||||
## TypeScript Source Code
|
## TypeScript Source Code
|
||||||
|
|
||||||
|
|
@ -23,6 +25,8 @@ interface ArtistFull {
|
||||||
description: string
|
description: string
|
||||||
topSongs: Omit<SongDetailed, "duration">[]
|
topSongs: Omit<SongDetailed, "duration">[]
|
||||||
topAlbums: AlbumDetailed[]
|
topAlbums: AlbumDetailed[]
|
||||||
|
topSingles: AlbumDetailed[]
|
||||||
|
topVideos: Omit<VideoDetailed, "duration">[]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ interface VideoDetailed {
|
||||||
|
|
||||||
## Usages
|
## Usages
|
||||||
|
|
||||||
|
[ArtistFull#topVideos](../types/ArtistFull.html)
|
||||||
|
|
||||||
[SearchResult](../types/SearchResult.html)
|
[SearchResult](../types/SearchResult.html)
|
||||||
|
|
||||||
[YTMusic#searchVideos](../ytmusic/searchVideos.html)
|
[YTMusic#searchVideos](../ytmusic/searchVideos.html)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ytmusic-api",
|
"name": "ytmusic-api",
|
||||||
"version": "4.0.2",
|
"version": "4.1.0",
|
||||||
"description": "YouTube Music API",
|
"description": "YouTube Music API",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ export default class AlbumParser {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static parseArtistTopAlbums(item: any, artistBasic: ArtistBasic): AlbumDetailed {
|
public static parseArtistTopAlbum(item: any, artistBasic: ArtistBasic): AlbumDetailed {
|
||||||
return checkType(
|
return checkType(
|
||||||
{
|
{
|
||||||
type: "ALBUM",
|
type: "ALBUM",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
|
|
||||||
|
|
||||||
import { ArtistBasic, ArtistDetailed, ArtistFull } from "../schemas"
|
import { ArtistBasic, ArtistDetailed, ArtistFull } from "../schemas"
|
||||||
import checkType from "../utils/checkType"
|
import checkType from "../utils/checkType"
|
||||||
import traverse from "../utils/traverse"
|
|
||||||
import traverseList from "../utils/traverseList"
|
import traverseList from "../utils/traverseList"
|
||||||
import traverseString from "../utils/traverseString"
|
import traverseString from "../utils/traverseString"
|
||||||
import AlbumParser from "./AlbumParser"
|
import AlbumParser from "./AlbumParser"
|
||||||
import SongParser from "./SongParser"
|
import SongParser from "./SongParser"
|
||||||
|
import VideoParser from "./VideoParser"
|
||||||
|
|
||||||
export default class ArtistParser {
|
export default class ArtistParser {
|
||||||
public static parse(data: any, artistId: string): ArtistFull {
|
public static parse(data: any, artistId: string): ArtistFull {
|
||||||
|
|
@ -28,7 +30,19 @@ export default class ArtistParser {
|
||||||
traverseList(data, "musicCarouselShelfRenderer")
|
traverseList(data, "musicCarouselShelfRenderer")
|
||||||
?.at(0)
|
?.at(0)
|
||||||
?.contents.map((item: any) =>
|
?.contents.map((item: any) =>
|
||||||
AlbumParser.parseArtistTopAlbums(item, artistBasic)
|
AlbumParser.parseArtistTopAlbum(item, artistBasic)
|
||||||
|
) ?? [],
|
||||||
|
topSingles:
|
||||||
|
traverseList(data, "musicCarouselShelfRenderer")
|
||||||
|
?.at(1)
|
||||||
|
?.contents.map((item: any) =>
|
||||||
|
AlbumParser.parseArtistTopAlbum(item, artistBasic)
|
||||||
|
) ?? [],
|
||||||
|
topVideos:
|
||||||
|
traverseList(data, "musicCarouselShelfRenderer")
|
||||||
|
?.at(2)
|
||||||
|
?.contents.map((item: any) =>
|
||||||
|
VideoParser.parseArtistTopVideo(item, artistBasic)
|
||||||
) ?? []
|
) ?? []
|
||||||
},
|
},
|
||||||
ArtistFull
|
ArtistFull
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { VideoDetailed, VideoFull } from "../schemas"
|
import { ArtistBasic, VideoDetailed, VideoFull } from "../schemas"
|
||||||
import checkType from "../utils/checkType"
|
import checkType from "../utils/checkType"
|
||||||
import traverse from "../utils/traverse"
|
import traverse from "../utils/traverse"
|
||||||
import traverseList from "../utils/traverseList"
|
import traverseList from "../utils/traverseList"
|
||||||
|
|
@ -46,6 +46,19 @@ export default class VideoParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static parseArtistTopVideo(
|
||||||
|
item: any,
|
||||||
|
artistBasic: ArtistBasic
|
||||||
|
): Omit<VideoDetailed, "duration"> {
|
||||||
|
return {
|
||||||
|
type: "VIDEO",
|
||||||
|
videoId: traverseString(item, "videoId")(),
|
||||||
|
name: traverseString(item, "runs", "text")(),
|
||||||
|
artists: [artistBasic],
|
||||||
|
thumbnails: traverseList(item, "thumbnails")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static parsePlaylistVideo(item: any): VideoDetailed {
|
public static parsePlaylistVideo(item: any): VideoDetailed {
|
||||||
const flexColumns = traverseList(item, "flexColumns")
|
const flexColumns = traverseList(item, "flexColumns")
|
||||||
const videoId =
|
const videoId =
|
||||||
|
|
|
||||||
|
|
@ -94,17 +94,10 @@ export const ArtistFull = z.object({
|
||||||
type: z.literal("ARTIST"),
|
type: z.literal("ARTIST"),
|
||||||
thumbnails: z.array(ThumbnailFull),
|
thumbnails: z.array(ThumbnailFull),
|
||||||
description: z.string(),
|
description: z.string(),
|
||||||
topSongs: z.array(
|
topSongs: z.array(SongDetailed.omit({ duration: true })),
|
||||||
z.object({
|
topAlbums: z.array(AlbumDetailed),
|
||||||
type: z.literal("SONG"),
|
topSingles: z.array(AlbumDetailed),
|
||||||
videoId: z.string(),
|
topVideos: z.array(VideoDetailed.omit({ duration: true }))
|
||||||
name: z.string(),
|
|
||||||
artists: z.array(ArtistBasic),
|
|
||||||
album: AlbumBasic,
|
|
||||||
thumbnails: z.array(ThumbnailFull)
|
|
||||||
})
|
|
||||||
),
|
|
||||||
topAlbums: z.array(AlbumDetailed)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export type AlbumFull = z.infer<typeof AlbumFull>
|
export type AlbumFull = z.infer<typeof AlbumFull>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue