UNPKG

lrclib-api

Version:

The unofficial lrclib.net library for JS and TS

253 lines (242 loc) 8.82 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/errors/NotFound.ts var NotFoundError = class extends Error { constructor() { super("Track was not found"); } }; var NoResultError = class extends Error { constructor() { super("No result was found"); } }; // src/errors/RequestError.ts var RequestError = class extends Error { constructor(error) { super("Request error " + error); } }; // src/utils.ts function parseLocalLyrics(lyrics) { const lines = lyrics.replace(/\[[a-zA-Z]+:.+\]/g, "").trim().split("\n"); const syncedTimestamp = /\[([0-9:.]+)\]/; const unsynced = []; const synced = []; lines.forEach((line) => { const syncMatch = line.match(syncedTimestamp); if (syncMatch) { const startTime = parseTime(syncMatch[1]); const text = line.replace(syncedTimestamp, "").trim(); if (text) { synced.push({ text, startTime }); } } else { const text = line.trim(); if (text) { unsynced.push({ text }); } } }); return { synced: synced.length > 0 ? synced : null, unsynced }; } function parseTime(time) { const [minutes, seconds] = time.split(":").map(Number); return minutes * 60 + seconds; } // src/lyrics.ts var Client = class { /** * Creates a request client to api * * Example Usage; * ```typescript * const client = new Client(); * * client.findLyrics({ track_name: "The Chain", artist_name: "Fleetwood Mac" }).then(console.log); * ``` * * @notigorwastaken: I'm still working on it. * * @param options - An optional object containing Client Options * - `url`: The base URL, e.g. you can set up a custom url that uses another lrclib.net instance * - `key`: The token used to publish lyrics to the api. [click here for more info](https://lrclib.net/docs) */ constructor(options) { this._url = "https://lrclib.net/api"; this._url = (options == null ? void 0 : options.url) || this._url; this._key = options == null ? void 0 : options.key; } request(path, options) { return __async(this, null, function* () { return yield fetch(this._url + path, options); }); } /** * Sends a request to the lyrics search API at https://lrclib.net/api/search. * * Example Usage: * ```typescript * const search = await searchLyrics({ query: "The Chain" }); * ``` * * @param info - An object containing search parameters: * - `query`: The search term (conditional | e.g., song title or lyrics fragment). * - `track_name`: The name of the track (conditional). * - `artist_name`: The artist's name (optional). * - `duration`: The song duration in milliseconds (optional). * * @returns A promise that resolves to an array of {@link FindLyricsResponse | FindLyricsResponse[]}. */ searchLyrics(info, options) { return __async(this, null, function* () { const baseURL = "/search"; const params = { q: info.query || "", track_name: info.track_name || "", artist_name: info.artist_name || "", duration: info.duration ? info.duration / 1e3 : "" }; const finalURL = `${baseURL}?${Object.entries(params).filter(([_, value]) => value !== void 0 && value !== "").map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&")}`; const response = yield this.request(finalURL, options); if (!response.ok) { throw new RequestError(); } const body = yield response.json(); if (!body) { throw new NoResultError(); } return body; }); } /** * Finds lyrics for a given track using the API at https://lrclib.net/api/get. * * Example Usage: * ```typescript * const lyrics = await findLyrics({ track_name: "The Chain", artist_name: "Fleetwood Mac" }); * ``` * * @param info - An object containing query parameters: * - `id`: The unique identifier of the track (conditional). * - `track_name`: The name of the track (conditional). * - `artist_name`: The artist's name (conditional). * - `album_name`: The album's name (optional). * - `duration`: The song duration in milliseconds (optional). * * @returns A promise that resolves to a {@link FindLyricsResponse | FindLyricsResponse} object containing the track's lyrics. * @throws Will throw an error if the request fails or the track is not found. */ findLyrics(info, options) { return __async(this, null, function* () { const parseID = info.id ? `/${info.id}` : "?"; const baseURL = "/get" + parseID; const durr = (info == null ? void 0 : info.duration) ? info.duration / 1e3 : void 0; const params = { track_name: info.track_name || "", artist_name: info.artist_name || "", album_name: info.album_name || "", duration: durr || "" }; const finalURL = `${baseURL}${Object.entries(params).filter(([_, value]) => value !== void 0 && value !== "").map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join("&")}`; const response = yield this.request(finalURL, options); if (!response.ok && response.status === 404) { throw new NotFoundError(); } else if (!response.ok && response.status !== 200) { throw new RequestError(response.statusText); } const body = yield response.json(); return body; }); } /** * Retrieves unsynchronized (plain) lyrics for a given track. * * Example Usage: * ```typescript * const unsyncedLyrics = await getUnsynced({ track_name: "The Chain", artist_name: "Fleetwood Mac" }); * ``` * * @param info - An object containing query parameters: * - `id`: The unique identifier of the track (conditional). * - `track_name`: The name of the track (conditional). * - `artist_name`: The artist's name (conditional). * - `album_name`: The album's name (optional). * - `duration`: The song duration in milliseconds (optional). * * @returns A promise that resolves to an array of {@link LyricLine | LyricLine[]} objects * containing unsynchronized lyrics or `null` if no lyrics are found. */ getUnsynced(info) { return __async(this, null, function* () { try { const body = yield this.findLyrics(info); if ("error" in body) return null; const unsyncedLyrics = body == null ? void 0 : body.plainLyrics; const isInstrumental = body.instrumental; if (isInstrumental) return [{ text: "[Instrumental]" }]; if (!unsyncedLyrics) return null; return parseLocalLyrics(unsyncedLyrics).unsynced; } catch (e) { console.error(e); return null; } }); } /** * Retrieves synchronized (timed) lyrics for a given track. * * Example Usage: * ```typescript * const syncedLyrics = await getSynced({ track_name: "The Chain", artist_name: "Fleetwood Mac" }); * ``` * * @param info - An object containing query parameters: * - `id`: The unique identifier of the track (conditional). * - `track_name`: The name of the track (conditional). * - `artist_name`: The artist's name (conditional). * - `album_name`: The album's name (optional). * - `duration`: The song duration in milliseconds (optional). * * @returns A promise that resolves to an array of {@link LyricLine | LyricLine[]} objects * containing synchronized lyrics or `null` if no lyrics are found. */ getSynced(info) { return __async(this, null, function* () { try { const body = yield this.findLyrics(info); const syncedLyrics = body == null ? void 0 : body.syncedLyrics; const isInstrumental = body.instrumental; if (isInstrumental) return [{ text: "[Instrumental]" }]; if (!syncedLyrics) return null; return parseLocalLyrics(syncedLyrics).synced; } catch (e) { console.error(e); return null; } }); } }; exports.Client = Client; exports.NoResultError = NoResultError; exports.NotFoundError = NotFoundError; exports.RequestError = RequestError; exports.parseLocalLyrics = parseLocalLyrics; exports.parseTime = parseTime; //# sourceMappingURL=index.js.map