### Basic Setup Example Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md A minimal example showing the basic setup for using the library, including installation and a simple search call. It also includes basic error handling. ```javascript # Install the library npm install music-lyrics # Basic usage const { search } = require('music-lyrics'); async function main() { try { const lyrics = await search('Bohemian Rhapsody', 'Queen'); console.log(lyrics); } catch (error) { console.error('Failed to fetch lyrics:', error); } } ``` -------------------------------- ### Install Music-Lyrics Package Source: https://github.com/gabrideiros/music-lyrics/blob/main/README.md Install the music-lyric package using npm. This is the first step before using the API. ```javascript npm i music-lyric ``` -------------------------------- ### Install music-lyrics with npm Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Install the library using npm. Ensure you are using the correct package name. ```bash npm install music-lyrics ``` -------------------------------- ### Install music-lyrics with yarn Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Install the library using yarn. Ensure you are using the correct package name. ```bash yarn add music-lyrics ``` -------------------------------- ### Async/Await Search Example Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Illustrates the asynchronous nature of the search function using async/await syntax for cleaner promise handling. This is the recommended way to use the function. ```javascript const { search } = require("music-lyrics"); async function getLyrics(title, artist) { try { const lyrics = await search(title, artist); return lyrics; } catch (error) { console.error("Error fetching lyrics:", error); return null; } } getLyrics("Hotel California", "Eagles").then(lyrics => { if (lyrics) { console.log(lyrics); } }); ``` -------------------------------- ### Install music-lyrics with pnpm Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Install the library using pnpm. Ensure you are using the correct package name. ```bash pnpm add music-lyrics ``` -------------------------------- ### Install Dependencies Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Lists the required peer dependencies for the music-lyrics library: cheerio and superagent. These are typically installed automatically with the library. ```bash npm list superagent cheerio ``` -------------------------------- ### Minimal music-lyrics search example Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md A basic example demonstrating how to search for lyrics of a song using the 'search' function and handle potential errors. ```javascript const lyrics = require('music-lyrics'); (async () => { try { const result = await lyrics.search('Bohemian Rhapsody'); console.log(result); } catch (error) { console.error('Failed to fetch lyrics'); } })(); ``` -------------------------------- ### Making HTTP GET Requests with Superagent Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Use Superagent to make GET requests and access the response body as text. Ensure Superagent is installed and imported. ```javascript const request = require('superagent'); // Making requests const rest = await request.get(url); // Response handling const text = rest.text; // Response body as string ``` -------------------------------- ### Async Function to Get Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/api-reference.md Demonstrates how to use the search function within an async function to retrieve lyrics, returning the content or null if an error occurs. ```javascript async function getLyrics(songTitle) { try { const content = await lyrics.search(songTitle); return content; } catch (err) { return null; } } ``` -------------------------------- ### Search for Lyrics using Music-Lyrics API Source: https://github.com/gabrideiros/music-lyrics/blob/main/README.md Demonstrates how to import and use the music-lyrics package to search for a specific song's lyrics. Includes basic error handling for unknown lyrics. ```javascript const lyrics = require("music-lyrics"); (async() => { try { const lyric = await lyrics.search('Watermelon Sugar'); console.log(lyric); } catch (error) { console.log("Unknow lyric."); } })() ``` -------------------------------- ### Basic Search Functionality Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Demonstrates the basic usage of the search function to find lyrics by title. Requires importing the search function. ```javascript const { search } = require("music-lyrics"); async function main() { const lyrics = await search("Bohemian Rhapsody"); console.log(lyrics); } main(); ``` -------------------------------- ### CommonJS Import Pattern Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Demonstrates the standard CommonJS import pattern for Node.js modules. This is how you typically include the library in your project. ```javascript const { search } = require('music-lyrics'); ``` -------------------------------- ### Calling the Search Function Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md This demonstrates the typical way to call the search function from user code after requiring the 'music-lyrics' package. It shows the awaited call to the search function with a song title. ```javascript const lyrics = require('music-lyrics'); await lyrics.search('Song Title'); // Function called directly ``` -------------------------------- ### Construct Google Search URL Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Constructs a Google Search URL by URL-encoding the song title and appending '+letra'. ```javascript const rest = await request.get(`https://www.google.com/search?q=${encodeURIComponent(title)}+letra`); ``` -------------------------------- ### Batch Processing of Lyrics Requests Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Demonstrates how to process multiple lyrics requests in a batch. This can be useful for fetching lyrics for a list of songs efficiently. ```javascript const songs = [ { title: 'Bohemian Rhapsody', artist: 'Queen' }, { title: 'Hotel California', artist: 'Eagles' } ]; async function processBatch() { for (const song of songs) { try { const lyrics = await search(song.title, song.artist); console.log(`--- ${song.title} by ${song.artist} --- ${lyrics} `); } catch (error) { console.error(`Error for ${song.title}:`, error); } } } processBatch(); ``` -------------------------------- ### Implement Caching for Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Demonstrates how to use NodeCache to cache lyrics search results for a specified duration (1 hour). This helps improve performance by reducing redundant network requests. ```javascript const NodeCache = require('node-cache'); const lyrics = require('music-lyrics'); // Cache for 1 hour (3600 seconds) const cache = new NodeCache({ stdTTL: 3600 }); async function getCachedLyrics(title) { const cached = cache.get(title); if (cached) return cached; const result = await lyrics.search(title); cache.set(title, result); return result; } ``` -------------------------------- ### Express.js Endpoint for Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Shows how to create an Express.js endpoint that uses the music-lyrics library to serve lyrics. This integrates the library into a web application. ```javascript const express = require('express'); const { search } = require('music-lyrics'); const app = express(); const port = 3000; app.get('/lyrics/:title/:artist', async (req, res) => { try { const { title, artist } = req.params; const lyrics = await search(title, artist); res.send(lyrics); } catch (error) { res.status(500).send('Error fetching lyrics'); } }); app.listen(port, () => { console.log(`Lyrics server listening at http://localhost:${port}`); }); ``` -------------------------------- ### Complete JavaScript Module Implementation Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md The entire library is contained within a single JavaScript module file. ```javascript const cheerio = require('cheerio'); const request = require('superagent'); module.exports = async function (title) { // Main search function implementation // ... async function find(link) { // Lyrics extraction for a single link // ... } function isLink(link) { // Link validation helper // ... } } ``` -------------------------------- ### Load HTML Response with Cheerio Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Parses the HTML response from Google Search using Cheerio to enable CSS selector queries. ```javascript const $ = cheerio.load(rest.text); ``` -------------------------------- ### Async Function for Fetching Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md This snippet demonstrates the use of async/await for making asynchronous network requests to fetch lyrics. It includes error handling for both the initial search and the subsequent lyrics fetching. ```javascript module.exports = async function (title) { try { // Get Google search results const rest = await request.get(googleUrl); // ... link processing ... // Fetch lyrics from website const value = await find(link); return value; } catch (error) { throw new Error("Error") } async function find(link) { try { const rest = await request.get(link); // ... extraction ... } catch (error) { throw new Error("Error") } } } ``` -------------------------------- ### Parallel Requests with Promise.allSettled Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Illustrates how to make parallel requests for lyrics using `Promise.allSettled`. This method is useful for handling multiple asynchronous operations where you want to know the outcome of each, regardless of success or failure. ```javascript const songs = [ { title: 'Bohemian Rhapsody', artist: 'Queen' }, { title: 'Stairway to Heaven', artist: 'Led Zeppelin' }, { title: 'Imagine', artist: 'John Lennon' } ]; async function fetchAllLyrics() { const promises = songs.map(song => search(song.title, song.artist)); const results = await Promise.allSettled(promises); results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`Successfully fetched lyrics for ${songs[index].title}: ${result.value} `); } else { console.error(`Failed to fetch lyrics for ${songs[index].title}: ${result.reason}`); } }); } fetchAllLyrics(); ``` -------------------------------- ### Loading HTML with Cheerio Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Use Cheerio to load an HTML string and query elements using CSS selectors. The loaded object provides a jQuery-like API. ```javascript const cheerio = require('cheerio'); const $ = cheerio.load(html); // CSS selector queries const element = $(selector); // Converting to string const html = element.toString(); ``` -------------------------------- ### Implement Rate Limiting for Searches Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Provides a class to manage rate limiting for lyrics searches, ensuring a minimum delay between requests to avoid Google Search rate limits. Usage involves creating an instance with a desired delay. ```javascript const lyrics = require('music-lyrics'); class RateLimitedLyricsSearch { constructor(delayMs = 1000) { this.delayMs = delayMs; this.lastRequestTime = 0; } async search(title) { const timeSinceLastRequest = Date.now() - this.lastRequestTime; const remainingDelay = Math.max(0, this.delayMs - timeSinceLastRequest); if (remainingDelay > 0) { await new Promise(resolve => setTimeout(resolve, remainingDelay)); } this.lastRequestTime = Date.now(); return lyrics.search(title); } } // Usage with 2-second delay between requests const limiter = new RateLimitedLyricsSearch(2000); const result1 = await limiter.search('Song 1'); const result2 = await limiter.search('Song 2'); // Waits at least 2 seconds ``` -------------------------------- ### Documentation Map Structure Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/README.md This snippet outlines the hierarchical structure of the project's documentation, indicating the primary files and their purposes. ```markdown README.md (this file) ├── Quick reference and overview ├── Link to API Reference ├── Link to Architecture & Module Structure ├── Link to Implementation Details ├── Link to Errors & Exception Handling └── Link to Integration Guide ``` -------------------------------- ### Module Hierarchy Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/architecture-and-module-structure.md Illustrates the hierarchical structure of the music-lyrics project's core modules. ```tree index.js (entry point) └── lib/search.js (core search implementation) ├── superagent (HTTP client for requests) └── cheerio (HTML parser for extraction) ``` -------------------------------- ### search(title: string): Promise Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/DOCUMENTATION-SUMMARY.txt Searches for song lyrics from multiple websites based on the provided song title. It returns a promise that resolves with the lyrics as a string. ```APIDOC ## search(title: string): Promise ### Description Searches for song lyrics from multiple websites based on the provided song title. It returns a promise that resolves with the lyrics as a string. ### Method search ### Parameters #### Path Parameters - **title** (string) - Required - The title of the song to search for. ### Return Value - **Promise** - A promise that resolves with the song lyrics as a string. ### Error Conditions - **Error** - Triggered when lyrics cannot be found or an issue occurs during the search process. ### Examples ```javascript // Example 1: Basic usage lyricsClient.search('Bohemian Rhapsody').then(lyrics => { console.log(lyrics); }).catch(error => { console.error('Error fetching lyrics:', error); }); // Example 2: Handling potential errors async function getLyrics(songTitle) { try { const lyrics = await lyricsClient.search(songTitle); return lyrics; } catch (error) { console.error(`Failed to get lyrics for ${songTitle}:`, error.message); return null; } } // Example 3: Using with a specific data source (if supported, though not detailed in source) // Note: The source does not specify how to target specific websites, so this is illustrative. // lyricsClient.search('Stairway to Heaven', { source: 'websiteA' }).then(...).catch(...); ``` -------------------------------- ### Data Flow for Fetching Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/architecture-and-module-structure.md Illustrates the sequence of operations from a user's search request to the final extraction of cleaned lyrics content. It highlights the use of external libraries for fetching and parsing. ```text User calls search(title) Create Google Search query: "{title} letra" Fetch Google results using superagent Parse HTML with Cheerio Extract all links from results Filter links against supported domains Use first valid link Fetch lyrics website using superagent Parse with Cheerio using source-specific CSS selector Extract lyrics content Remove HTML tags Return cleaned lyrics string ``` -------------------------------- ### Import music-lyrics in CommonJS Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Import the library using require in a CommonJS environment. The 'search' function is the primary export. ```javascript const lyrics = require('music-lyrics'); // lyrics.search is the only exported function console.log(typeof lyrics.search); // 'function' ``` -------------------------------- ### Parallel lyrics fetching with Promise.allSettled Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Fetch lyrics for multiple songs concurrently using Promise.allSettled for robust handling of both successful and failed requests. ```javascript const lyrics = require('music-lyrics'); async function fetchMultipleLyrics(songTitles) { const promises = songTitles.map(title => lyrics.search(title)); const results = await Promise.allSettled(promises); return results.map((result, index) => ({ song: songTitles[index], lyrics: result.status === 'fulfilled' ? result.value : null, error: result.status === 'rejected' ? result.reason.message : null })); } // Usage (async () => { const results = await fetchMultipleLyrics([ 'Stairway to Heaven', 'Like a Rolling Stone', 'A Day in the Life' ]); results.forEach(r => { if (r.lyrics) { console.log(`${r.song}: ${r.lyrics.substring(0, 50)}...`); } else { console.log(`${r.song}: Failed (${r.error})`); } }); })(); ``` -------------------------------- ### Search with Artist Name Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Shows how to refine a lyrics search by including the artist's name. This improves accuracy by specifying the artist. ```javascript const { search } = require("music-lyrics"); async function main() { const lyrics = await search("Bohemian Rhapsody", "Queen"); console.log(lyrics); } ``` -------------------------------- ### Wrapper function with caching and error recovery Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Implement a wrapper function to cache lyrics and handle errors gracefully, improving performance for repeated requests. ```javascript const lyrics = require('music-lyrics'); const lyricsCache = new Map(); async function getCachedLyrics(title) { // Check cache first if (lyricsCache.has(title)) { return lyricsCache.get(title); } try { const result = await lyrics.search(title); // Store in cache for future requests lyricsCache.set(title, result); return result; } catch (error) { // Handle error gracefully throw new Error(`Could not find lyrics for "${title}"`); } } // Usage (async () => { const lyrics1 = await getCachedLyrics('Watermelon Sugar'); const lyrics2 = await getCachedLyrics('Watermelon Sugar'); // Returns from cache })(); ``` -------------------------------- ### Extract Lyrics from Supported Websites Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Fetches and parses HTML content from a given link to extract lyrics. It uses Cheerio for DOM manipulation and applies domain-specific CSS selectors and cleanup logic. Handles potential errors during the request or parsing. ```javascript async function find(link) { try { let lyric; const rest = await request.get(link); const $ = cheerio.load(rest.text); if (link.includes('https://www.letras.mus.br/') || link.includes('https://www.letras.com/')) { lyric = $('.cnt-letra.p402_premium').toString().replace(/<.*?>/g, "\n").trim(); } else if (link.includes('https://www.letras.com.br/')) { lyric = $('.lyrics-section').toString().replace(/<.*?>/g, "\n").trim(); } else if (link.includes('https://www.musixmatch.com/')) { lyric = $('.mxm-lyrics__content').toString().replace('', '\n').replace(/<.*?>/g, '') } else if (link.includes('https://www.vagalume.com.br/')) { lyric = $('div[id="lyrics"]').toString().replace(/<.*?>/g, "\n").trim(); } if (!lyric) throw new Error("Error"); return lyric; } catch (error) { throw new Error("Error") } } ``` -------------------------------- ### Basic Lyrics Search Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/README.md Demonstrates how to search for song lyrics using the `search` function from the music-lyrics package. Ensure you handle potential errors during the asynchronous operation. ```javascript const lyrics = require('music-lyrics'); (async () => { try { const result = await lyrics.search('Watermelon Sugar'); console.log(result); } catch (error) { console.error('Failed to fetch lyrics'); } })(); ``` -------------------------------- ### Standard HTML Cleanup for Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Applies a standard HTML cleanup process to extracted lyric content. This involves converting Cheerio objects to strings, removing all HTML tags, and trimming whitespace. Used for Letras Mus, Letras, Letras BR, and Vagalume. ```javascript lyric = selector.toString().replace(/<.*?>/g, "\n").trim(); ``` -------------------------------- ### Generic Catch Block for Error Handling Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Demonstrates a generic catch block pattern for handling potential errors when using the library. This is a basic approach to error management. ```javascript try { // Code that might throw an error const lyrics = await search("Some Song"); } catch (e) { // Handle the error generically console.error("An error occurred:", e.message); } ``` -------------------------------- ### Wrapper Function with Caching Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Implements a wrapper function that adds caching to the search functionality. This can improve performance by storing and reusing previously fetched lyrics. ```javascript const cache = {}; async function searchWithCache(title, artist) { const key = `${title}-${artist}`; if (cache[key]) { return cache[key]; } const lyrics = await search(title, artist); cache[key] = lyrics; return lyrics; } // Usage: // searchWithCache('Bohemian Rhapsody', 'Queen').then(lyrics => console.log(lyrics)); ``` -------------------------------- ### Batch processing of songs with error handling Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Process a list of songs sequentially, collecting results and errors for each song. Useful for iterating through multiple song titles. ```javascript const lyrics = require('music-lyrics'); async function processSongs(songList) { const results = []; for (const song of songList) { try { const lyric = await lyrics.search(song); results.push({ song, status: 'success', lyrics: lyric }); } catch (error) { results.push({ song, status: 'failed', error: error.message }); } } return results; } // Usage const songs = ['Imagine', 'Bohemian Rhapsody', 'Hotel California']; processSongs(songs).then(results => { results.forEach(r => { if (r.status === 'success') { console.log(`✓ ${r.song}`); } else { console.log(`✗ ${r.song}: ${r.error}`); } }); }); ``` -------------------------------- ### search(title: string): Promise Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Searches for song lyrics by title and returns the cleaned lyrics text. This is the primary function for retrieving lyrics. ```APIDOC ## search(title: string): Promise ### Description Searches for song lyrics by title and returns the cleaned lyrics text. This is the primary function for retrieving lyrics. ### Method Not Applicable (SDK Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **title** (string) - Required - The title of the song to search for. ### Returns - **Promise** - A promise that resolves with the lyrics text with HTML tags removed. ### Throws - **Error("Error")** - Thrown on any failure during the search process. ### Request Example ```javascript // Example usage: import { search } from 'music-lyrics'; async function getLyrics(songTitle) { try { const lyrics = await search(songTitle); console.log(lyrics); } catch (error) { console.error('Failed to fetch lyrics:', error); } } getLyrics('Bohemian Rhapsody'); ``` ### Response #### Success Response - **lyricsText** (string) - The lyrics of the song with HTML tags removed. #### Response Example ```json "[Lyrics text with HTML tags removed]" ``` ``` -------------------------------- ### Handling Lyrics Website Fetch Failure Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md This snippet illustrates the error handling within the `find` function for fetching lyrics from a website. It catches errors that occur during the HTTP request or HTML parsing, re-throwing a generic 'Error'. ```javascript async function find(link) { try { let lyric; const rest = await request.get(link); const $ = cheerio.load(rest.text); // ... extraction logic } catch (error) { throw new Error("Error") } } ``` -------------------------------- ### Fallback with Retry Pattern for Error Handling Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Shows a fallback with retry pattern for error handling, allowing for retrying an operation if it fails. This is a more robust error recovery strategy. ```javascript async function searchWithRetry(title, retries = 3) { try { return await search(title); } catch (error) { if (retries <= 0) { throw error; } console.log(`Retrying... (${retries} left)`); await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second return searchWithRetry(title, retries - 1); } } searchWithRetry("Song to Retry").catch(err => console.error(err)); ``` -------------------------------- ### Null Check Pattern for Error Handling Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md Illustrates the null check pattern as a way to handle cases where the search function might return null instead of throwing an error. This is useful for specific error scenarios. ```javascript const lyrics = await search("Another Song"); if (lyrics === null) { console.warn("Lyrics not found or an issue occurred."); } else { // Process lyrics } ``` -------------------------------- ### Search Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/README.md Searches for and returns the lyrics of a given song title. It handles fetching lyrics from multiple sources and cleans the HTML to provide plain text. ```APIDOC ## search(title) ### Description Searches for and returns lyrics for a song title. This is the primary function for retrieving song lyrics. ### Method `async function` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript const lyrics = require('music-lyrics'); (async () => { try { const result = await lyrics.search('Watermelon Sugar'); console.log(result); } catch (error) { console.error('Failed to fetch lyrics'); } })(); ``` ### Response #### Success Response - **lyrics** (string) - Lyrics text with HTML tags removed #### Response Example ```json "Lyrics text here..." ``` ### Error Handling - **Throws:** `Error` — Generic error with message `"Error"` on any failure ``` -------------------------------- ### Handle CSS Selector Variability for Lyrics Websites Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/architecture-and-module-structure.md Detects the source domain of a lyrics URL and applies the appropriate CSS selector to extract content. This handles variations in HTML structure across different websites. ```javascript if (link.includes('https://www.letras.mus.br/') || link.includes('https://www.letras.com/')) { selector = '.cnt-letra.p402_premium'; } else if (link.includes('https://www.letras.com.br/')) { selector = '.lyrics-section'; } else if (link.includes('https://www.musixmatch.com/')) { selector = '.mxm-lyrics__content'; } else if (link.includes('https://www.vagalume.com.br/')) { selector = 'div[id="lyrics"]'; } ``` -------------------------------- ### search Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/api-reference.md The main exported function from the music-lyrics library that searches for song lyrics by title. It returns a Promise that resolves to the complete lyrics text as a string. ```APIDOC ## search ### Description Searches for song lyrics by title. It returns a Promise that resolves to the complete lyrics text as a string, with HTML tags removed and newlines preserved. ### Method `search(title: string): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | title | string | Yes | — | The song title to search for. Can include artist name for better results. | ### Return Value **Type:** `Promise` Returns a Promise that resolves to the complete lyrics text as a string. The lyrics are extracted from one of the supported lyrics websites and have HTML tags removed, with newlines preserved. ### Throws Rejects with an `Error` if: - No lyrics websites are found in the Google search results for the query - The selected lyrics website is unreachable or the connection fails - The lyrics content cannot be parsed from the website's HTML structure - Any network request fails All errors are thrown as generic `Error` objects with the message `"Error"`. ### Example Usage ```javascript const lyrics = require('music-lyrics'); // Basic usage (async () => { try { const lyric = await lyrics.search('Watermelon Sugar'); console.log(lyric); } catch (error) { console.log('Unknown lyric.'); } })(); // With artist name for better results (async () => { try { const lyric = await lyrics.search('Bohemian Rhapsody Queen'); console.log(lyric); } catch (error) { console.log('Lyrics not found'); } })(); // Using await in async context async function getLyrics(songTitle) { try { const content = await lyrics.search(songTitle); return content; } catch (err) { return null; } } ``` ``` -------------------------------- ### Express.js endpoint for lyrics API Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md Create an Express.js route to serve song lyrics via an API endpoint. Handles song title extraction from URL parameters and error responses. ```javascript const express = require('express'); const lyrics = require('music-lyrics'); const app = express(); app.get('/lyrics/:song', async (req, res) => { try { const songTitle = req.params.song; const result = await lyrics.search(songTitle); res.json({ success: true, lyrics: result }); } catch (error) { res.status(500).json({ success: false, error: 'Could not find lyrics for the requested song' }); } }); app.listen(3000, () => console.log('Server running on port 3000')); ``` -------------------------------- ### Catching No Valid Links Found Error Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md This code shows how to handle the 'Error' thrown when no valid links are found after a Google search, either because none matched supported domains or the initial validated link was falsy. The consumer code checks the error message to log a 'Could not find lyrics' message. ```javascript const link = values[0]; if (!link) throw new Error("Error"); ``` ```javascript try { const lyrics = await lyrics.search('Extremely Obscure Song'); } catch (error) { if (error.message === "Error") { // Could mean no valid lyrics sources found, or network error console.log('Could not find lyrics'); } } ``` -------------------------------- ### URL Validation Regex Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md This regex pattern validates URLs, optionally including the protocol. It matches domain names and paths. ```regex /(https?:\[\/\/)?)[a-z\.-]+\/.+/gi ``` -------------------------------- ### Search Function Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/INDEX.md The `search()` function is the primary method for retrieving song lyrics. It takes a song title as input and returns a promise that resolves with the lyrics or rejects with an error. ```APIDOC ## search(title: string): Promise ### Description This function searches for song lyrics based on the provided title. It performs a multi-step process involving Google searches and fetching from various lyrics websites. ### Method search ### Parameters #### Path Parameters - **title** (string) - Required - The title of the song to search for. ### Response #### Success Response - Returns a Promise that resolves with a string containing the song lyrics. #### Error Response - Throws an error if the search fails, no links are found, a lyrics website fetch fails, or content cannot be extracted. ``` -------------------------------- ### Handling Lyrics Content Not Found Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md This code block handles cases where lyrics content is not found on a reachable website. It checks multiple domains using specific CSS selectors and throws a generic 'Error' if the extracted lyric content is falsy or empty. ```javascript let lyric; if (link.includes('https://www.letras.mus.br/') || link.includes('https://www.letras.com/')) { lyric = $('.cnt-letra.p402_premium').toString().replace(/<.*?>/g, "\n").trim(); } else if (link.includes('https://www.letras.com.br/')) { lyric = $('.lyrics-section').toString().replace(/<.*?>/g, "\n").trim(); } else if (link.includes('https://www.musixmatch.com/')) { lyric = $('.mxm-lyrics__content').toString().replace('', '\n').replace(/<.*?>/g, '') } else if (link.includes('https://www.vagalume.com.br/')) { lyric = $('div[id="lyrics"]').toString().replace(/<.*?>/g, "\n").trim(); } if (!lyric) throw new Error("Error"); ``` -------------------------------- ### Catching Google Search Failure Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md This snippet demonstrates how to catch a generic 'Error' thrown when the Google Search operation fails due to network issues, non-2xx status codes, or unparseable HTML. It checks the error message to identify the specific failure. ```javascript try { const rest = await request.get(`https://www.google.com/search?q=${encodeURIComponent(title)}+letra`); const $ = cheerio.load(rest.text); // ... link extraction } catch (error) { throw new Error("Error") } ``` ```javascript try { const lyrics = await lyrics.search('Song Title'); // ... } catch (error) { if (error.message === "Error") { console.log('Search operation failed'); } } ``` -------------------------------- ### Search Song Lyrics Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/00-START-HERE.md Use this basic async function to search for song lyrics by title. It returns the lyrics text after removing HTML tags. ```javascript const lyrics = require('music-lyrics'); const result = await lyrics.search('Watermelon Sugar'); console.log(result); // Returns lyrics text ``` -------------------------------- ### Error Propagation Flow Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Illustrates the flow of errors through the call stack, showing how exceptions are caught and re-thrown at different levels of the asynchronous operations. ```text User calls search(title) ↓ Google request fails ↓ catch block at line 34 ↓ throw new Error("Error") ↓ Propagates to user's catch block ``` ```text User calls search(title) ↓ find(link) is called ↓ Lyrics website request fails ↓ catch block in find() at line 69 ↓ throw new Error("Error") ↓ Caught and re-thrown at line 34 ↓ Propagates to user's catch block ``` -------------------------------- ### Fetch lyrics with error details Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/integration-guide.md A function to fetch lyrics that returns success status and lyrics, or failure status and an error message. ```javascript const lyrics = require('music-lyrics'); async function getLyrics(songTitle) { try { const text = await lyrics.search(songTitle); return { success: true, lyrics: text }; } catch (error) { return { success: false, error: error.message }; } } // Usage getLyrics('Imagine').then(result => { if (result.success) { console.log('Lyrics:', result.lyrics); } else { console.log('Error:', result.error); } }); ``` -------------------------------- ### Null Check Pattern for Safe Lyrics Search Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md Implement a safe search function that returns null on failure instead of throwing an error. This allows the calling code to check for a null result to determine if the lyrics were retrieved. ```javascript async function safeLyricsSearch(title) { try { return await lyrics.search(title); } catch { return null; // Indicate failure with null } } const result = await safeLyricsSearch('Watermelon Sugar'); if (result === null) { console.log('Could not retrieve lyrics'); } else { console.log(result); } ``` -------------------------------- ### Extract and Validate Links Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Iterates through anchor elements to extract, clean, and validate URLs based on a whitelist. ```javascript const values = []; $("a").each(function (i, link) { let url = $(link).attr("href").replace("/url?q=", "").split("&")[0]; if (url[0] === "/") return; // Skip relative links if (!isLink(url)) return; // Skip non-whitelisted domains values.push(url); }); const link = values[0]; // Use first valid link ``` -------------------------------- ### Fallback with Retry for Lyrics Search Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md This function attempts to retrieve lyrics, retrying with a delay if an error occurs. It will throw the error after the maximum number of retries is reached. ```javascript async function getLyricsWithFallback(title, maxRetries = 2) { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await lyrics.search(title); } catch (error) { if (attempt === maxRetries - 1) throw error; // Retry with slight delay await new Promise(r => setTimeout(r, 1000 * (attempt + 1))); } } } ``` -------------------------------- ### Validate Whitelisted Domains Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Checks if a given link belongs to one of the five supported music lyric domains using a regex and string inclusion checks. Ensure the link matches a basic URL pattern and contains a whitelisted domain. ```javascript function isLink(link) { const mus = 'https://www.letras.mus.br/'; const letter = 'https://www.letras.com/'; const letterbr = 'https://www.letras.com.br/'; const musix = 'https://www.musixmatch.com/'; const vagalume = 'https://www.vagalume.com.br/'; const regex = /(https?:\[\/\/)?\[a-z\.-]+\/.+/gi; return regex.test(link) && (link.includes(mus) || link.includes(letter) || link.includes(letterbr) || link.includes(musix) || link.includes(vagalume)); } ``` -------------------------------- ### Re-exporting from Index.js Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md The default export is re-exported from index.js under the name 'search'. This is the name typically used when requiring the library. ```javascript exports.search = require('./lib/search'); ``` -------------------------------- ### Generic Catch Block for Lyrics Search Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/errors-and-exception-handling.md Use this technique to catch any errors during a lyrics search and display a user-friendly message. It does not attempt to recover from specific error types. ```javascript try { const lyrics = await lyrics.search('Song Title'); console.log(lyrics); } catch (error) { console.error('Lyrics search failed. Please try again.'); } ``` -------------------------------- ### Search Lyrics by Title Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/api-reference.md Basic usage of the search function to retrieve lyrics for a given song title. Handles potential errors during the search process. ```javascript const lyrics = require('music-lyrics'); // Basic usage (async () => { try { const lyric = await lyrics.search('Watermelon Sugar'); console.log(lyric); } catch (error) { console.log('Unknown lyric.'); } })(); ``` -------------------------------- ### lyrics.search(title) Source: https://github.com/gabrideiros/music-lyrics/blob/main/_autodocs/implementation-details.md Searches for song lyrics using the provided song title. This is the primary function exposed by the library for users to interact with. ```APIDOC ## lyrics.search(title) ### Description Searches for song lyrics using the provided song title. This is the primary function exposed by the library for users to interact with. ### Method Asynchronous Function Call ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript const lyrics = require('music-lyrics'); await lyrics.search('Song Title'); ``` ### Response #### Success Response (Details not provided in source) #### Response Example (Details not provided in source) ```