Created
May 5, 2025 11:47
-
-
Save Sv443/9b58dd12107e7037639b63685125fcf9 to your computer and use it in GitHub Desktop.
TypeScript function and types for fetching the info of an album given its name and the artist's name. Also allows to fetch the artwork in its highest available resolution (generally around 1500x1500).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type ITunesAlbumObj = { | |
wrapperType: "collection" | (string & {}); | |
collectionType: "Album" | (string & {}); | |
artistId: number; | |
collectionId: number; | |
artistName: string; | |
collectionName: string; | |
collectionCensoredName: string; | |
artistViewUrl: `https://music.apple.com/us/artist/${string}/${number}?uo=${number}`; | |
collectionViewUrl: `https://music.apple.com/us/album/${string}/${number}?uo=${number}`; | |
artworkUrl60: `https://${string}.mzstatic.com/image/thumb/${string}/${number}x${number}bb.jpg`; | |
artworkUrl100: `https://${string}.mzstatic.com/image/thumb/${string}/${number}x${number}bb.jpg`; | |
collectionPrice: number; | |
collectionExplicitness: "explicit" | "notExplicit" | "cleaned" | (string & {}); | |
contentAdvisoryRating?: "Explicit" | "Clean" | (string & {}); | |
trackCount: number; | |
copyright: string; | |
country: "USA" | (string & {}); | |
currency: "USD" | (string & {}); | |
releaseDate: `${number}-${number}-${number}T${number}:${number}:${number}Z`; | |
primaryGenreName: string; | |
}; | |
type CustomProps = { | |
/** | |
* Returns the URL of the album artwork in the given resolution. | |
* If not found, the API will return the image in the largest available resolution. | |
*/ | |
getArtwork: (resolution: number) => `https://${string}.mzstatic.com/image/thumb/${string}/${number}x${number}bb.jpg`; | |
} | |
type ITunesAPIResponse = { | |
resultCount: number; | |
results: ITunesAlbumObj[]; | |
}; | |
async function fetchITunesAlbumInfo(artist: string, album: string): Promise<Array<ITunesAlbumObj & CustomProps>> { | |
try { | |
const res = await fetch(`https://itunes.apple.com/search?country=us&limit=5&entity=album&term=${encodeURIComponent(`${artist} ${album}`)}`); | |
const json = await res.json() as ITunesAPIResponse; | |
if(!res.ok) { | |
console.error("Couldn't fetch iTunes album info due to an error:", json); | |
return []; | |
} | |
if(!("resultCount" in json) || !("results" in json)) { | |
console.error("Couldn't parse iTunes album info due to an error:", json); | |
return []; | |
} | |
if(json.resultCount === 0) { | |
console.warn("No iTunes album info found for artist", artist, "and album", album); | |
return []; | |
} | |
return json.results | |
.filter((result) => { | |
if(!("collectionType" in result) || !("collectionName" in result) || !("artistName" in result) || !("collectionId" in result) || !("artworkUrl60" in result) || !("artworkUrl100" in result)) | |
return false; | |
return result.collectionType === "Album" && result.collectionName && result.artistName && result.collectionId && result.artworkUrl60 && result.artworkUrl100; | |
}) | |
.map((result) => ({ | |
...result, | |
getArtwork(res) { | |
return (result.artworkUrl60 ?? result.artworkUrl100).replace(/(60x60|100x100)/, `${res}x${res}`) as ReturnType<CustomProps["getArtwork"]>; | |
}, | |
})); | |
} | |
catch(err) { | |
console.error("Couldn't fetch iTunes album info due to an error:", err); | |
return []; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment