{"id":28798125,"url":"https://github.com/mkornajcik/leaguele","last_synced_at":"2026-04-10T14:39:40.236Z","repository":{"id":299652758,"uuid":"1003569260","full_name":"mkornajcik/leaguele","owner":"mkornajcik","description":"Leaguele is a Wordle-like guessing game for League of Legends champions, based on Loldle.","archived":false,"fork":false,"pushed_at":"2025-06-17T15:49:46.000Z","size":6015,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-17T16:36:28.356Z","etag":null,"topics":["docker","ejs","expressjs","gitlab","javascript","nodejs","redis","tailwind","typescript"],"latest_commit_sha":null,"homepage":"https://leaguele.up.railway.app/","language":"EJS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkornajcik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-17T10:47:22.000Z","updated_at":"2025-06-17T15:49:49.000Z","dependencies_parsed_at":"2025-06-17T16:47:26.472Z","dependency_job_id":null,"html_url":"https://github.com/mkornajcik/leaguele","commit_stats":null,"previous_names":["mkornajcik/leaguele"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mkornajcik/leaguele","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkornajcik%2Fleaguele","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkornajcik%2Fleaguele/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkornajcik%2Fleaguele/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkornajcik%2Fleaguele/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkornajcik","download_url":"https://codeload.github.com/mkornajcik/leaguele/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkornajcik%2Fleaguele/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260491143,"owners_count":23017183,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","ejs","expressjs","gitlab","javascript","nodejs","redis","tailwind","typescript"],"created_at":"2025-06-18T05:01:59.161Z","updated_at":"2026-04-10T14:39:40.223Z","avatar_url":"https://github.com/mkornajcik.png","language":"EJS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Leaguele\n\n**Live Demo:** [https://leaguele.up.railway.app/](https://leaguele.up.railway.app/)\n\nLeaguele is a Wordle-like guessing game for League of Legends champions, based on Loldle. It offers multiple modes (classic, quote, ability, emoji, splash) where players guess the champion based on varying clues each day.\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Demo / Screenshots](#demo--screenshots)\n- [Tech Stack](#tech-stack)\n- [Prerequisites](#prerequisites)\n- [Running in Development](#running-in-development)\n- [Building \u0026 Production](#building--production)\n- [Testing](#testing)\n- [CI/CD (GitLab)](#cicd-gitlab)\n- [Security \u0026 Rate Limiting](#security--rate-limiting)\n- [Disclaimer \u0026 Legal](#disclaimer--legal)\n- [License](#license)\n- [Acknowledgments](#acknowledgments)\n\n---\n\n## Features\n\n- Five game modes:\n  - **Classic**: Guess the champion by comparing attributes and deducing the champion that fits all criteria.\n  - **Quote**: Guess the champion from a random in-game quote or voice line.\n  - **Ability**: Guess the champion based on an ability image.\n  - **Emoji**: Decode an emoji sequence representing the champion.\n  - **Splash**: Guess from a zoomed-in portion of the official splash art.\n\n- Built with TypeScript, Express, EJS templates, Tailwind CSS.\n- Session management with `express-session` and Redis (via `connect-redis` and `redis`).\n- Daily champion assignment at midnight (Europe/Paris timezone) for each mode.\n- Data stored in JSON files (included in the repo for free use).\n- Tests for all endpoints using Jest and SuperTest.\n- GitLab CI/CD pipeline: building Docker image, compiling TypeScript, building assets, running tests.\n- Dockerized for easy local and production deployment.\n- Rate limiting, input validation/sanitization, security headers via Helmet.\n- Deployed on Railway with a linked Redis database.\n\n---\n\n## Demo / Screenshots\n\n\u003cdetails\u003e\n  \u003csummary\u003eShow Game Mode Screenshots\u003c/summary\u003e\n\n  ### Home\n  ![main](https://github.com/user-attachments/assets/d3c27b3b-2bfc-49db-8844-188dd60e0cb8)\n\n  ### Classic\n  ![classic](https://github.com/user-attachments/assets/2c6d7a4e-ce53-4ee3-928b-1df5b1f8f554)\n\n  ### Quote\n  ![quote](https://github.com/user-attachments/assets/d7967691-fa4b-4989-8550-4d6aa3cb3ad6)\n\n  ### Ability\n  ![ability1](https://github.com/user-attachments/assets/55ece3d5-6521-46ca-b6e1-5f168ed9fe38)\n  ![ability2](https://github.com/user-attachments/assets/0000f43b-b407-4b7c-9cce-98c537dd1338)\n\n  ### Emoji\n  ![emoji](https://github.com/user-attachments/assets/284a4a09-4ef5-445d-a660-0e8acd86bc98)\n\n  ### Splash\n  ![splash](https://github.com/user-attachments/assets/23b009b4-9567-4192-b2bd-b255ea28d8ed)\n\n\u003c/details\u003e\n\n\n---\n\n## Tech Stack\n\n- **Language \u0026 Runtime:** Node.js (TypeScript)\n- **Web Framework:** Express \n- **Templating:** EJS\n- **Styling:** Tailwind CSS, PostCSS\n- **Session \u0026 Storage:** express-session, redis, ioredis\n- **Scheduling / Date Handling:** Luxon\n- **Testing:** Jest, SuperTest\n- **Utilities:** express-validator, helmet, express-rate-limit, dotenv\n- **CI/CD:** GitLab CI with Docker-in-Docker\n- **Deployment:** Docker, Railway\n- **Data Fetching (scripts):** node-fetch, cheerio, puppeteer, shelljs\n\n---\n\n## Prerequisites\n\n- **Node.js**: version \u003e= 18 (adjust if different).\n- **npm** (scripts assume npm).\n- **Docker**: for local Redis instance (optional but recommended) and building the app image.\n- **Redis**: Used for session storage. For local development, run Redis in Docker:\n  ```bash\n  docker run -d --name leaguele-redis -p 6379:6379 redis\n  ```\n\n---\n\n\n## Running in Development\n\n- Start Redis locally (e.g., via Docker as above).\n- Run the dev server with hot reload:\n  ```bash\n  npm run dev\n  ```\n- CSS changes: in another terminal, watch Tailwind CSS:\n  ```bash\n  npm run watch:css\n  ```\n- The server listens on `http://localhost:3000` (or your `PORT`).\n\n---\n\n## Building \u0026 Production\n\n1. **Prebuild** (copy assets):\n   ```bash\n   npm run prebuild\n   ```\n2. **Compile TypeScript**:\n   ```bash\n   npm run build\n   ```\n3. **Build CSS**:\n   ```bash\n   npm run build:css\n   ```\n4. **Start**:\n   ```bash\n   npm start\n   ```\n   Ensure `NODE_ENV=production`, environment variables set, and Redis is accessible.\n\n---\n\n## Testing\n\n- **Run tests**:\n  ```bash\n  npm run test\n  ```\n- For experimental VM modules in Jest:\n  ```bash\n  npm run test:exp\n  ```\n- Tests may require a running Redis instance or mocks depending on setup.\n\n---\n\n## CI/CD (GitLab)\n\nThe project includes `.gitlab-ci.yml` with stages:\n1. **build_docker**: Build Docker image and save artifact.\n2. **build_typescript**: Install dependencies and compile TypeScript.\n3. **build_assets**: Install dependencies and build Tailwind CSS assets.\n4. **test**: Install dependencies and run Jest tests.\n\n---\n\n## Security \u0026 Rate Limiting\n\n- **Helmet** secures HTTP headers.\n- **express-rate-limit** prevents abuse; configured in middleware.\n- **express-validator** for input validation/sanitization.\n- **Sessions**: Stored in Redis; ensure `SESSION_SECRET` is strong and kept secret.\n\n---\n\n## Disclaimer \u0026 Legal\n\nLeaguele is heavily inspired by Loldle.\n\nLeaguele is a fan-made project that uses assets and data owned by Riot Games. This project is not endorsed, sponsored, or affiliated with Riot Games. Use of Riot assets and data is subject to Riot’s policies:\n\n\u003e “Leaguele was created under Riot Games’ ‘Legal Jibber Jabber’ policy using assets owned by Riot Games. Riot Games does not endorse or sponsor this project.”  \n\n---\n\n## License\n\nThis project is open source under the MIT License.\n\n---\n\n## Acknowledgments\n\n- **Riot Games** for providing Data Dragon and API (used in scripts).\n- **Community Dragon CDN** for assets.\n- Inspiration from Loldle.\n- Open-source libraries and tools used throughout.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkornajcik%2Fleaguele","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkornajcik%2Fleaguele","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkornajcik%2Fleaguele/lists"}