UNPKG

kazagumo-spotify

Version:
206 lines (205 loc) 10.8 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.KazagumoPlugin = void 0; const kazagumo_1 = require("kazagumo"); const RequestManager_1 = require("./RequestManager"); const undici_1 = __importDefault(require("undici")); const REGEX = /(?:https:\/\/open\.spotify\.com\/|spotify:)(?:.+)?(track|playlist|album|artist)[\/:]([A-Za-z0-9]+)/; const SHORT_REGEX = /(?:https:\/\/spotify\.link)\/([A-Za-z0-9]+)/; const ISRC_REGEX = /^[A-Z]{2}-?\w{3}-?\d{2}-?\d{5}$/; class KazagumoPlugin extends kazagumo_1.KazagumoPlugin { constructor(spotifyOptions) { super(); this.token = ''; this.undici = undici_1.default; this.triesLeft = 2; this.options = spotifyOptions; this.requestManager = new RequestManager_1.RequestManager(spotifyOptions); if (spotifyOptions.lavalinkPluginTries !== undefined) this.triesLeft = spotifyOptions.lavalinkPluginTries; this.methods = { track: this.getTrack.bind(this), album: this.getAlbum.bind(this), artist: this.getArtist.bind(this), playlist: this.getPlaylist.bind(this), }; this.kazagumo = null; this._search = null; } load(kazagumo) { this.kazagumo = kazagumo; this._search = kazagumo.search.bind(kazagumo); kazagumo.search = this.search.bind(this); } search(query, options) { var _a; return __awaiter(this, void 0, void 0, function* () { if (!this.kazagumo || !this._search) throw new kazagumo_1.KazagumoError(1, 'kazagumo-spotify is not loaded yet.'); if (!query) throw new kazagumo_1.KazagumoError(3, 'Query is required'); let [, type, id] = REGEX.exec(query) || []; const isUrl = /^https?:\/\//.test(query); if (SHORT_REGEX.test(query)) { const res = yield this.undici.request(query, { method: 'HEAD' }); query = String(res.headers.location); } (REGEX.exec(query) || []).map((_, i) => i === 1 ? (type = _) : i === 2 ? (id = _) : null); if (ISRC_REGEX.test(query)) { const res = yield this.searchTrack(`isrc:${query}`, options === null || options === void 0 ? void 0 : options.requester); const a = this.buildSearch(undefined, res.tracks, 'TRACK'); return a; } if (type in this.methods) { try { if (this.triesLeft > 0) { const lavalinkResult = yield this._search(query, options); if (lavalinkResult.tracks.length > 0) return lavalinkResult; this.triesLeft--; } const _function = this.methods[type]; const result = yield _function(id, options === null || options === void 0 ? void 0 : options.requester); const loadType = type === 'track' ? 'TRACK' : 'PLAYLIST'; const playlistName = (_a = result.name) !== null && _a !== void 0 ? _a : undefined; const tracks = result.tracks.filter(this.filterNullOrUndefined); return this.buildSearch(playlistName, tracks, loadType); } catch (e) { return this.buildSearch(undefined, [], 'SEARCH'); } } else if ((options === null || options === void 0 ? void 0 : options.engine) === 'spotify' && !isUrl) { const result = yield this.searchTrack(query, options === null || options === void 0 ? void 0 : options.requester); return this.buildSearch(undefined, result.tracks, 'SEARCH'); } return this._search(query, options); }); } buildSearch(playlistName, tracks = [], type) { return { playlistName, tracks, type: type !== null && type !== void 0 ? type : 'TRACK', }; } searchTrack(query, requester) { var _a; return __awaiter(this, void 0, void 0, function* () { const limit = this.options.searchLimit && this.options.searchLimit > 0 && this.options.searchLimit < 50 ? this.options.searchLimit : 10; const tracks = yield this.requestManager.makeRequest(`/search?q=${decodeURIComponent(query)}&type=track&limit=${limit}&market=${(_a = this.options.searchMarket) !== null && _a !== void 0 ? _a : 'US'}`); return { tracks: tracks.tracks.items.map((track) => this.buildKazagumoTrack(track, requester)), }; }); } getTrack(id, requester) { return __awaiter(this, void 0, void 0, function* () { const track = yield this.requestManager.makeRequest(`/tracks/${id}`); return { tracks: [this.buildKazagumoTrack(track, requester)] }; }); } getAlbum(id, requester) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const album = yield this.requestManager.makeRequest(`/albums/${id}?market=${(_a = this.options.searchMarket) !== null && _a !== void 0 ? _a : 'US'}`); const tracks = album.tracks.items .filter(this.filterNullOrUndefined) .map((track) => { var _a; return this.buildKazagumoTrack(track, requester, (_a = album.images[0]) === null || _a === void 0 ? void 0 : _a.url); }); if (album && tracks.length) { let next = album.tracks.next; let page = 1; while (next && (!this.options.playlistPageLimit ? true : (_b = page < this.options.playlistPageLimit) !== null && _b !== void 0 ? _b : 1)) { const nextTracks = yield this.requestManager.makeRequest(next !== null && next !== void 0 ? next : '', true); page++; if (nextTracks.items.length) { next = nextTracks.next; tracks.push(...nextTracks.items .filter(this.filterTrackNullOrUndefined) .filter((a) => a.track) .map((track) => { var _a; return this.buildKazagumoTrack(track.track, requester, (_a = album.images[0]) === null || _a === void 0 ? void 0 : _a.url); })); } } } return { tracks, name: album.name }; }); } getArtist(id, requester) { var _a; return __awaiter(this, void 0, void 0, function* () { const artist = yield this.requestManager.makeRequest(`/artists/${id}`); const fetchedTracks = yield this.requestManager.makeRequest(`/artists/${id}/top-tracks?market=${(_a = this.options.searchMarket) !== null && _a !== void 0 ? _a : 'US'}`); const tracks = fetchedTracks.tracks .filter(this.filterNullOrUndefined) .map((track) => this.buildKazagumoTrack(track, requester)); return { tracks, name: artist.name }; }); } getPlaylist(id, requester) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const playlist = yield this.requestManager.makeRequest(`/playlists/${id}?market=${(_a = this.options.searchMarket) !== null && _a !== void 0 ? _a : 'US'}`); const tracks = playlist.tracks.items .filter(this.filterTrackNullOrUndefined) .map((track) => this.buildKazagumoTrack(track.track, requester)); if (playlist && tracks.length) { let next = playlist.tracks.next; let page = 1; while (next && (!this.options.playlistPageLimit ? true : (_b = page < this.options.playlistPageLimit) !== null && _b !== void 0 ? _b : 1)) { const nextTracks = yield this.requestManager.makeRequest(next !== null && next !== void 0 ? next : '', true); page++; if (nextTracks.items.length) { next = nextTracks.next; tracks.push(...nextTracks.items .filter(this.filterTrackNullOrUndefined) .filter((a) => a.track) .map((track) => this.buildKazagumoTrack(track.track, requester))); } } } return { tracks, name: playlist.name }; }); } filterNullOrUndefined(obj) { return obj !== undefined && obj !== null; } filterTrackNullOrUndefined(obj) { return obj !== undefined && obj !== null && obj.track; } buildKazagumoTrack(spotifyTrack, requester, thumbnail) { var _a, _b; return new kazagumo_1.KazagumoTrack({ encoded: '', pluginInfo: { name: 'kazagumo@kazagumo-spotify', }, info: { sourceName: 'spotify', identifier: spotifyTrack.id, isSeekable: true, author: spotifyTrack.artists[0] ? spotifyTrack.artists[0].name : 'Unknown', length: spotifyTrack.duration_ms, isStream: false, position: 0, title: spotifyTrack.name, uri: `https://open.spotify.com/track/${spotifyTrack.id}`, artworkUrl: thumbnail ? thumbnail : (_b = (_a = spotifyTrack.album) === null || _a === void 0 ? void 0 : _a.images[0]) === null || _b === void 0 ? void 0 : _b.url, }, }, requester).setKazagumo(this.kazagumo); } } exports.KazagumoPlugin = KazagumoPlugin;