lrclib-api
Version:
The unofficial lrclib.net library for JS and TS
253 lines (249 loc) • 8.63 kB
JavaScript
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;
}
});
}
};
export {
Client,
NoResultError,
NotFoundError,
RequestError,
parseLocalLyrics,
parseTime
};
//# sourceMappingURL=index.mjs.map