Using jest for testing instead of doing it manually
This commit is contained in:
parent
75d85764c3
commit
2154dc67ab
|
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
["@babel/preset-env", { targets: { node: "current" } }],
|
||||
"@babel/preset-typescript"
|
||||
]
|
||||
}
|
||||
|
|
@ -10,12 +10,21 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/zS1L3NT/ts-npm-ytmusic-api"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.25.0",
|
||||
"jest": "^27.4.7",
|
||||
"tough-cookie": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.0",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/preset-typescript": "^7.16.7",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/tough-cookie": "^4.0.1",
|
||||
"babel-jest": "^27.4.6",
|
||||
"typescript": "^4.5.5",
|
||||
"validate-any": "^1.2.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export default class YTMusic {
|
|||
}
|
||||
|
||||
for (const cookieString of cookieStrings) {
|
||||
const cookie = Cookie.parse(cookieString)
|
||||
const cookie = Cookie.parse(`${cookieString}`)
|
||||
if (!cookie) return
|
||||
|
||||
this.cookiejar.setCookieSync(cookie, res.config.baseURL)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,337 @@
|
|||
import ObjectValidator from "validate-any/dist/validators/ObjectValidator"
|
||||
import Validator from "validate-any/dist/classes/Validator"
|
||||
import YTMusic, {
|
||||
AlbumBasic,
|
||||
AlbumDetailed,
|
||||
AlbumFull,
|
||||
ArtistBasic,
|
||||
ArtistDetailed,
|
||||
ArtistFull,
|
||||
PlaylistFull,
|
||||
SongDetailed,
|
||||
SongFull,
|
||||
ThumbnailFull,
|
||||
VideoDetailed,
|
||||
VideoFull
|
||||
} from ".."
|
||||
import {
|
||||
BOOLEAN,
|
||||
iValidationError,
|
||||
LIST,
|
||||
NULL,
|
||||
NUMBER,
|
||||
OBJECT,
|
||||
OR,
|
||||
STRING,
|
||||
validate
|
||||
} from "validate-any"
|
||||
|
||||
//#region Interfaces
|
||||
const THUMBNAIL_FULL: ObjectValidator<ThumbnailFull> = OBJECT({
|
||||
url: STRING(),
|
||||
width: NUMBER(),
|
||||
height: NUMBER()
|
||||
})
|
||||
|
||||
const ARTIST_BASIC: ObjectValidator<ArtistBasic> = OBJECT({
|
||||
artistId: OR(STRING(), NULL()),
|
||||
name: STRING()
|
||||
})
|
||||
|
||||
const ALBUM_BASIC: ObjectValidator<AlbumBasic> = OBJECT({
|
||||
albumId: STRING(),
|
||||
name: STRING()
|
||||
})
|
||||
|
||||
const SONG_DETAILED: ObjectValidator<SongDetailed> = OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
album: ALBUM_BASIC,
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
const VIDEO_DETAILED: ObjectValidator<VideoDetailed> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
views: NUMBER(),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
const ARTIST_DETAILED: ObjectValidator<ArtistDetailed> = OBJECT({
|
||||
artistId: STRING(),
|
||||
name: STRING(),
|
||||
type: STRING("ARTIST"),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
const ALBUM_DETAILED: ObjectValidator<AlbumDetailed> = OBJECT({
|
||||
type: STRING("ALBUM"),
|
||||
albumId: STRING(),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
year: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
const SONG_FULL: ObjectValidator<SongFull> = OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: STRING(),
|
||||
formats: LIST(OBJECT()),
|
||||
adaptiveFormats: LIST(OBJECT())
|
||||
})
|
||||
|
||||
const VIDEO_FULL: ObjectValidator<VideoFull> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
views: NUMBER(),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: STRING(),
|
||||
unlisted: BOOLEAN(),
|
||||
familySafe: BOOLEAN(),
|
||||
paid: BOOLEAN(),
|
||||
tags: LIST(STRING())
|
||||
})
|
||||
|
||||
const ARTIST_FULL: ObjectValidator<ArtistFull> = OBJECT({
|
||||
artistId: STRING(),
|
||||
name: STRING(),
|
||||
type: STRING("ARTIST"),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: OR(STRING(), NULL()),
|
||||
subscribers: NUMBER(),
|
||||
topSongs: LIST(
|
||||
OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
album: ALBUM_BASIC,
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
),
|
||||
topAlbums: LIST(ALBUM_DETAILED)
|
||||
})
|
||||
|
||||
const ALBUM_FULL: ObjectValidator<AlbumFull> = OBJECT({
|
||||
type: STRING("ALBUM"),
|
||||
albumId: STRING(),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
year: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: OR(STRING(), NULL()),
|
||||
songs: LIST(SONG_DETAILED)
|
||||
})
|
||||
|
||||
const PLAYLIST_DETAILED: ObjectValidator<PlaylistFull> = OBJECT({
|
||||
type: STRING("PLAYLIST"),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artist: ARTIST_BASIC,
|
||||
videoCount: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
const PLAYLIST_VIDEO: ObjectValidator<Omit<VideoDetailed, "views">> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
//#endregion
|
||||
|
||||
const issues: iValidationError[][] = []
|
||||
const queries = ["Lilac", "Weekend", "Eill", "Eminem", "Lisa Hannigan"]
|
||||
const _expect = (data: any, validator: Validator<any>) => {
|
||||
const { errors } = validate(data, validator)
|
||||
if (errors.length > 0) {
|
||||
issues.push(errors)
|
||||
}
|
||||
|
||||
expect(errors.length).toBe(0)
|
||||
}
|
||||
|
||||
const ytmusic = new YTMusic()
|
||||
|
||||
beforeAll(() => ytmusic.initialize())
|
||||
|
||||
queries.forEach(query => {
|
||||
describe("Query: " + query, () => {
|
||||
test("Search Songs", done => {
|
||||
ytmusic
|
||||
.search(query, "SONG")
|
||||
.then(songs => {
|
||||
_expect(songs, LIST(SONG_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Search Videos", done => {
|
||||
ytmusic
|
||||
.search(query, "VIDEO")
|
||||
.then(videos => {
|
||||
_expect(videos, LIST(VIDEO_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Search Artists", done => {
|
||||
ytmusic
|
||||
.search(query, "ARTIST")
|
||||
.then(artists => {
|
||||
_expect(artists, LIST(ARTIST_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Search Albums", done => {
|
||||
ytmusic
|
||||
.search(query, "ALBUM")
|
||||
.then(albums => {
|
||||
_expect(albums, LIST(ALBUM_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Search Playlists", done => {
|
||||
ytmusic
|
||||
.search(query, "PLAYLIST")
|
||||
.then(playlists => {
|
||||
_expect(playlists, LIST(PLAYLIST_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Search All", done => {
|
||||
ytmusic
|
||||
.search(query)
|
||||
.then(results => {
|
||||
_expect(
|
||||
results,
|
||||
LIST(
|
||||
ALBUM_DETAILED,
|
||||
ARTIST_DETAILED,
|
||||
PLAYLIST_DETAILED,
|
||||
SONG_DETAILED,
|
||||
VIDEO_DETAILED
|
||||
)
|
||||
)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get details of the first song result", done => {
|
||||
ytmusic
|
||||
.search(query, "SONG")
|
||||
.then(songs => ytmusic.getSong(songs[0]!.videoId!))
|
||||
.then(song => {
|
||||
_expect(song, SONG_FULL)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get details of the first video result", done => {
|
||||
ytmusic
|
||||
.search(query, "VIDEO")
|
||||
.then(videos => ytmusic.getVideo(videos[0]!.videoId!))
|
||||
.then(video => {
|
||||
_expect(video, VIDEO_FULL)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get details of the first artist result", done => {
|
||||
ytmusic
|
||||
.search(query, "ARTIST")
|
||||
.then(artists => ytmusic.getArtist(artists[0]!.artistId!))
|
||||
.then(artist => {
|
||||
_expect(artist, ARTIST_FULL)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get the songs of the first artist result", done => {
|
||||
ytmusic
|
||||
.search(query, "ARTIST")
|
||||
.then(artists => ytmusic.getArtistSongs(artists[0]!.artistId!))
|
||||
.then(songs => {
|
||||
_expect(songs, LIST(SONG_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get the albums of the first artist result", done => {
|
||||
ytmusic
|
||||
.search(query, "ARTIST")
|
||||
.then(artists => ytmusic.getArtistAlbums(artists[0]!.artistId!))
|
||||
.then(albums => {
|
||||
_expect(albums, LIST(ALBUM_DETAILED))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get details of the first album result", done => {
|
||||
ytmusic
|
||||
.search(query, "ALBUM")
|
||||
.then(albums => ytmusic.getAlbum(albums[0]!.albumId!))
|
||||
.then(album => {
|
||||
_expect(album, ALBUM_FULL)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get details of the first playlist result", done => {
|
||||
ytmusic
|
||||
.search(query, "PLAYLIST")
|
||||
.then(playlists => ytmusic.getPlaylist(playlists[0]!.playlistId!))
|
||||
.then(playlist => {
|
||||
_expect(playlist, PLAYLIST_DETAILED)
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
|
||||
test("Get the videos of the first playlist result", done => {
|
||||
ytmusic
|
||||
.search(query, "PLAYLIST")
|
||||
.then(playlists => ytmusic.getPlaylistVideos(playlists[0]!.playlistId!))
|
||||
.then(videos => {
|
||||
_expect(videos, LIST(PLAYLIST_VIDEO))
|
||||
done()
|
||||
})
|
||||
.catch(done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterAll(() => console.log("Issues:", issues))
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
import Validator from "validate-any/build/classes/Validator"
|
||||
import YTMusic from "../YTMusic"
|
||||
import {
|
||||
ALBUM_DETAILED,
|
||||
ALBUM_FULL,
|
||||
ARTIST_DETAILED,
|
||||
ARTIST_FULL,
|
||||
PLAYLIST_DETAILED,
|
||||
PLAYLIST_VIDEO,
|
||||
SONG_DETAILED,
|
||||
SONG_FULL,
|
||||
VIDEO_DETAILED,
|
||||
VIDEO_FULL
|
||||
} from "./interfaces"
|
||||
import { LIST, validate } from "validate-any"
|
||||
|
||||
const queries = ["Lilac", "Weekend", "Yours Raiden", "Eminem", "Lisa Hannigan"]
|
||||
const ytmusic = new YTMusic()
|
||||
|
||||
ytmusic.initialize().then(() =>
|
||||
queries.forEach(async query => {
|
||||
const [songs, videos, artists, albums, playlists, results] = await Promise.all([
|
||||
ytmusic.search(query, "SONG"),
|
||||
ytmusic.search(query, "VIDEO"),
|
||||
ytmusic.search(query, "ARTIST"),
|
||||
ytmusic.search(query, "ALBUM"),
|
||||
ytmusic.search(query, "PLAYLIST"),
|
||||
ytmusic.search(query)
|
||||
])
|
||||
|
||||
const [song, video, artist, artistSongs, artistAlbums, album, playlist, playlistVideos] =
|
||||
await Promise.all([
|
||||
ytmusic.getSong(songs[0].videoId!),
|
||||
ytmusic.getVideo(videos[0].videoId!),
|
||||
ytmusic.getArtist(artists[0].artistId),
|
||||
ytmusic.getArtistSongs(artists[0].artistId),
|
||||
ytmusic.getArtistAlbums(artists[0].artistId),
|
||||
ytmusic.getAlbum(albums[0].albumId),
|
||||
ytmusic.getPlaylist(playlists[0].playlistId),
|
||||
ytmusic.getPlaylistVideos(playlists[0].playlistId)
|
||||
])
|
||||
|
||||
const tests: [any, Validator<any>][] = [
|
||||
[songs, LIST(SONG_DETAILED)],
|
||||
[videos, LIST(VIDEO_DETAILED)],
|
||||
[artists, LIST(ARTIST_DETAILED)],
|
||||
[albums, LIST(ALBUM_DETAILED)],
|
||||
[playlists, LIST(PLAYLIST_DETAILED)],
|
||||
[
|
||||
results,
|
||||
LIST(
|
||||
ALBUM_DETAILED,
|
||||
ARTIST_DETAILED,
|
||||
PLAYLIST_DETAILED,
|
||||
SONG_DETAILED,
|
||||
VIDEO_DETAILED
|
||||
)
|
||||
],
|
||||
[song, SONG_FULL],
|
||||
[video, VIDEO_FULL],
|
||||
[artist, ARTIST_FULL],
|
||||
[artistSongs, LIST(SONG_DETAILED)],
|
||||
[artistAlbums, LIST(ALBUM_DETAILED)],
|
||||
[album, ALBUM_FULL],
|
||||
[playlist, PLAYLIST_DETAILED],
|
||||
[playlistVideos, LIST(PLAYLIST_VIDEO)]
|
||||
]
|
||||
|
||||
for (const [value, validator] of tests) {
|
||||
const result = validate(value, validator)
|
||||
if (!result.success) {
|
||||
console.log(JSON.stringify(value))
|
||||
console.log(validator.formatSchema())
|
||||
console.log(result.errors)
|
||||
process.exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Valid 🎉 - ${query}`)
|
||||
})
|
||||
)
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
import ObjectValidator from "validate-any/build/validators/ObjectValidator"
|
||||
import {
|
||||
AlbumBasic,
|
||||
AlbumDetailed,
|
||||
AlbumFull,
|
||||
ArtistBasic,
|
||||
ArtistDetailed,
|
||||
ArtistFull,
|
||||
PlaylistFull,
|
||||
SongDetailed,
|
||||
SongFull,
|
||||
ThumbnailFull,
|
||||
VideoDetailed,
|
||||
VideoFull
|
||||
} from "../index"
|
||||
import { BOOLEAN, LIST, NULL, NUMBER, OBJECT, OR, STRING } from "validate-any"
|
||||
|
||||
export const THUMBNAIL_FULL: ObjectValidator<ThumbnailFull> = OBJECT({
|
||||
url: STRING(),
|
||||
width: NUMBER(),
|
||||
height: NUMBER()
|
||||
})
|
||||
|
||||
export const ARTIST_BASIC: ObjectValidator<ArtistBasic> = OBJECT({
|
||||
artistId: OR(STRING(), NULL()),
|
||||
name: STRING()
|
||||
})
|
||||
|
||||
export const ALBUM_BASIC: ObjectValidator<AlbumBasic> = OBJECT({
|
||||
albumId: STRING(),
|
||||
name: STRING()
|
||||
})
|
||||
|
||||
export const SONG_DETAILED: ObjectValidator<SongDetailed> = OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
album: ALBUM_BASIC,
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
export const VIDEO_DETAILED: ObjectValidator<VideoDetailed> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
views: NUMBER(),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
export const ARTIST_DETAILED: ObjectValidator<ArtistDetailed> = OBJECT({
|
||||
artistId: STRING(),
|
||||
name: STRING(),
|
||||
type: STRING("ARTIST"),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
export const ALBUM_DETAILED: ObjectValidator<AlbumDetailed> = OBJECT({
|
||||
type: STRING("ALBUM"),
|
||||
albumId: STRING(),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
year: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
export const SONG_FULL: ObjectValidator<SongFull> = OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: STRING(),
|
||||
formats: LIST(OBJECT()),
|
||||
adaptiveFormats: LIST(OBJECT())
|
||||
})
|
||||
|
||||
export const VIDEO_FULL: ObjectValidator<VideoFull> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
views: NUMBER(),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: STRING(),
|
||||
unlisted: BOOLEAN(),
|
||||
familySafe: BOOLEAN(),
|
||||
paid: BOOLEAN(),
|
||||
tags: LIST(STRING())
|
||||
})
|
||||
|
||||
export const ARTIST_FULL: ObjectValidator<ArtistFull> = OBJECT({
|
||||
artistId: STRING(),
|
||||
name: STRING(),
|
||||
type: STRING("ARTIST"),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: OR(STRING(), NULL()),
|
||||
subscribers: NUMBER(),
|
||||
topSongs: LIST(
|
||||
OBJECT({
|
||||
type: STRING("SONG"),
|
||||
videoId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
album: ALBUM_BASIC,
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
),
|
||||
topAlbums: LIST(ALBUM_DETAILED)
|
||||
})
|
||||
|
||||
export const ALBUM_FULL: ObjectValidator<AlbumFull> = OBJECT({
|
||||
type: STRING("ALBUM"),
|
||||
albumId: STRING(),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
year: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL),
|
||||
description: OR(STRING(), NULL()),
|
||||
songs: LIST(SONG_DETAILED)
|
||||
})
|
||||
|
||||
export const PLAYLIST_DETAILED: ObjectValidator<PlaylistFull> = OBJECT({
|
||||
type: STRING("PLAYLIST"),
|
||||
playlistId: STRING(),
|
||||
name: STRING(),
|
||||
artist: ARTIST_BASIC,
|
||||
videoCount: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
||||
export const PLAYLIST_VIDEO: ObjectValidator<Omit<VideoDetailed, "views">> = OBJECT({
|
||||
type: STRING("VIDEO"),
|
||||
videoId: OR(STRING(), NULL()),
|
||||
name: STRING(),
|
||||
artists: LIST(ARTIST_BASIC),
|
||||
duration: NUMBER(),
|
||||
thumbnails: LIST(THUMBNAIL_FULL)
|
||||
})
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import YTMusic from "../YTMusic"
|
||||
|
||||
const ytmusic = new YTMusic()
|
||||
ytmusic.initialize().then(() => {
|
||||
ytmusic.search("Lilac", "SONG").then(res => {
|
||||
ytmusic.getSong(res.find(r => !!r.videoId)!.videoId!).then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
const traverse = (data: any, keys: string, single = false) => {
|
||||
const again = (data: any, key: string): any => {
|
||||
var res = []
|
||||
|
||||
data.hasOwnProperty(key) && res.push(data[key])
|
||||
if (single && data.hasOwnProperty(key)) {
|
||||
return res.shift()
|
||||
}
|
||||
|
||||
if (data instanceof Array) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
res = res.concat(again(data[i], key))
|
||||
}
|
||||
} else if (data instanceof Object) {
|
||||
const c = Object.keys(data)
|
||||
if (c.length > 0) {
|
||||
for (let i = 0; i < c.length; i++) {
|
||||
res = res.concat(again(data[c[i]], key))
|
||||
}
|
||||
}
|
||||
}
|
||||
return res.length == 1 ? res.shift() : res
|
||||
}
|
||||
|
||||
let z = keys.split(":"),
|
||||
value = data
|
||||
for (let i = 0; i < z.length; i++) {
|
||||
value = again(value, z[i])
|
||||
}
|
||||
console.log(value)
|
||||
}
|
||||
|
||||
traverse(require("./data.json"), "playNavigationEndpoint:videoId")
|
||||
|
||||
export default {}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
const traverse = (data: any, keys: string[], single: boolean = false) => {
|
||||
const again = (data: any, key: string): any => {
|
||||
let res = []
|
||||
|
||||
if (data instanceof Object && key in data) {
|
||||
res.push(data[key])
|
||||
}
|
||||
|
||||
if (data instanceof Array) {
|
||||
res.push(...data.map(v => again(v, key)).flat())
|
||||
} else if (data instanceof Object) {
|
||||
res.push(
|
||||
...Object.keys(data)
|
||||
.map(k => again(data[k], key))
|
||||
.flat()
|
||||
)
|
||||
}
|
||||
|
||||
return res.length === 1 ? res[0] : res
|
||||
}
|
||||
|
||||
let value = data
|
||||
for (const key of keys) {
|
||||
value = again(value, key)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
traverse(require("./data.json")[0], ["playNavigationEndpoint", "videoId"], true)
|
||||
|
||||
export default {}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
const traverse = (data: any, ...keys: string[]) => {
|
||||
const again = (data: any, key: string): any => {
|
||||
let res = []
|
||||
|
||||
if (data instanceof Object && key in data) {
|
||||
res.push(data[key])
|
||||
}
|
||||
|
||||
if (data instanceof Array) {
|
||||
res.push(...data.map(v => again(v, key)).flat())
|
||||
} else if (data instanceof Object) {
|
||||
res.push(
|
||||
...Object.keys(data)
|
||||
.map(k => again(data[k], key))
|
||||
.flat()
|
||||
)
|
||||
}
|
||||
|
||||
return res.length === 1 ? res[0] : res
|
||||
}
|
||||
|
||||
let value = data
|
||||
for (const key of keys) {
|
||||
value = again(value, key)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
export default traverse
|
||||
Loading…
Reference in New Issue