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#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)

View File

@ -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">[]
} }
``` ```

View File

@ -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)

View File

@ -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",

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

View File

@ -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

View File

@ -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 =

View File

@ -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>