UNPKG

leet-code-read-me-generator

Version:

A CLI tool to automatically generate a structured README for LeetCode solutions, making it easier to document your coding challenges and projects.

141 lines (130 loc) 7.11 kB
import axios from 'axios'; import fs from 'fs'; import path from 'path'; import { ArgvParser } from "parsemate"; import beautifyPkg from 'js-beautify'; const { html: beautify } = beautifyPkg; let parser = new ArgvParser( "leetcode-readme" ,{ github: { flags: ['-git', '--github'], description: 'Repo to use for the read me creation.', required: true, multiple: false, }, tech: { flags: ['-t', '--tech'], description: 'Your favourite programming language', multiple: false, required: true, }}); export async function generateReadme() { //parser.parse(); try{ let githubURL = parser.getArg( 'github' ); let lang = parser.getArg( "tech" ); let completedQuestions = []; let readMeFileName = "README.md"; const allLeetCodeQsPromise = axios.post("https://leetcode.com/api/problems/all"); const githubRepoPromise = axios.get(githubURL); let [allLeetCodeQs, githubRepo] = await Promise.all([allLeetCodeQsPromise, githubRepoPromise]); allLeetCodeQs = allLeetCodeQs.data; githubRepo = githubRepo.data githubRepo.map( (answer) => { let answerFileName = parseInt(answer.name.replace(/[^0-9]/g, "")); if( answer.name != "README.md" && answerFileName != isNaN ){ let index = allLeetCodeQs.stat_status_pairs.findIndex(q => { return q.stat.question_id === answerFileName; }) if( index != -1 ){ completedQuestions.push( { gitLink: answer._links.html, gitPath: answer.path, questionNumber: allLeetCodeQs.stat_status_pairs[index].stat.question_id, questionTitle: allLeetCodeQs.stat_status_pairs[index].stat.question__title, questionDifficulty :allLeetCodeQs.stat_status_pairs[index].difficulty.level, question_title_slug : allLeetCodeQs.stat_status_pairs[index].stat.question__title_slug }) } } } ); const filePath = path.join(process.cwd(), readMeFileName); let readMe = '<h1 align="center">🚀 My LeetCode Journey</h1><p align="center"><img src="https://img.shields.io/badge/Problems%20Solve%20'+githubRepo.length+'/'+allLeetCodeQs.stat_status_pairs.length+'-blueviolet?style=for-the-badge" alt="Problems Solved" /> '+getLanguageBadge(lang) +' <img src="https://img.shields.io/badge/Last%20Updated-'+getEncodedMonthYear(new Date())+'-brightgreen?style=for-the-badge" alt="Updated" /></p><p align="center"><b>A visually organized collection of my LeetCode solutions 🚀</b><br/><i>Click through each problem to see the code, patterns, and explanations!</i></p><hr/>'; readMe += "<table class='table table-striped table-hover'> <thead> <td> Question number </td> <td> Question Title </td> <td> Difficulty </td> <td> Link to description </td> </thead>" //console.log(rowGenerator(completedQuestions)) readMe += "<tbody>" + rowGenerator(completedQuestions) + "</tbody>"; readMe += "</table>"; const prettyHtml = beautify(readMe, { indent_size: 2 }); fs.writeFile(filePath, prettyHtml, 'utf8', (err) => { if (err) { console.error('An error occurred while writing the file:', err); } else { console.log(`File "${readMeFileName}" created and written successfully!`); } }); } catch( err ){ if( err.response?.status === 404 ){console.log(parser.generateHelp() + '\n' + "Can't find github URL" ), process.exit(1); } } }; function getDifficultyBadge(level) { switch (level) { case 1: return '<span class="badge text-bg-success">Easy</span>'; case 2: return '<span class="badge text-bg-warning">Medium</span>'; case 3: return '<span class="badge text-bg-danger">Hard</span>'; default: return '❓ Unknown'; } } function getLanguageBadge(language) { switch (language.toLowerCase()) { case 'javascript': return '<img src="https://img.shields.io/badge/Language-JavaScript-yellow?style=for-the-badge" alt="JavaScript" />'; case 'python': return '<img src="https://img.shields.io/badge/Language-Python-blue?style=for-the-badge" alt="Python" />'; case 'java': return '<img src="https://img.shields.io/badge/Language-Java-red?style=for-the-badge" alt="Java" />'; case 'c++': return '<img src="https://img.shields.io/badge/Language-C++-blue?style=for-the-badge" alt="C++" />'; case 'c#': return '<img src="https://img.shields.io/badge/Language-C%23-8A2BE2?style=for-the-badge" alt="C#" />'; case 'go': return '<img src="https://img.shields.io/badge/Language-Go-00ADD8?style=for-the-badge" alt="Go" />'; case 'rust': return '<img src="https://img.shields.io/badge/Language-Rust-b7410e?style=for-the-badge" alt="Rust" />'; case 'typescript': return '<img src="https://img.shields.io/badge/Language-TypeScript-3178C6?style=for-the-badge" alt="TypeScript" />'; case 'php': return '<img src="https://img.shields.io/badge/Language-PHP-777BB4?style=for-the-badge" alt="PHP" />'; case 'ruby': return '<img src="https://img.shields.io/badge/Language-Ruby-CC342D?style=for-the-badge" alt="Ruby" />'; case 'swift': return '<img src="https://img.shields.io/badge/Language-Swift-FA7343?style=for-the-badge" alt="Swift" />'; case 'kotlin': return '<img src="https://img.shields.io/badge/Language-Kotlin-0095D5?style=for-the-badge" alt="Kotlin" />'; case 'dart': return '<img src="https://img.shields.io/badge/Language-Dart-0175C2?style=for-the-badge" alt="Dart" />'; case 'scala': return '<img src="https://img.shields.io/badge/Language-Scala-DC322F?style=for-the-badge" alt="Scala" />'; case 'shell': return '<img src="https://img.shields.io/badge/Language-Shell-89e051?style=for-the-badge" alt="Shell" />'; default: return '❓ Unknown Language'; } } function getEncodedMonthYear(date = new Date()) { const options = { month: 'long', year: 'numeric' }; const formatted = date.toLocaleString('default', options); // e.g., "April 2025" return encodeURIComponent(formatted); // e.g., "April%202025" } function rowGenerator( completedQuestions ){ let rows = ""; //console.log(completedQuestions, "-"); completedQuestions = completedQuestions.sort( (a,b) => { return a.questionNumber - b.questionNumber } ) for( let x = 0; x < completedQuestions.length; x++ ){ rows += ("<tr><th> <a href= '" + completedQuestions[x].gitLink +"'> "+completedQuestions[x].questionNumber+" </a></th> <td> " + completedQuestions[x].questionTitle + "</td> <td> " + getDifficultyBadge(completedQuestions[x].questionDifficulty) + "</td> <td>" + "https://leetcode.com/problems/"+ completedQuestions[x].question_title_slug +"/description/" + " </td></tr>") } return rows; };