get top singles and videos when fetching an artist

This commit is contained in:
Zechariah 2022-12-29 12:56:11 +08:00
parent d60878c8ac
commit 27df842c98
8 changed files with 44 additions and 16 deletions

View File

@ -30,6 +30,8 @@ interface AlbumDetailed {
[ArtistFull#topAlbums](./ArtistFull.html)
[ArtistFull#topSingles](./ArtistFull.html)
[SearchResult](../types/SearchResult.html)
[YTMusic#searchAlbums](../ytmusic/searchAlbums.html)

View File

@ -11,6 +11,8 @@
| description | `string` | Description |
| topSongs | `Omit<`[SongDetailed](./SongDetailed.html)`, "duration">[]` | Top Songs 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
@ -23,6 +25,8 @@ interface ArtistFull {
description: string
topSongs: Omit<SongDetailed, "duration">[]
topAlbums: AlbumDetailed[]
topSingles: AlbumDetailed[]
topVideos: Omit<VideoDetailed, "duration">[]
}
```

View File

@ -26,6 +26,8 @@ interface VideoDetailed {
## Usages
[ArtistFull#topVideos](../types/ArtistFull.html)
[SearchResult](../types/SearchResult.html)
[YTMusic#searchVideos](../ytmusic/searchVideos.html)

View File

@ -1,6 +1,6 @@
{
"name": "ytmusic-api",
"version": "4.0.2",
"version": "4.1.0",
"description": "YouTube Music API",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@ -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(
{
type: "ALBUM",

View File

@ -1,10 +1,12 @@
import { ArtistBasic, ArtistDetailed, ArtistFull } from "../schemas"
import checkType from "../utils/checkType"
import traverse from "../utils/traverse"
import traverseList from "../utils/traverseList"
import traverseString from "../utils/traverseString"
import AlbumParser from "./AlbumParser"
import SongParser from "./SongParser"
import VideoParser from "./VideoParser"
export default class ArtistParser {
public static parse(data: any, artistId: string): ArtistFull {
@ -28,7 +30,19 @@ export default class ArtistParser {
traverseList(data, "musicCarouselShelfRenderer")
?.at(0)
?.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

View File

@ -1,4 +1,4 @@
import { VideoDetailed, VideoFull } from "../schemas"
import { ArtistBasic, VideoDetailed, VideoFull } from "../schemas"
import checkType from "../utils/checkType"
import traverse from "../utils/traverse"
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 {
const flexColumns = traverseList(item, "flexColumns")
const videoId =

View File

@ -94,17 +94,10 @@ export const ArtistFull = z.object({
type: z.literal("ARTIST"),
thumbnails: z.array(ThumbnailFull),
description: z.string(),
topSongs: z.array(
z.object({
type: z.literal("SONG"),
videoId: z.string(),
name: z.string(),
artists: z.array(ArtistBasic),
album: AlbumBasic,
thumbnails: z.array(ThumbnailFull)
})
),
topAlbums: z.array(AlbumDetailed)
topSongs: z.array(SongDetailed.omit({ duration: true })),
topAlbums: z.array(AlbumDetailed),
topSingles: z.array(AlbumDetailed),
topVideos: z.array(VideoDetailed.omit({ duration: true }))
})
export type AlbumFull = z.infer<typeof AlbumFull>