diff --git a/docs/references/interfaces/AlbumDetailed.md b/docs/references/interfaces/AlbumDetailed.md index dc6b265..25d12b7 100644 --- a/docs/references/interfaces/AlbumDetailed.md +++ b/docs/references/interfaces/AlbumDetailed.md @@ -30,6 +30,8 @@ interface AlbumDetailed { [ArtistFull#topAlbums](./ArtistFull.html) +[ArtistFull#topSingles](./ArtistFull.html) + [SearchResult](../types/SearchResult.html) [YTMusic#searchAlbums](../ytmusic/searchAlbums.html) diff --git a/docs/references/interfaces/ArtistFull.md b/docs/references/interfaces/ArtistFull.md index fd849ee..a2ee61d 100644 --- a/docs/references/interfaces/ArtistFull.md +++ b/docs/references/interfaces/ArtistFull.md @@ -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[] topAlbums: AlbumDetailed[] + topSingles: AlbumDetailed[] + topVideos: Omit[] } ``` diff --git a/docs/references/interfaces/VideoDetailed.md b/docs/references/interfaces/VideoDetailed.md index c833507..740448c 100644 --- a/docs/references/interfaces/VideoDetailed.md +++ b/docs/references/interfaces/VideoDetailed.md @@ -26,6 +26,8 @@ interface VideoDetailed { ## Usages +[ArtistFull#topVideos](../types/ArtistFull.html) + [SearchResult](../types/SearchResult.html) [YTMusic#searchVideos](../ytmusic/searchVideos.html) diff --git a/package.json b/package.json index 612e149..094da7c 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/parsers/AlbumParser.ts b/src/parsers/AlbumParser.ts index ccada83..7250bbc 100644 --- a/src/parsers/AlbumParser.ts +++ b/src/parsers/AlbumParser.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( { type: "ALBUM", diff --git a/src/parsers/ArtistParser.ts b/src/parsers/ArtistParser.ts index a6e3671..ceb78d5 100644 --- a/src/parsers/ArtistParser.ts +++ b/src/parsers/ArtistParser.ts @@ -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 diff --git a/src/parsers/VideoParser.ts b/src/parsers/VideoParser.ts index c5ee6d4..fe35d20 100644 --- a/src/parsers/VideoParser.ts +++ b/src/parsers/VideoParser.ts @@ -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 { + 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 = diff --git a/src/schemas.ts b/src/schemas.ts index 47f3aa5..24c9522 100644 --- a/src/schemas.ts +++ b/src/schemas.ts @@ -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