From fd80b67e089736efb1d4fb6023b900bac059388a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fidel=20Alejandro=20Fern=C3=A1ndez=20Arias?= <47539231+ale94lko@users.noreply.github.com> Date: Tue, 26 Jul 2022 03:04:24 -0400 Subject: [PATCH 01/88] Fixed misspelling (#1885) --- src/translations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations.js b/src/translations.js index 38e53f37..31b2d218 100644 --- a/src/translations.js +++ b/src/translations.js @@ -201,7 +201,7 @@ const repoCardLocales = { cs: "Šablona", de: "Vorlage", en: "Template", - es: "Planitlla", + es: "Plantilla", fr: "Modèle", hu: "Sablon", it: "Template", From cffb0843b172ca114a0164b6258dc35947e99bd3 Mon Sep 17 00:00:00 2001 From: tmt <101849050+tinnamchoi@users.noreply.github.com> Date: Wed, 27 Jul 2022 15:17:55 +0930 Subject: [PATCH 02/88] docs: incorrect cache documentation (#1889) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d1aa23a3..14673905 100644 --- a/readme.md +++ b/readme.md @@ -167,7 +167,7 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_ - `hide_border` - Hides the card's border _(boolean)_ - `theme` - name of the theme, choose from [all available themes](./themes/README.md) -- `cache_seconds` - set the cache header manually _(min: 1800, max: 86400)_ +- `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_ - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_ - `border_radius` - Corner rounding on the card_ From 678fa1141676fc8fb75e2a322e4297323900e330 Mon Sep 17 00:00:00 2001 From: tmt <101849050+tinnamchoi@users.noreply.github.com> Date: Wed, 27 Jul 2022 15:18:20 +0930 Subject: [PATCH 03/88] docs: note for temporary cache inc (#1890) --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 14673905..ec31fdfc 100644 --- a/readme.md +++ b/readme.md @@ -171,6 +171,8 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_ - `border_radius` - Corner rounding on the card_ +> Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. + ##### Gradient in bg_color You can provide multiple comma-separated values in the bg_color option to render a gradient, with the following format: From 86f0ea071595df748a8db294db38d9cb18bd1a47 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 29 Jul 2022 10:42:47 +0200 Subject: [PATCH 04/88] build: pin node version to >=13 (#1900) (#1901) This commit pins the node version to >=13 since node 12 is now end of life (see https://vercel.com/changelog/node-js-12-is-being-deprecated). --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index ed7a9ae2..e2f13552 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,9 @@ }, "author": "Anurag Hazra", "license": "MIT", + "engines": { + "node": ">=13" + }, "devDependencies": { "@actions/core": "^1.2.4", "@actions/github": "^4.0.0", From 74fc4a3cc3a051f5792a08d94deda1bd9a752dc3 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 31 Jul 2022 12:10:10 +0200 Subject: [PATCH 05/88] refactor: improve issues template Move FAQ notice to the top of the issues template to increase the change of users reading it. --- .github/ISSUE_TEMPLATE/bug_report.md | 41 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9375a5e1..44704fb4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,23 +1,3 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "" -labels: "" -assignees: "" ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**Expected behaviour** -A clear and concise description of what you expected to happen. - -**Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** -If applicable, add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. - + +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: "" +assignees: "" +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Expected behaviour** +A clear and concise description of what you expected to happen. + +**Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. From 689e1f4052203b89043af7fdd2e4571e7a6c46d8 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 31 Jul 2022 12:11:18 +0200 Subject: [PATCH 06/88] refactor: fix bug in issues template --- .github/ISSUE_TEMPLATE/bug_report.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 44704fb4..b9616818 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,3 +1,10 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: "" +assignees: "" +--- ---- -name: Bug report -about: Create a report to help us improve -title: "" -labels: "" -assignees: "" ---- - **Describe the bug** A clear and concise description of what the bug is. From e547eaf563d3ae0444b1ecea82dddc2e351a2e7d Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 31 Jul 2022 12:16:46 +0200 Subject: [PATCH 07/88] refactor: improve issues template Move part of the FAQ notice to the bottom so that it doesn't clutter the issues window. --- .github/ISSUE_TEMPLATE/bug_report.md | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b9616818..5ed7d3c9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -5,9 +5,22 @@ title: "" labels: "" assignees: "" --- - -PLEASE FIRST READ THE FAQ (#1770) AND COMMON ERROR CODES (#1772)!!! +**Describe the bug** +A clear and concise description of what the bug is. + +**Expected behaviour** +A clear and concise description of what you expected to happen. + +**Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. + + - -**Describe the bug** -A clear and concise description of what the bug is. - -**Expected behaviour** -A clear and concise description of what you expected to happen. - -**Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** -If applicable, add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. From 7ceec9245507288bc8d1f1f065a78d3a495cea10 Mon Sep 17 00:00:00 2001 From: Cong Date: Mon, 1 Aug 2022 18:13:59 +1000 Subject: [PATCH 08/88] refactor: fix typo in comment (#1912) --- src/cards/top-languages-card.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index 4e079ff2..836af05b 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -214,7 +214,7 @@ const useLanguages = (topLangs, hide, langs_count) => { }); } - // filter out langauges to be hidden + // filter out languages to be hidden langs = langs .sort((a, b) => b.size - a.size) .filter((lang) => { From b6d75b2e65ee3c28db064af5cb19478968dbac4c Mon Sep 17 00:00:00 2001 From: Kisaragi <48310258+KisaragiEffective@users.noreply.github.com> Date: Tue, 2 Aug 2022 19:26:07 +0900 Subject: [PATCH 09/88] refactor: remove arrow function body braces (#1917) --- src/fetchers/top-languages-fetcher.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 9dd109e2..7c4c8785 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -68,14 +68,10 @@ async function fetchTopLanguages(username, exclude_repo = []) { // filter out repositories to be hidden repoNodes = repoNodes .sort((a, b) => b.size - a.size) - .filter((name) => { - return !repoToHide[name.name]; - }); + .filter((name) => !repoToHide[name.name]); repoNodes = repoNodes - .filter((node) => { - return node.languages.edges.length > 0; - }) + .filter((node) => node.languages.edges.length > 0) // flatten the list of language nodes .reduce((acc, curr) => curr.languages.edges.concat(acc), []) .reduce((acc, prev) => { From e5222902c3f390733fa93e94ba61cd21412389cc Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 13 Aug 2022 01:26:05 -0700 Subject: [PATCH 10/88] refactor: update license year (#1735) * Updated Year * Update LICENSE / Revert to 2020 The MIT license [year] field should indicate the year the copyright was applied Co-authored-by: Rick Staa Co-authored-by: Rick Staa --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 83b114d1..14d9ba34 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 Anurag Hazra +Copyright (c) 2020 Anurag Hazra Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 4b6f4650b21a892b8ee1f57593b38efffed74155 Mon Sep 17 00:00:00 2001 From: akmhmgc <38002468+akmhmgc@users.noreply.github.com> Date: Sun, 14 Aug 2022 03:24:44 +0900 Subject: [PATCH 11/88] refactor: improve level calculator (#1946) --- src/calculateRank.js | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index 76909d09..0c401d9a 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -63,29 +63,13 @@ function calculateRank({ const normalizedScore = normalcdf(score, TOTAL_VALUES, ALL_OFFSETS) * 100; - let level = ""; - - if (normalizedScore < RANK_S_VALUE) { - level = "S+"; - } - if ( - normalizedScore >= RANK_S_VALUE && - normalizedScore < RANK_DOUBLE_A_VALUE - ) { - level = "S"; - } - if ( - normalizedScore >= RANK_DOUBLE_A_VALUE && - normalizedScore < RANK_A2_VALUE - ) { - level = "A++"; - } - if (normalizedScore >= RANK_A2_VALUE && normalizedScore < RANK_A3_VALUE) { - level = "A+"; - } - if (normalizedScore >= RANK_A3_VALUE && normalizedScore < RANK_B_VALUE) { - level = "B+"; - } + const level = (() => { + if (normalizedScore < RANK_S_VALUE) return "S+"; + if (normalizedScore >= RANK_S_VALUE && normalizedScore < RANK_DOUBLE_A_VALUE) return "S"; + if (normalizedScore >= RANK_DOUBLE_A_VALUE && normalizedScore < RANK_A2_VALUE) return "A++"; + if (normalizedScore >= RANK_A2_VALUE && normalizedScore < RANK_A3_VALUE) return "A+" + if (normalizedScore >= RANK_A3_VALUE && normalizedScore < RANK_B_VALUE) return "B+" + })() return { level, score: normalizedScore }; } From 8d5f2da3f317dc8977ba887b36030d9195e41c96 Mon Sep 17 00:00:00 2001 From: Qi Mo Lin <60514926+qimolin@users.noreply.github.com> Date: Wed, 17 Aug 2022 23:22:52 +0200 Subject: [PATCH 12/88] test: fix gradient test by using more specific querySelector (#1954) --- tests/card.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/card.test.js b/tests/card.test.js index 002d278a..2ef77945 100644 --- a/tests/card.test.js +++ b/tests/card.test.js @@ -168,18 +168,18 @@ describe("Card", () => { "fill", "url(#gradient)", ); - expect(document.querySelector("defs linearGradient")).toHaveAttribute( + expect(document.querySelector("defs #gradient")).toHaveAttribute( "gradientTransform", "rotate(90)", ); expect( - document.querySelector("defs linearGradient stop:nth-child(1)"), + document.querySelector("defs #gradient stop:nth-child(1)"), ).toHaveAttribute("stop-color", "#fff"); expect( - document.querySelector("defs linearGradient stop:nth-child(2)"), + document.querySelector("defs #gradient stop:nth-child(2)"), ).toHaveAttribute("stop-color", "#000"); expect( - document.querySelector("defs linearGradient stop:nth-child(3)"), + document.querySelector("defs #gradient stop:nth-child(3)"), ).toHaveAttribute("stop-color", "#f00"); }); }); From dd5a41d696c3f6a6ad84253317d1b70bd0e1a66f Mon Sep 17 00:00:00 2001 From: Qi Mo Lin <60514926+qimolin@users.noreply.github.com> Date: Thu, 18 Aug 2022 10:32:03 +0200 Subject: [PATCH 13/88] feat: add min width languages card (#1953) * Add min width to languages card * Add test for min width languages card * feat: increase lang card min width Co-authored-by: Rick Staa --- src/cards/top-languages-card.js | 20 +++++++++++++------- tests/renderTopLanguages.test.js | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index 836af05b..b2f5c362 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -13,6 +13,7 @@ const { } = require("../common/utils"); const DEFAULT_CARD_WIDTH = 300; +const MIN_CARD_WIDTH = 230; const DEFAULT_LANGS_COUNT = 5; const DEFAULT_LANG_COLOR = "#858585"; const CARD_PADDING = 25; @@ -24,12 +25,12 @@ const CARD_PADDING = 25; /** * @param {Lang[]} arr */ - const getLongestLang = (arr) => - arr.reduce( - (savedLang, lang) => - lang.name.length > savedLang.name.length ? lang : savedLang, - { name: "", size: null, color: "" }, - ); +const getLongestLang = (arr) => + arr.reduce( + (savedLang, lang) => + lang.name.length > savedLang.name.length ? lang : savedLang, + { name: "", size: null, color: "" }, + ); /** * @param {{ @@ -261,7 +262,11 @@ const renderTopLanguages = (topLangs, options = {}) => { String(langs_count), ); - let width = isNaN(card_width) ? DEFAULT_CARD_WIDTH : card_width; + let width = isNaN(card_width) + ? DEFAULT_CARD_WIDTH + : card_width < MIN_CARD_WIDTH + ? MIN_CARD_WIDTH + : card_width; let height = calculateNormalLayoutHeight(langs.length); let finalLayout = ""; @@ -307,3 +312,4 @@ const renderTopLanguages = (topLangs, options = {}) => { }; module.exports = renderTopLanguages; +module.exports.MIN_CARD_WIDTH = MIN_CARD_WIDTH; diff --git a/tests/renderTopLanguages.test.js b/tests/renderTopLanguages.test.js index 36dbf03f..b2ff70f6 100644 --- a/tests/renderTopLanguages.test.js +++ b/tests/renderTopLanguages.test.js @@ -103,6 +103,21 @@ describe("Test renderTopLanguages", () => { expect(document.querySelector("svg")).toHaveAttribute("width", "400"); }); + it("should render with min width", () => { + document.body.innerHTML = renderTopLanguages(langs, { card_width: 190 }); + + expect(document.querySelector("svg")).toHaveAttribute( + "width", + renderTopLanguages.MIN_CARD_WIDTH.toString(), + ); + + document.body.innerHTML = renderTopLanguages(langs, { card_width: 100 }); + expect(document.querySelector("svg")).toHaveAttribute( + "width", + renderTopLanguages.MIN_CARD_WIDTH.toString(), + ); + }); + it("should render default colors properly", () => { document.body.innerHTML = renderTopLanguages(langs); From 663fbae49acd7daccbf20ccbfd18d0d5a10b1005 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 18 Aug 2022 11:31:45 +0200 Subject: [PATCH 14/88] ci: add top-issues-dashboard action This commit adds the top issues dashboard action which creates a issue displaying the top issues of the week. --- .github/workflows/top-issues-dashboard.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/top-issues-dashboard.yml diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml new file mode 100644 index 00000000..19ebe418 --- /dev/null +++ b/.github/workflows/top-issues-dashboard.yml @@ -0,0 +1,20 @@ +name: Update top issues dashboard. +on: + schedule: + - cron: "0 0 */7 * *" + +jobs: + showAndLabelTopIssues: + name: Update top issues Dashboard. + runs-on: ubuntu-latest + steps: + - name: Run top issues action + uses: rickstaa/top-issues-action@v1 + env: + github_token: ${{ secrets.GITHUB_TOKEN }} + label: false + dashboard: true + top_issues: true + top_bugs: true + top_features: true + top_pull_requests: true From e9c55d90ad8c9663a480ffaa56484f979ce86fad Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 18 Aug 2022 11:32:57 +0200 Subject: [PATCH 15/88] ci: fix title of top-issues action --- .github/workflows/top-issues-dashboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml index 19ebe418..36394081 100644 --- a/.github/workflows/top-issues-dashboard.yml +++ b/.github/workflows/top-issues-dashboard.yml @@ -1,4 +1,4 @@ -name: Update top issues dashboard. +name: Update top issues dashboard on: schedule: - cron: "0 0 */7 * *" From c2c07ea02238177495eb693c6c1cecb77662ad0b Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 25 Aug 2022 19:45:11 +0200 Subject: [PATCH 16/88] ci: fix top-issues-action syntax (#1978) --- .github/workflows/top-issues-dashboard.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml index 36394081..a8b2bf30 100644 --- a/.github/workflows/top-issues-dashboard.yml +++ b/.github/workflows/top-issues-dashboard.yml @@ -12,6 +12,7 @@ jobs: uses: rickstaa/top-issues-action@v1 env: github_token: ${{ secrets.GITHUB_TOKEN }} + with: label: false dashboard: true top_issues: true From 84610521a2b56a165f631e9f0e1272d48caafeee Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Thu, 25 Aug 2022 20:06:45 +0200 Subject: [PATCH 17/88] ci: add top-issues-action argument --- .github/workflows/top-issues-dashboard.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml index 36394081..db9abfe7 100644 --- a/.github/workflows/top-issues-dashboard.yml +++ b/.github/workflows/top-issues-dashboard.yml @@ -14,6 +14,7 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} label: false dashboard: true + dashboard_show_total_reactions: true top_issues: true top_bugs: true top_features: true From a481021dab695e1d8259e218d8e159e8a2110b1e Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Fri, 26 Aug 2022 21:28:48 +0100 Subject: [PATCH 18/88] Fix NaN and undefined for empty profiles (#1965) * totalCommits: don't return NaN * rank: B+ should cover everyone Empty profile used to show "undefined" as the rank. Now empty profile shows "A+"... is B+ possible? --- src/calculateRank.js | 8 ++++---- src/fetchers/stats-fetcher.js | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index 0c401d9a..9a8a55d5 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -65,10 +65,10 @@ function calculateRank({ const level = (() => { if (normalizedScore < RANK_S_VALUE) return "S+"; - if (normalizedScore >= RANK_S_VALUE && normalizedScore < RANK_DOUBLE_A_VALUE) return "S"; - if (normalizedScore >= RANK_DOUBLE_A_VALUE && normalizedScore < RANK_A2_VALUE) return "A++"; - if (normalizedScore >= RANK_A2_VALUE && normalizedScore < RANK_A3_VALUE) return "A+" - if (normalizedScore >= RANK_A3_VALUE && normalizedScore < RANK_B_VALUE) return "B+" + if (normalizedScore < RANK_DOUBLE_A_VALUE) return "S"; + if (normalizedScore < RANK_A2_VALUE) return "A++"; + if (normalizedScore < RANK_A3_VALUE) return "A+" + return "B+"; })() return { level, score: normalizedScore }; diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 04b4b3e5..2617137a 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -86,15 +86,16 @@ const totalCommitsFetcher = async (username) => { try { let res = await retryer(fetchTotalCommits, { login: username }); - if (res.data.total_count) { + let total_count = res.data.total_count; + if (!!total_count && !isNaN(total_count)) { return res.data.total_count; } } catch (err) { logger.log(err); - // just return 0 if there is something wrong so that - // we don't break the whole app - return 0; } + // just return 0 if there is something wrong so that + // we don't break the whole app + return 0; }; /** From d5c94b6f57d4592b8fafe3fb56f5c8d254cdc51a Mon Sep 17 00:00:00 2001 From: John Sweeney Date: Tue, 6 Sep 2022 07:50:39 +0100 Subject: [PATCH 19/88] Remove unneeded underscore from Readme (#2003) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index ec31fdfc..f6578712 100644 --- a/readme.md +++ b/readme.md @@ -169,7 +169,7 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `theme` - name of the theme, choose from [all available themes](./themes/README.md) - `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_ - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_ -- `border_radius` - Corner rounding on the card_ +- `border_radius` - Corner rounding on the card > Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. From 4c2307ab4b30c02123e072f91b1675b876299a72 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 6 Sep 2022 03:09:45 -0400 Subject: [PATCH 20/88] Add prettier check to CI (#1999) * Add prettier check to CI * Run prettier:format --- .github/workflows/test.yml | 4 ++++ package.json | 4 +++- scripts/generate-langs-json.js | 40 ++++++++++++++++++-------------- src/calculateRank.js | 4 ++-- src/cards/repo-card.js | 12 +++++----- src/fetchers/wakatime-fetcher.js | 2 +- tests/fetchTopLanguages.test.js | 5 +++- tests/fetchWakatime.test.js | 2 +- tests/renderWakatimeCard.test.js | 17 +++++++++----- themes/index.js | 4 ++-- 10 files changed, 56 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 89df34e6..d26607d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,5 +25,9 @@ jobs: npm install npm run test + - name: Run Prettier + run: | + npm run prettier:check:ci + - name: Code Coverage uses: codecov/codecov-action@v1 diff --git a/package.json b/package.json index e2f13552..110a4e80 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,9 @@ "test:watch": "jest --watch", "theme-readme-gen": "node scripts/generate-theme-doc", "preview-theme": "node scripts/preview-theme", - "generate-langs-json": "node scripts/generate-langs-json" + "generate-langs-json": "node scripts/generate-langs-json", + "prettier:check:ci": "./node_modules/.bin/prettier --check .", + "prettier:format": "./node_modules/.bin/prettier --write ." }, "author": "Anurag Hazra", "license": "MIT", diff --git a/scripts/generate-langs-json.js b/scripts/generate-langs-json.js index 0705080d..bd210a3c 100644 --- a/scripts/generate-langs-json.js +++ b/scripts/generate-langs-json.js @@ -1,26 +1,30 @@ -const fs = require('fs'); -const jsYaml = require('js-yaml'); -const axios = require('axios'); +const fs = require("fs"); +const jsYaml = require("js-yaml"); +const axios = require("axios"); -const LANGS_FILEPATH = "./src/common/languageColors.json" +const LANGS_FILEPATH = "./src/common/languageColors.json"; //Retrieve languages from github linguist repository yaml file //@ts-ignore -axios.get("https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml") -.then((response) => { +axios + .get( + "https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml", + ) + .then((response) => { + //and convert them to a JS Object + const languages = jsYaml.load(response.data); - //and convert them to a JS Object - const languages = jsYaml.load(response.data); + const languageColors = {}; - const languageColors = {}; + //Filter only language colors from the whole file + Object.keys(languages).forEach((lang) => { + languageColors[lang] = languages[lang].color; + }); - //Filter only language colors from the whole file - Object.keys(languages).forEach((lang) => { - languageColors[lang] = languages[lang].color; + //Debug Print + //console.dir(languageColors); + fs.writeFileSync( + LANGS_FILEPATH, + JSON.stringify(languageColors, null, " "), + ); }); - - //Debug Print - //console.dir(languageColors); - fs.writeFileSync(LANGS_FILEPATH, JSON.stringify(languageColors, null, ' ')); - -}); diff --git a/src/calculateRank.js b/src/calculateRank.js index 9a8a55d5..742b9ab1 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -67,9 +67,9 @@ function calculateRank({ if (normalizedScore < RANK_S_VALUE) return "S+"; if (normalizedScore < RANK_DOUBLE_A_VALUE) return "S"; if (normalizedScore < RANK_A2_VALUE) return "A++"; - if (normalizedScore < RANK_A3_VALUE) return "A+" + if (normalizedScore < RANK_A3_VALUE) return "A+"; return "B+"; - })() + })(); return { level, score: normalizedScore }; } diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index bb5c178a..034ee1f6 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -67,8 +67,8 @@ const iconWithLabel = (icon, label, testid) => { }; /** - * @param {import('../fetchers/types').RepositoryData} repo - * @param {Partial} options + * @param {import('../fetchers/types').RepositoryData} repo + * @param {Partial} options * @returns {string} */ const renderRepoCard = (repo, options = {}) => { @@ -167,11 +167,11 @@ const renderRepoCard = (repo, options = {}) => { return card.render(` ${ isTemplate - // @ts-ignore - ? getBadgeSVG(i18n.t("repocard.template"), colors.textColor) + ? // @ts-ignore + getBadgeSVG(i18n.t("repocard.template"), colors.textColor) : isArchived - // @ts-ignore - ? getBadgeSVG(i18n.t("repocard.archived"), colors.textColor) + ? // @ts-ignore + getBadgeSVG(i18n.t("repocard.archived"), colors.textColor) : "" } diff --git a/src/fetchers/wakatime-fetcher.js b/src/fetchers/wakatime-fetcher.js index e9779d60..fe06c638 100644 --- a/src/fetchers/wakatime-fetcher.js +++ b/src/fetchers/wakatime-fetcher.js @@ -7,7 +7,7 @@ const { MissingParamError } = require("../common/utils"); */ const fetchWakatimeStats = async ({ username, api_domain, range }) => { if (!username) throw new MissingParamError(["username"]); - + try { const { data } = await axios.get( `https://${ diff --git a/tests/fetchTopLanguages.test.js b/tests/fetchTopLanguages.test.js index 54238df1..0792f28d 100644 --- a/tests/fetchTopLanguages.test.js +++ b/tests/fetchTopLanguages.test.js @@ -81,7 +81,10 @@ describe("FetchTopLanguages", () => { it("should fetch correct language data while excluding the 'test-repo-1' repository", async () => { mock.onPost("https://api.github.com/graphql").reply(200, data_langs); - let repo = await fetchTopLanguages("anuraghazra", exclude_repo=["test-repo-1"]); + let repo = await fetchTopLanguages( + "anuraghazra", + (exclude_repo = ["test-repo-1"]), + ); expect(repo).toStrictEqual({ HTML: { color: "#0f0", diff --git a/tests/fetchWakatime.test.js b/tests/fetchWakatime.test.js index 6255890c..ef8c64c3 100644 --- a/tests/fetchWakatime.test.js +++ b/tests/fetchWakatime.test.js @@ -207,7 +207,7 @@ describe("Wakatime fetcher", () => { mock.onGet(/\/https:\/\/wakatime\.com\/api/).reply(404, wakaTimeData); await expect(fetchWakatimeStats("noone")).rejects.toThrow( - "Missing params \"username\" make sure you pass the parameters in URL", + 'Missing params "username" make sure you pass the parameters in URL', ); }); }); diff --git a/tests/renderWakatimeCard.test.js b/tests/renderWakatimeCard.test.js index 51d63e6c..a6d7c85f 100644 --- a/tests/renderWakatimeCard.test.js +++ b/tests/renderWakatimeCard.test.js @@ -48,10 +48,15 @@ describe("Test Render Wakatime Card", () => { }); it('should show "no coding activitiy this week" message when there hasn not been activity', () => { - document.body.innerHTML = renderWakatimeCard({ - ...wakaTimeData.data, - languages: undefined - }, {}); - expect(document.querySelector(".stat").textContent).toBe("No coding activity this week") - }) + document.body.innerHTML = renderWakatimeCard( + { + ...wakaTimeData.data, + languages: undefined, + }, + {}, + ); + expect(document.querySelector(".stat").textContent).toBe( + "No coding activity this week", + ); + }); }); diff --git a/themes/index.js b/themes/index.js index 2508c9d2..4312496a 100644 --- a/themes/index.js +++ b/themes/index.js @@ -355,12 +355,12 @@ const themes = { bg_color: "09131B", border_color: "0c1a25", }, - "rose_pine":{ + rose_pine: { title_color: "9ccfd8", icon_color: "ebbcba", text_color: "e0def4", bg_color: "191724", - } + }, }; module.exports = themes; From 192170c1111333a2a6a65015c81ab1cdb4b86a6a Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 6 Sep 2022 10:00:21 +0200 Subject: [PATCH 21/88] ci: add empty issues closer action (#2004) Co-authored-by: Prashubh Atri Co-authored-by: Prashubh Atri --- .github/workflows/empty-issues-closer.yaml | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/empty-issues-closer.yaml diff --git a/.github/workflows/empty-issues-closer.yaml b/.github/workflows/empty-issues-closer.yaml new file mode 100644 index 00000000..5f050fe0 --- /dev/null +++ b/.github/workflows/empty-issues-closer.yaml @@ -0,0 +1,30 @@ +name: Close empty issues and templates +on: + issues: + types: + - reopened + - opened + - edited + +jobs: + closeEmptyIssuesAndTemplates: + name: Close empty issues + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 # NOTE: Retrieve issue templates. + - name: Run empty issues closer action + uses: rickstaa/empty-issues-closer-action@v1 + env: + github_token: ${{ secrets.GITHUB_TOKEN }} + with: + close_comment: + Closing this issue because it appears to be empty. Please update the + issue for it to be reopened. + open_comment: + Reopening this issue because the author provided more information. + check_templates: true + template_close_comment: + Closing this issue since the issue template was not filled in. + Please provide us with more information to have this issue reopened. + template_open_comment: + Reopening this issue because the author provided more information. From b0bb994ad36d7c187e2f934e36e34978e9de5e21 Mon Sep 17 00:00:00 2001 From: Artem Kostiuk Date: Fri, 16 Sep 2022 06:50:30 -0400 Subject: [PATCH 22/88] Fix #1170: Allow customizable width for GitHub Stats Card (#1334) * Change default stats card width with hide rank * Add tests for stats card with card_width * Add card_width Stats Card description to readme * fix: add icon width to stats-card min width calculation * fix: fixes rank circle padding problem This commit fixes a padding problem that was introduced in f9c0e0bff64f325235ccbf936c9d5f7a918ac790. In the new code, the padding around the rank circle will be 50 when the stats card is bigger than 450. When it is smaller than 450 the left and right padding will shrink equally. * style: run prettier * tests: add extra stats 'card_width' tests This commit makes sure we also test the stats card width for the case that the 'show_icons' option is enabled. * style: run prettier Co-authored-by: rickstaa --- api/index.js | 2 + readme.md | 1 + src/cards/stats-card.js | 91 +++++++++++++++++++++++------------ tests/renderStatsCard.test.js | 46 ++++++++++++++++++ 4 files changed, 108 insertions(+), 32 deletions(-) diff --git a/api/index.js b/api/index.js index 6563dbcc..b07464d0 100644 --- a/api/index.js +++ b/api/index.js @@ -17,6 +17,7 @@ module.exports = async (req, res) => { hide, hide_title, hide_border, + card_width, hide_rank, show_icons, count_private, @@ -65,6 +66,7 @@ module.exports = async (req, res) => { show_icons: parseBoolean(show_icons), hide_title: parseBoolean(hide_title), hide_border: parseBoolean(hide_border), + card_width: parseInt(card_width, 10), hide_rank: parseBoolean(hide_rank), include_all_commits: parseBoolean(include_all_commits), line_height, diff --git a/readme.md b/readme.md index f6578712..d8e4c7d4 100644 --- a/readme.md +++ b/readme.md @@ -187,6 +187,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_ - `hide_title` - _(boolean)_ +- `card_width` - Set the card's width manually _(number)_ - `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width - `show_icons` - _(boolean)_ - `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_ diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 9db45623..bbc48cfc 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -36,10 +36,10 @@ const createTextNode = ({ ${iconSvg} ${label}: - ${kValue} @@ -66,6 +66,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { show_icons = false, hide_title = false, hide_border = false, + card_width, hide_rank = false, include_all_commits = false, line_height = 25, @@ -174,26 +175,6 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { hide_rank ? 0 : 150, ); - // Conditionally rendered elements - const rankCircle = hide_rank - ? "" - : ` - - - - - ${rank.level} - - - `; - // the better user's score the the rank will be closer to zero so // subtracting 100 to get the progress in 100% const progress = 100 - rank.score; @@ -209,13 +190,20 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { return measureText(custom_title ? custom_title : i18n.t("statcard.title")); }; - const width = hide_rank - ? clampValue( - 50 /* padding */ + calculateTextWidth() * 2, - 270 /* min */, - Infinity, - ) - : 495; + /* + When hide_rank=true, the minimum card width is 270 px + the title length and padding. + When hide_rank=false, the minimum card_width is 340 px + the icon width (if show_icons=true). + Numbers are picked by looking at existing dimensions on production. + */ + const iconWidth = show_icons ? 16 : 0; + const minCardWidth = hide_rank + ? clampValue(50 /* padding */ + calculateTextWidth() * 2, 270, Infinity) + : 340 + iconWidth; + const defaultCardWidth = hide_rank ? 270 : 495; + let width = isNaN(card_width) ? defaultCardWidth : card_width; + if (width < minCardWidth) { + width = minCardWidth; + } const card = new Card({ customTitle: custom_title, @@ -238,6 +226,45 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { if (disable_animations) card.disableAnimations(); + /** + * Calculates the right rank circle translation values such that the rank circle + * keeps respecting the padding. + * + * width > 450: The default left padding of 50 px will be used. + * width < 450: The left and right padding will shrink equally. + * + * @returns {number} - Rank circle translation value. + */ + const calculateRankXTranslation = () => { + if (width < 450) { + return width - 95 + (45 * (450 - 340)) / 110; + } else { + return width - 95; + } + }; + + // Conditionally rendered elements + const rankCircle = hide_rank + ? "" + : ` + + + + + ${rank.level} + + + `; + // Accessibility Labels const labels = Object.keys(STATS) .filter((key) => !hide.includes(key)) @@ -264,7 +291,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { gap: lheight, direction: "column", }).join("")} - + `); }; diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js index aabf2f6b..09bd9b04 100644 --- a/tests/renderStatsCard.test.js +++ b/tests/renderStatsCard.test.js @@ -75,6 +75,52 @@ describe("Test renderStatsCard", () => { expect(queryByTestId(document.body, "rank-circle")).not.toBeInTheDocument(); }); + it("should render with custom width set", () => { + document.body.innerHTML = renderStatsCard(stats); + expect(document.querySelector("svg")).toHaveAttribute("width", "495"); + + document.body.innerHTML = renderStatsCard(stats, { card_width: 400 }); + expect(document.querySelector("svg")).toHaveAttribute("width", "400"); + }); + + it("should render with custom width set and limit minimum width", () => { + document.body.innerHTML = renderStatsCard(stats, { card_width: 1 }); + expect(document.querySelector("svg")).toHaveAttribute("width", "340"); + + document.body.innerHTML = renderStatsCard(stats, { + card_width: 1, + hide_rank: true, + }); + expect(document.querySelector("svg")).toHaveAttribute( + "width", + "305.81250000000006", + ); + + document.body.innerHTML = renderStatsCard(stats, { + card_width: 1, + hide_rank: true, + show_icons: true, + }); + expect(document.querySelector("svg")).toHaveAttribute( + "width", + "305.81250000000006", + ); + + document.body.innerHTML = renderStatsCard(stats, { + card_width: 1, + hide_rank: false, + show_icons: true, + }); + expect(document.querySelector("svg")).toHaveAttribute("width", "356"); + + document.body.innerHTML = renderStatsCard(stats, { + card_width: 1, + hide_rank: false, + show_icons: false, + }); + expect(document.querySelector("svg")).toHaveAttribute("width", "340"); + }); + it("should render default colors properly", () => { document.body.innerHTML = renderStatsCard(stats); From dc8852dd6ba0b5f86de0e4a13a031c30dcbd20fc Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 16 Sep 2022 12:55:35 +0200 Subject: [PATCH 23/88] refactor: change formatting command --- .github/workflows/test.yml | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d26607d3..0911168f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: - name: Run Prettier run: | - npm run prettier:check:ci + npm run format:check - name: Code Coverage uses: codecov/codecov-action@v1 diff --git a/package.json b/package.json index 110a4e80..be9e4354 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "theme-readme-gen": "node scripts/generate-theme-doc", "preview-theme": "node scripts/preview-theme", "generate-langs-json": "node scripts/generate-langs-json", - "prettier:check:ci": "./node_modules/.bin/prettier --check .", - "prettier:format": "./node_modules/.bin/prettier --write ." + "format": "./node_modules/.bin/prettier --write .", + "format:check": "./node_modules/.bin/prettier --check ." }, "author": "Anurag Hazra", "license": "MIT", From c1324b31bfc6da38c0f3c529b1562c80ec6ecd76 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 16 Sep 2022 13:09:19 +0200 Subject: [PATCH 24/88] feat: add 'exclude_repo' option to stats card (#1450) This commit allows users to exclude repositories for the stats card using the `exclude_repo` option. --- api/index.js | 2 ++ readme.md | 11 +++++---- src/fetchers/stats-fetcher.js | 22 +++++++++++++++--- tests/fetchStats.test.js | 43 +++++++++++++++++++++++++++++++---- 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/api/index.js b/api/index.js index b07464d0..20750059 100644 --- a/api/index.js +++ b/api/index.js @@ -29,6 +29,7 @@ module.exports = async (req, res) => { bg_color, theme, cache_seconds, + exclude_repo, custom_title, locale, disable_animations, @@ -50,6 +51,7 @@ module.exports = async (req, res) => { username, parseBoolean(count_private), parseBoolean(include_all_commits), + parseArray(exclude_repo), ); const cacheSeconds = clampValue( diff --git a/readme.md b/readme.md index d8e4c7d4..a4034ee2 100644 --- a/readme.md +++ b/readme.md @@ -67,12 +67,12 @@ Give india logo -Are you considering supporting the project by donating? Please DON'T!! +Are you considering supporting the project by donating? Please DON'T!! -Instead, Help India fight the 2nd deadly wave of COVID-19. -Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure. +Instead, Help India fight the 2nd deadly wave of COVID-19. +Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure. -Visit [https://indiafightscorona.giveindia.org](https://indiafightscorona.giveindia.org) and make a small donation to help us fight COVID and overcome this crisis. +Visit [https://indiafightscorona.giveindia.org](https://indiafightscorona.giveindia.org) and make a small donation to help us fight COVID and overcome this crisis. A small donation goes a long way. :heart:

@@ -171,7 +171,7 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_ - `border_radius` - Corner rounding on the card -> Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. +> Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. ##### Gradient in bg_color @@ -193,6 +193,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_ - `count_private` - Count private commits _(boolean)_ - `line_height` - Sets the line-height between text _(number)_ +- `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_ - `custom_title` - Sets a custom title for the card - `disable_animations` - Disables all animations in the card _(boolean)_ diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 2617137a..dc9be5bb 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -47,6 +47,7 @@ const fetcher = (variables, token) => { repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}) { totalCount nodes { + name stargazers { totalCount } @@ -108,6 +109,7 @@ async function fetchStats( username, count_private = false, include_all_commits = false, + exclude_repo = [], ) { if (!username) throw new MissingParamError(["username"]); @@ -133,6 +135,15 @@ async function fetchStats( const user = res.data.data.user; + // populate repoToHide map for quick lookup + // while filtering out + let repoToHide = {}; + if (exclude_repo) { + exclude_repo.forEach((repoName) => { + repoToHide[repoName] = true; + }); + } + stats.name = user.name || user.login; stats.totalIssues = user.openIssues.totalCount + user.closedIssues.totalCount; @@ -154,9 +165,14 @@ async function fetchStats( stats.totalPRs = user.pullRequests.totalCount; stats.contributedTo = user.repositoriesContributedTo.totalCount; - stats.totalStars = user.repositories.nodes.reduce((prev, curr) => { - return prev + curr.stargazers.totalCount; - }, 0); + // Retrieve stars while filtering out repositories to be hidden + stats.totalStars = user.repositories.nodes + .filter((data) => { + return !repoToHide[data.name]; + }) + .reduce((prev, curr) => { + return prev + curr.stargazers.totalCount; + }, 0); stats.rank = calculateRank({ totalCommits: stats.totalCommits, diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js index f732182f..fe2fd4d7 100644 --- a/tests/fetchStats.test.js +++ b/tests/fetchStats.test.js @@ -20,11 +20,11 @@ const data = { repositories: { totalCount: 5, nodes: [ - { stargazers: { totalCount: 100 } }, - { stargazers: { totalCount: 100 } }, - { stargazers: { totalCount: 100 } }, - { stargazers: { totalCount: 50 } }, - { stargazers: { totalCount: 50 } }, + { name: "test-repo-1", stargazers: { totalCount: 100 } }, + { name: "test-repo-2", stargazers: { totalCount: 100 } }, + { name: "test-repo-3", stargazers: { totalCount: 100 } }, + { name: "test-repo-4", stargazers: { totalCount: 50 } }, + { name: "test-repo-5", stargazers: { totalCount: 50 } }, ], }, }, @@ -134,4 +134,37 @@ describe("Test fetchStats", () => { rank, }); }); + + it("should exclude stars of the `test-repo-1` repository", async () => { + mock.onPost("https://api.github.com/graphql").reply(200, data); + mock + .onGet("https://api.github.com/search/commits?q=author:anuraghazra") + .reply(200, { total_count: 1000 }); + + let stats = await fetchStats( + "anuraghazra", + true, + true, + (exclude_repo = ["test-repo-1"]), + ); + const rank = calculateRank({ + totalCommits: 1050, + totalRepos: 5, + followers: 100, + contributions: 61, + stargazers: 300, + prs: 300, + issues: 200, + }); + + expect(stats).toStrictEqual({ + contributedTo: 61, + name: "Anurag Hazra", + totalCommits: 1050, + totalIssues: 200, + totalPRs: 300, + totalStars: 300, + rank, + }); + }); }); From eacc3cd29cecde23d488023ff8dc2326bc69c25d Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sat, 17 Sep 2022 11:28:50 +0200 Subject: [PATCH 25/88] fix: add missing StatsCard types --- src/cards/types.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cards/types.d.ts b/src/cards/types.d.ts index 4580a2ea..46bf6659 100644 --- a/src/cards/types.d.ts +++ b/src/cards/types.d.ts @@ -16,6 +16,7 @@ export type StatCardOptions = CommonOptions & { show_icons: boolean; hide_title: boolean; hide_border: boolean; + card_width: number; hide_rank: boolean; include_all_commits: boolean; line_height: number | string; From f9b9015ec2566b0a2afa930d97d9637019cd967f Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 17 Sep 2022 13:32:40 +0200 Subject: [PATCH 26/88] feat(stats): add 'not_bold' option to stats card (#1468) --- api/index.js | 2 ++ readme.md | 2 ++ src/cards/stats-card.js | 9 +++++++-- src/getStyles.js | 1 + tests/__snapshots__/renderWakatimeCard.test.js.snap | 2 ++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/api/index.js b/api/index.js index 20750059..2315ddda 100644 --- a/api/index.js +++ b/api/index.js @@ -26,6 +26,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + text_bold, bg_color, theme, cache_seconds, @@ -75,6 +76,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + text_bold: parseBoolean(text_bold), bg_color, theme, custom_title, diff --git a/readme.md b/readme.md index a4034ee2..3ef40724 100644 --- a/readme.md +++ b/readme.md @@ -195,6 +195,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `line_height` - Sets the line-height between text _(number)_ - `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_ - `custom_title` - Sets a custom title for the card +- `text_bold` - Use bold text _(boolean)_ - `disable_animations` - Disables all animations in the card _(boolean)_ #### Repo Card Exclusive Options: @@ -453,3 +454,4 @@ Thanks! :heart: Contributions are welcome! <3 Made with :heart: and JavaScript. + diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index bbc48cfc..30056b85 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -20,6 +20,7 @@ const createTextNode = ({ index, showIcons, shiftValuePos, + bold, }) => { const kValue = kFormatter(value); const staggerDelay = (index + 3) * 150; @@ -35,9 +36,11 @@ const createTextNode = ({ return ` ${iconSvg} - ${label}: + ${label}: { title_color, icon_color, text_color, + text_bold = true, bg_color, theme = "default", custom_title, @@ -165,6 +169,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { showIcons: show_icons, shiftValuePos: (!include_all_commits ? 50 : 35) + (isLongLocale ? 50 : 0), + bold: text_bold, }), ); diff --git a/src/getStyles.js b/src/getStyles.js index e5013e56..e76b51f4 100644 --- a/src/getStyles.js +++ b/src/getStyles.js @@ -85,6 +85,7 @@ const getStyles = ({ animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: ${iconColor}; diff --git a/tests/__snapshots__/renderWakatimeCard.test.js.snap b/tests/__snapshots__/renderWakatimeCard.test.js.snap index aa5641a0..bd625802 100644 --- a/tests/__snapshots__/renderWakatimeCard.test.js.snap +++ b/tests/__snapshots__/renderWakatimeCard.test.js.snap @@ -41,6 +41,7 @@ exports[`Test Render Wakatime Card should render correctly 1`] = ` animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: #4c71f2; @@ -202,6 +203,7 @@ exports[`Test Render Wakatime Card should render correctly with compact layout 1 animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: #4c71f2; From 40735124ed33b7759b3f25928519f6da5e369d7f Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sat, 17 Sep 2022 13:42:16 +0200 Subject: [PATCH 27/88] ci: change theme-preview action run condition (#1903) This commit makes sure that the theme-preview action only runs when a theme was added or changed. --- .github/workflows/preview-theme.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index f102b59c..db7e291d 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -5,8 +5,10 @@ on: types: [opened, synchronize, reopened] branches: - master - - theme-preview-script + - theme_preview_script + paths: - "themes/index.js" + - "scripts/preview-theme.js" jobs: build: From 107f7ca52c3431bf989e7c3624ad130e98cb4f5a Mon Sep 17 00:00:00 2001 From: rsk2 Date: Sat, 24 Sep 2022 13:50:54 +0530 Subject: [PATCH 28/88] Feature/grs 1955 change commonjs imports (#1995) * GRS-1955: Using ES6 import/export in src files * GRS-1955: Using ES6 import/export in test files * GRS-1955: Using ES6 import/export in themes index.js * GRS-1955: Readding blank line at end of top-languages-card.js * feat: fix test es6 import errors This commit makes sure jest is set-up to support es6. It also fixes several test errors and sorts the imports. * test: update test node version This commit makes sure node 16 is used in the github actions. * refactor: run prettier Co-authored-by: rickstaa --- .github/workflows/generate-theme-doc.yml | 2 +- .github/workflows/test.yml | 2 +- api/index.js | 18 +- api/pin.js | 15 +- api/top-langs.js | 18 +- api/wakatime.js | 16 +- jest.config.js | 4 +- package.json | 14 +- scripts/generate-langs-json.js | 6 +- scripts/generate-theme-doc.js | 8 +- scripts/preview-theme.js | 29 +- scripts/push-theme-readme.sh | 2 +- src/calculateRank.js | 7 +- src/cards/repo-card.js | 21 +- src/cards/stats-card.js | 23 +- src/cards/top-languages-card.js | 19 +- src/cards/wakatime-card.js | 22 +- src/common/Card.js | 7 +- src/common/I18n.js | 3 +- src/common/blacklist.js | 3 +- src/common/createProgressNode.js | 7 +- src/common/icons.js | 3 +- src/common/languageColors.json | 2 +- src/common/retryer.js | 5 +- src/common/utils.js | 10 +- src/fetchers/repo-fetcher.js | 7 +- src/fetchers/stats-fetcher.js | 23 +- src/fetchers/top-languages-fetcher.js | 11 +- src/fetchers/wakatime-fetcher.js | 9 +- src/getStyles.js | 6 +- src/translations.js | 4 +- .../renderWakatimeCard.test.js.snap | 268 ++++-------------- tests/api.test.js | 14 +- tests/calculateRank.test.js | 4 +- tests/card.test.js | 12 +- tests/fetchRepo.test.js | 8 +- tests/fetchStats.test.js | 17 +- tests/fetchTopLanguages.test.js | 13 +- tests/fetchWakatime.test.js | 32 +-- tests/flexLayout.test.js | 2 +- tests/pin.test.js | 13 +- tests/renderRepoCard.test.js | 10 +- tests/renderStatsCard.test.js | 17 +- tests/renderTopLanguages.test.js | 22 +- tests/renderWakatimeCard.test.js | 13 +- tests/retryer.test.js | 7 +- tests/top-langs.test.js | 13 +- tests/utils.test.js | 18 +- themes/index.js | 4 +- 49 files changed, 338 insertions(+), 475 deletions(-) diff --git a/.github/workflows/generate-theme-doc.yml b/.github/workflows/generate-theme-doc.yml index 9028044d..75fcb89b 100644 --- a/.github/workflows/generate-theme-doc.yml +++ b/.github/workflows/generate-theme-doc.yml @@ -16,7 +16,7 @@ jobs: - name: setup node uses: actions/setup-node@v1 with: - node-version: "12.x" + node-version: "16.x" - name: npm install, generate readme run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0911168f..f5eec351 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v1 with: - node-version: "12.x" + node-version: "16.x" - name: Install & Test run: | diff --git a/api/index.js b/api/index.js index 2315ddda..64231a59 100644 --- a/api/index.js +++ b/api/index.js @@ -1,17 +1,19 @@ -require("dotenv").config(); -const { +import { renderError, parseBoolean, parseArray, clampValue, CONSTANTS, -} = require("../src/common/utils"); -const fetchStats = require("../src/fetchers/stats-fetcher"); -const renderStatsCard = require("../src/cards/stats-card"); -const blacklist = require("../src/common/blacklist"); -const { isLocaleAvailable } = require("../src/translations"); +} from "../src/common/utils"; +import fetchStats from "../src/fetchers/stats-fetcher"; +import renderStatsCard from "../src/cards/stats-card"; +import blacklist from "../src/common/blacklist"; +import { isLocaleAvailable } from "../src/translations"; +import * as dotenv from "dotenv"; -module.exports = async (req, res) => { +dotenv.config(); + +export default async (req, res) => { const { username, hide, diff --git a/api/pin.js b/api/pin.js index f2761cb6..19023885 100644 --- a/api/pin.js +++ b/api/pin.js @@ -1,16 +1,15 @@ -require("dotenv").config(); -const { +import { renderError, parseBoolean, clampValue, CONSTANTS, -} = require("../src/common/utils"); -const fetchRepo = require("../src/fetchers/repo-fetcher"); -const renderRepoCard = require("../src/cards/repo-card"); -const blacklist = require("../src/common/blacklist"); -const { isLocaleAvailable } = require("../src/translations"); +} from "../src/common/utils"; +import fetchRepo from "../src/fetchers/repo-fetcher"; +import renderRepoCard from "../src/cards/repo-card"; +import blacklist from "../src/common/blacklist"; +import { isLocaleAvailable } from "../src/translations"; -module.exports = async (req, res) => { +export default async (req, res) => { const { username, repo, diff --git a/api/top-langs.js b/api/top-langs.js index 80802074..d83d9d6a 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -1,17 +1,19 @@ -require("dotenv").config(); -const { +import { renderError, clampValue, parseBoolean, parseArray, CONSTANTS, -} = require("../src/common/utils"); -const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher"); -const renderTopLanguages = require("../src/cards/top-languages-card"); -const blacklist = require("../src/common/blacklist"); -const { isLocaleAvailable } = require("../src/translations"); +} from "../src/common/utils"; +import fetchTopLanguages from "../src/fetchers/top-languages-fetcher"; +import { renderTopLanguages } from "../src/cards/top-languages-card"; +import blacklist from "../src/common/blacklist"; +import { isLocaleAvailable } from "../src/translations"; +import * as dotenv from "dotenv"; -module.exports = async (req, res) => { +dotenv.config(); + +export default async (req, res) => { const { username, hide, diff --git a/api/wakatime.js b/api/wakatime.js index 18b52189..8e27e2f2 100644 --- a/api/wakatime.js +++ b/api/wakatime.js @@ -1,16 +1,18 @@ -require("dotenv").config(); -const { +import { renderError, parseBoolean, clampValue, parseArray, CONSTANTS, -} = require("../src/common/utils"); -const { isLocaleAvailable } = require("../src/translations"); -const { fetchWakatimeStats } = require("../src/fetchers/wakatime-fetcher"); -const wakatimeCard = require("../src/cards/wakatime-card"); +} from "../src/common/utils"; +import { isLocaleAvailable } from "../src/translations"; +import fetchWakatimeStats from "../src/fetchers/wakatime-fetcher"; +import wakatimeCard from "../src/cards/wakatime-card"; +import * as dotenv from "dotenv"; -module.exports = async (req, res) => { +dotenv.config(); + +export default async (req, res) => { const { username, title_color, diff --git a/jest.config.js b/jest.config.js index 0d51c47d..7fbe69b6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,5 @@ -module.exports = { +export default { clearMocks: true, + transform: {}, + testEnvironment: "jsdom", }; diff --git a/package.json b/package.json index be9e4354..4cfcd074 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,11 @@ "version": "1.0.0", "description": "Dynamically generate stats for your github readmes", "main": "index.js", + "type": "module", "scripts": { - "test": "jest --coverage", - "test:watch": "jest --watch", + "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage", + "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch", + "test:update:snapshot": "node --experimental-vm-modules node_modules/jest/bin/jest.js -u", "theme-readme-gen": "node scripts/generate-theme-doc", "preview-theme": "node scripts/preview-theme", "generate-langs-json": "node scripts/generate-langs-json", @@ -20,14 +22,15 @@ "devDependencies": { "@actions/core": "^1.2.4", "@actions/github": "^4.0.0", - "@testing-library/dom": "^7.20.0", - "@testing-library/jest-dom": "^5.11.0", + "@testing-library/dom": "^8.17.1", + "@testing-library/jest-dom": "^5.16.5", + "jest-environment-jsdom": "^29.0.3", + "jest": "^29.0.3", "@uppercod/css-to-object": "^1.1.1", "axios-mock-adapter": "^1.18.1", "color-contrast-checker": "^2.1.0", "hjson": "^3.2.2", "husky": "^4.2.5", - "jest": "^26.1.0", "js-yaml": "^4.1.0", "lodash.snakecase": "^4.1.1", "parse-diff": "^0.7.0", @@ -38,6 +41,7 @@ "dotenv": "^8.2.0", "emoji-name-map": "^1.2.8", "github-username-regex": "^1.0.0", + "upgrade": "^1.1.0", "word-wrap": "^1.2.3" }, "husky": { diff --git a/scripts/generate-langs-json.js b/scripts/generate-langs-json.js index bd210a3c..803d60b1 100644 --- a/scripts/generate-langs-json.js +++ b/scripts/generate-langs-json.js @@ -1,6 +1,6 @@ -const fs = require("fs"); -const jsYaml = require("js-yaml"); -const axios = require("axios"); +import axios from "axios"; +import fs from "fs"; +import jsYaml from "js-yaml"; const LANGS_FILEPATH = "./src/common/languageColors.json"; diff --git a/scripts/generate-theme-doc.js b/scripts/generate-theme-doc.js index fcb3c5ee..e8b83ad2 100644 --- a/scripts/generate-theme-doc.js +++ b/scripts/generate-theme-doc.js @@ -1,5 +1,5 @@ -const theme = require("../themes/index"); -const fs = require("fs"); +import fs from "fs"; +import { themes } from "../themes/index"; const TARGET_FILE = "./themes/README.md"; const REPO_CARD_LINKS_FLAG = ""; @@ -54,7 +54,7 @@ const createStatMdLink = (theme) => { }; const generateLinks = (fn) => { - return Object.keys(theme) + return Object.keys(themes) .map((name) => fn(name)) .join(""); }; @@ -65,7 +65,7 @@ const createTableItem = ({ link, label, isRepoCard }) => { }; const generateTable = ({ isRepoCard }) => { const rows = []; - const themes = Object.keys(theme).filter( + const themes = Object.keys(themes).filter( (name) => name !== (!isRepoCard ? "default_repocard" : "default"), ); diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index e4422ecd..33ee96bc 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -1,11 +1,12 @@ -const core = require("@actions/core"); -const github = require("@actions/github"); -const parse = require("parse-diff"); -const Hjson = require("hjson"); -const snakeCase = require("lodash.snakecase"); -const ColorContrastChecker = require("color-contrast-checker"); +import core from "@actions/core"; +import github from "@actions/github"; +import ColorContrastChecker from "color-contrast-checker"; +import * as dotenv from "dotenv"; +import Hjson from "hjson"; +import snakeCase from "lodash.snakecase"; +import parse from "parse-diff"; -require("dotenv").config(); +dotenv.config(); const OWNER = "anuraghazra"; const REPO = "github-readme-stats"; @@ -76,10 +77,10 @@ function getGrsLink(colors) { } const themeContribGuidelines = ` - \rHi, thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). + \rHi, thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). \rWe are currently only accepting color combinations from any VSCode theme or themes which have good color combination to minimize bloating the themes collection. - \r> Also note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization) + \r> Also note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization) `; async function run() { @@ -128,7 +129,7 @@ async function run() { issue_number: pullRequestId, body: ` \r**${COMMENT_TITLE}** - + \rCannot create theme preview ${themeContribGuidelines} @@ -167,16 +168,16 @@ async function run() { owner: OWNER, repo: REPO, body: ` - \r**${COMMENT_TITLE}** - + \r**${COMMENT_TITLE}** + \r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")} \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} - + \r[Preview Link](${url}) \r[![](${url})](${url}) - + ${themeContribGuidelines} `, }); diff --git a/scripts/push-theme-readme.sh b/scripts/push-theme-readme.sh index 5223dd11..946096bd 100755 --- a/scripts/push-theme-readme.sh +++ b/scripts/push-theme-readme.sh @@ -11,4 +11,4 @@ git checkout -b $BRANCH_NAME git add --all git commit --message "docs(theme): Auto update theme readme" || exit 0 git remote add origin-$BRANCH_NAME https://${PERSONAL_TOKEN}@github.com/${GH_REPO}.git -git push --force --quiet --set-upstream origin-$BRANCH_NAME $BRANCH_NAME \ No newline at end of file +git push --force --quiet --set-upstream origin-$BRANCH_NAME $BRANCH_NAME diff --git a/src/calculateRank.js b/src/calculateRank.js index 742b9ab1..bbfece15 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -57,8 +57,8 @@ function calculateRank({ issues * ISSUES_OFFSET + stargazers * STARS_OFFSET + prs * PRS_OFFSET + - followers * FOLLOWERS_OFFSET + - totalRepos * REPO_OFFSET + followers * FOLLOWERS_OFFSET + + totalRepos * REPO_OFFSET ) / 100; const normalizedScore = normalcdf(score, TOTAL_VALUES, ALL_OFFSETS) * 100; @@ -74,4 +74,5 @@ function calculateRank({ return { level, score: normalizedScore }; } -module.exports = calculateRank; +export { calculateRank }; +export default calculateRank; diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 034ee1f6..61073bee 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -1,17 +1,17 @@ // @ts-check -const { - kFormatter, +import { Card } from "../common/Card"; +import { I18n } from "../common/I18n"; +import { icons } from "../common/icons"; +import { encodeHTML, - getCardColors, flexLayout, - wrapTextMultiline, + getCardColors, + kFormatter, measureText, parseEmojis, -} = require("../common/utils"); -const I18n = require("../common/I18n"); -const Card = require("../common/Card"); -const icons = require("../common/icons"); -const { repoCardLocales } = require("../translations"); + wrapTextMultiline, +} from "../common/utils"; +import { repoCardLocales } from "../translations"; /** * @param {string} label @@ -185,4 +185,5 @@ const renderRepoCard = (repo, options = {}) => { `); }; -module.exports = renderRepoCard; +export { renderRepoCard }; +export default renderRepoCard; diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 30056b85..962c1e4f 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -1,16 +1,16 @@ // @ts-check -const I18n = require("../common/I18n"); -const Card = require("../common/Card"); -const icons = require("../common/icons"); -const { getStyles } = require("../getStyles"); -const { statCardLocales } = require("../translations"); -const { - kFormatter, - flexLayout, +import { Card } from "../common/Card"; +import { I18n } from "../common/I18n"; +import { icons } from "../common/icons"; +import { clampValue, - measureText, + flexLayout, getCardColors, -} = require("../common/utils"); + kFormatter, + measureText, +} from "../common/utils"; +import { getStyles } from "../getStyles"; +import { statCardLocales } from "../translations"; const createTextNode = ({ icon, @@ -300,4 +300,5 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { `); }; -module.exports = renderStatsCard; +export { renderStatsCard }; +export default renderStatsCard; diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index b2f5c362..d8c18253 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -1,16 +1,16 @@ // @ts-check -const Card = require("../common/Card"); -const I18n = require("../common/I18n"); -const { langCardLocales } = require("../translations"); -const { createProgressNode } = require("../common/createProgressNode"); -const { +import { Card } from "../common/Card"; +import { createProgressNode } from "../common/createProgressNode"; +import { I18n } from "../common/I18n"; +import { + chunkArray, clampValue, - getCardColors, flexLayout, + getCardColors, lowercaseTrim, measureText, - chunkArray, -} = require("../common/utils"); +} from "../common/utils"; +import { langCardLocales } from "../translations"; const DEFAULT_CARD_WIDTH = 300; const MIN_CARD_WIDTH = 230; @@ -311,5 +311,4 @@ const renderTopLanguages = (topLangs, options = {}) => { `); }; -module.exports = renderTopLanguages; -module.exports.MIN_CARD_WIDTH = MIN_CARD_WIDTH; +export { renderTopLanguages, MIN_CARD_WIDTH }; diff --git a/src/cards/wakatime-card.js b/src/cards/wakatime-card.js index 5ab2f29d..2f30b941 100644 --- a/src/cards/wakatime-card.js +++ b/src/cards/wakatime-card.js @@ -1,16 +1,16 @@ // @ts-check -const Card = require("../common/Card"); -const I18n = require("../common/I18n"); -const { getStyles } = require("../getStyles"); -const { wakatimeCardLocales } = require("../translations"); -const languageColors = require("../common/languageColors.json"); -const { createProgressNode } = require("../common/createProgressNode"); -const { +import { Card } from "../common/Card"; +import { createProgressNode } from "../common/createProgressNode"; +import { I18n } from "../common/I18n"; +import languageColors from "../common/languageColors.json"; +import { clampValue, - getCardColors, flexLayout, + getCardColors, lowercaseTrim, -} = require("../common/utils"); +} from "../common/utils"; +import { getStyles } from "../getStyles"; +import { wakatimeCardLocales } from "../translations"; /** * @param {{color: string, text: string}} param0 @@ -314,5 +314,5 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => { `); }; -module.exports = renderWakatimeCard; -exports.createProgressNode = createProgressNode; +export { renderWakatimeCard }; +export default renderWakatimeCard; diff --git a/src/common/Card.js b/src/common/Card.js index 2cc84553..24ec4430 100644 --- a/src/common/Card.js +++ b/src/common/Card.js @@ -1,5 +1,5 @@ -const { getAnimations } = require("../getStyles"); -const { flexLayout, encodeHTML } = require("../common/utils"); +import { encodeHTML, flexLayout } from "../common/utils"; +import { getAnimations } from "../getStyles"; class Card { /** @@ -216,4 +216,5 @@ class Card { } } -module.exports = Card; +export { Card }; +export default Card; diff --git a/src/common/I18n.js b/src/common/I18n.js index e28f6050..7f607cd9 100644 --- a/src/common/I18n.js +++ b/src/common/I18n.js @@ -18,4 +18,5 @@ class I18n { } } -module.exports = I18n; +export { I18n }; +export default I18n; diff --git a/src/common/blacklist.js b/src/common/blacklist.js index 3ef635c4..752ef943 100644 --- a/src/common/blacklist.js +++ b/src/common/blacklist.js @@ -1,3 +1,4 @@ const blacklist = ["renovate-bot", "technote-space", "sw-yx"]; -module.exports = blacklist; +export { blacklist }; +export default blacklist; diff --git a/src/common/createProgressNode.js b/src/common/createProgressNode.js index 0f152645..80abc8ff 100644 --- a/src/common/createProgressNode.js +++ b/src/common/createProgressNode.js @@ -1,4 +1,4 @@ -const { clampValue } = require("../common/utils"); +import { clampValue } from "../common/utils"; const createProgressNode = ({ x, @@ -16,7 +16,7 @@ const createProgressNode = ({ @@ -25,4 +25,5 @@ const createProgressNode = ({ `; }; -exports.createProgressNode = createProgressNode; +export { createProgressNode }; +export default createProgressNode; diff --git a/src/common/icons.js b/src/common/icons.js index 7b7e5075..5282a93e 100644 --- a/src/common/icons.js +++ b/src/common/icons.js @@ -8,4 +8,5 @@ const icons = { fork: ``, }; -module.exports = icons; +export { icons }; +export default icons; diff --git a/src/common/languageColors.json b/src/common/languageColors.json index 12c85bd5..3c1370f7 100644 --- a/src/common/languageColors.json +++ b/src/common/languageColors.json @@ -499,4 +499,4 @@ "wdl": "#42f1f4", "wisp": "#7582D1", "xBase": "#403a40" -} \ No newline at end of file +} diff --git a/src/common/retryer.js b/src/common/retryer.js index b06d3e29..f37aaa40 100644 --- a/src/common/retryer.js +++ b/src/common/retryer.js @@ -1,4 +1,4 @@ -const { logger, CustomError } = require("../common/utils"); +import { CustomError, logger } from "../common/utils"; const retryer = async (fetcher, variables, retries = 0) => { if (retries > 7) { @@ -40,4 +40,5 @@ const retryer = async (fetcher, variables, retries = 0) => { } }; -module.exports = retryer; +export { retryer }; +export default retryer; diff --git a/src/common/utils.js b/src/common/utils.js index 2ad18ddd..042b6358 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1,8 +1,8 @@ // @ts-check -const axios = require("axios"); -const wrap = require("word-wrap"); -const themes = require("../../themes"); -const toEmoji = require("emoji-name-map"); +import axios from "axios"; +import toEmoji from "emoji-name-map"; +import wrap from "word-wrap"; +import { themes } from "../../themes"; /** * @param {string} message @@ -370,7 +370,7 @@ function parseEmojis(str) { }); } -module.exports = { +export { renderError, kFormatter, encodeHTML, diff --git a/src/fetchers/repo-fetcher.js b/src/fetchers/repo-fetcher.js index 0bad5f2b..c55c3d71 100644 --- a/src/fetchers/repo-fetcher.js +++ b/src/fetchers/repo-fetcher.js @@ -1,6 +1,6 @@ // @ts-check -const retryer = require("../common/retryer"); -const { request, MissingParamError } = require("../common/utils"); +import { retryer } from "../common/retryer"; +import { MissingParamError, request } from "../common/utils"; /** * @param {import('Axios').AxiosRequestHeaders} variables @@ -97,4 +97,5 @@ async function fetchRepo(username, reponame) { } } -module.exports = fetchRepo; +export { fetchRepo }; +export default fetchRepo; diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index dc9be5bb..cb13255b 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -1,17 +1,17 @@ // @ts-check -const axios = require("axios").default; -const githubUsernameRegex = require("github-username-regex"); - -const retryer = require("../common/retryer"); -const calculateRank = require("../calculateRank"); -const { - request, - logger, +import axios from "axios"; +import * as dotenv from "dotenv"; +import githubUsernameRegex from "github-username-regex"; +import { calculateRank } from "../calculateRank"; +import { retryer } from "../common/retryer"; +import { CustomError, + logger, MissingParamError, -} = require("../common/utils"); + request, +} from "../common/utils"; -require("dotenv").config(); +dotenv.config(); /** * @param {import('axios').AxiosRequestHeaders} variables @@ -187,4 +187,5 @@ async function fetchStats( return stats; } -module.exports = fetchStats; +export { fetchStats }; +export default fetchStats; diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 7c4c8785..555fb063 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -1,7 +1,9 @@ // @ts-check -const { request, logger, MissingParamError } = require("../common/utils"); -const retryer = require("../common/retryer"); -require("dotenv").config(); +import * as dotenv from "dotenv"; +import { retryer } from "../common/retryer"; +import { logger, MissingParamError, request } from "../common/utils"; + +dotenv.config(); /** * @param {import('Axios').AxiosRequestHeaders} variables @@ -104,4 +106,5 @@ async function fetchTopLanguages(username, exclude_repo = []) { return topLangs; } -module.exports = fetchTopLanguages; +export { fetchTopLanguages }; +export default fetchTopLanguages; diff --git a/src/fetchers/wakatime-fetcher.js b/src/fetchers/wakatime-fetcher.js index fe06c638..8c40deb4 100644 --- a/src/fetchers/wakatime-fetcher.js +++ b/src/fetchers/wakatime-fetcher.js @@ -1,5 +1,5 @@ -const axios = require("axios"); -const { MissingParamError } = require("../common/utils"); +import axios from "axios"; +import { MissingParamError } from "../common/utils"; /** * @param {{username: string, api_domain: string, range: string}} props @@ -26,6 +26,5 @@ const fetchWakatimeStats = async ({ username, api_domain, range }) => { } }; -module.exports = { - fetchWakatimeStats, -}; +export { fetchWakatimeStats }; +export default fetchWakatimeStats; diff --git a/src/getStyles.js b/src/getStyles.js index e76b51f4..3c77787e 100644 --- a/src/getStyles.js +++ b/src/getStyles.js @@ -81,7 +81,7 @@ const getStyles = ({ animation: fadeInAnimation 0.3s ease-in-out forwards; } .rank-text { - font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor}; + font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor}; animation: scaleInAnimation 0.3s ease-in-out forwards; } @@ -91,7 +91,7 @@ const getStyles = ({ fill: ${iconColor}; display: ${!!show_icons ? "block" : "none"}; } - + .rank-circle-rim { stroke: ${titleColor}; fill: none; @@ -113,4 +113,4 @@ const getStyles = ({ `; }; -module.exports = { getStyles, getAnimations }; +export { getStyles, getAnimations }; diff --git a/src/translations.js b/src/translations.js index 31b2d218..c91dcb5e 100644 --- a/src/translations.js +++ b/src/translations.js @@ -1,4 +1,4 @@ -const { encodeHTML } = require("./common/utils"); +import { encodeHTML } from "./common/utils"; const statCardLocales = ({ name, apostrophe }) => { const encodedName = encodeHTML(name); @@ -358,7 +358,7 @@ function isLocaleAvailable(locale) { return availableLocales.includes(locale.toLowerCase()); } -module.exports = { +export { isLocaleAvailable, availableLocales, statCardLocales, diff --git a/tests/__snapshots__/renderWakatimeCard.test.js.snap b/tests/__snapshots__/renderWakatimeCard.test.js.snap index bd625802..69e22e4a 100644 --- a/tests/__snapshots__/renderWakatimeCard.test.js.snap +++ b/tests/__snapshots__/renderWakatimeCard.test.js.snap @@ -1,180 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Test Render Wakatime Card should render correctly 1`] = ` -" - - - - - - - - - - - - - Wakatime Stats - - - - - - - - - - Other: - 19 mins - - - - - - - - - - - TypeScript: - 1 min - - - - - - - - - - - - - - " -`; +exports[`Test Render Wakatime Card should render correctly 1`] = `[Function]`; exports[`Test Render Wakatime Card should render correctly with compact layout 1`] = ` " - - + + #${colorValue}`, + ); + invalidColors = true; + } + } + } + } + if (invalidColors) { + themeValid[theme] = false; + previewBody += ` + \r### ${ + themeName.charAt(0).toUpperCase() + themeName.slice(1) + } theme preview + + \r${warnings.map((warning) => `- :warning: ${warning}.\n`).join("")} + \r${errors.map((error) => `- :x: ${error}.\n`).join("")} - \r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")} + \r>:x: Cannot create theme preview. + `; + continue; + } - \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} + // Check color contrast. + debug("Theme preview body: Check color contrast..."); + const titleColor = colors.title_color; + const iconColor = colors.icon_color; + const textColor = colors.text_color; + const bgColor = colors.bg_color; + const url = getGRSLink(colors); + const colorPairs = { + title_color: [titleColor, bgColor], + icon_color: [iconColor, bgColor], + text_color: [textColor, bgColor], + }; + Object.keys(colorPairs).forEach((item) => { + const color1 = colorPairs[item][0]; + const color2 = colorPairs[item][1]; + if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) { + const permalink = getWebAimLink(color1, color2); + warnings.push( + `\`${item}\` does not pass [AA contrast ratio](${permalink})`, + ); + themeValid[theme] = false; + } + }); - \r[Preview Link](${url}) + // Create theme preview body. + debug("Theme preview body: Create theme preview body..."); + previewBody += ` + \r### ${ + themeName.charAt(0).toUpperCase() + themeName.slice(1) + } theme preview + + \r${warnings.map((warning) => `- :warning: ${warning}.\n`).join("")} - \r[![](${url})](${url}) + \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} - ${themeContribGuidelines} - `, - }); + \r[Preview Link](${url}) + + \r[![](${url})](${url}) + `; + } + + // Create comment body. + debug("Create comment body..."); + commentBody += ` + \r${ + Object.values(themeValid).every((value) => value) + ? THEME_PR_SUCCESS_TEXT + : THEME_PR_FAIL_TEXT + } + \r## Test results + \r${Object.entries(themeValid) + .map( + ([key, value]) => `- ${value ? ":heavy_check_mark:" : ":x:"} ${key}`, + ) + .join("\r")} + + \r${ + Object.values(themeValid).every((value) => value) + ? "**Result:** :heavy_check_mark: All themes are valid." + : "**Result:** :x: Some themes are invalid.\n\n" + FAIL_TEXT + } + + \r## Details + \r${previewBody} + `; + + // Create or update theme-preview comment. + debug("Create or update theme-preview comment..."); + let comment_url; + if (!dryRun) { + comment_url = await upsertComment(octokit, { + comment_id: comment?.id, + issue_number: pullRequestId, + owner, + repo, + body: commentBody, + }); + } else { + info(`DRY_RUN: Comment body: ${commentBody}`); + comment_url = ""; + } + + // Change review state and add/remove `invalid` label based on theme PR validity. + debug( + "Change review state and add/remove `invalid` label based on whether all themes passed...", + ); + const themesValid = Object.values(themeValid).every((value) => value); + const reviewState = themesValid ? "APPROVE" : "REQUEST_CHANGES"; + const reviewReason = themesValid + ? undefined + : INVALID_REVIEW_COMMENT(comment_url); + if (!dryRun) { + await addReview( + octokit, + pullRequestId, + owner, + repo, + reviewState, + reviewReason, + ); + await addRemoveLabel( + octokit, + pullRequestId, + owner, + repo, + "invalid", + !themesValid, + ); + } else { + info(`DRY_RUN: Review state: ${reviewState}`); + info(`DRY_RUN: Review reason: ${reviewReason}`); + } } catch (error) { - console.log(error); + setFailed(error.message); } -} +}; run(); From d5d8912954a1b7fe4203777f567be7ab428a976c Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 2 Oct 2022 10:33:29 +0200 Subject: [PATCH 38/88] ci: improve theme preview action (#2088) This commit makes sure that 4,5,6,8 digit hex colors are also accepted. It further also includes the border_color attribute in the tests. --- scripts/preview-theme.js | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index ea511a9e..c6312b40 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -12,6 +12,7 @@ import Hjson from "hjson"; import snakeCase from "lodash.snakecase"; import parse from "parse-diff"; import { inspect } from "util"; +import { isValidHexColor } from "../src/common/utils.js"; import { themes } from "../themes/index.js"; // Script variables @@ -33,11 +34,11 @@ const THEME_CONTRIB_GUIDELINESS = ` \r> Also, note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection, you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization). `; -const AVAILABLE_COLOR_PROPS = [ - "bg_color", +const REQUIRED_COLOR_PROPS = [ + "title_color", "icon_color", "text_color", - "title_color", + "bg_color", ]; const INVALID_REVIEW_COMMENT = (commentUrl) => `Some themes are invalid. See the [Automated Theme Preview](${commentUrl}) comment above for more information.`; @@ -320,20 +321,6 @@ const parseJSON = (json) => { } }; -/** - * Check if string is a valid hex color. - * - * @param {string} str String to check. - * @returns {boolean} Whether the string is a valid hex color. - */ -const isHexColor = (str, prefix = false) => { - if (prefix) { - return /^#[a-f0-9]{6}$/i.exec(str); - } else { - return /^[a-f0-9]{6}$/i.exec(str); - } -}; - /** * Check whether the theme name is still available. * @param {string} name Theme name. @@ -431,7 +418,7 @@ const run = async () => { warning.push("Theme colors are missing"); invalidColors = true; } else { - const missingKeys = AVAILABLE_COLOR_PROPS.filter( + const missingKeys = REQUIRED_COLOR_PROPS.filter( (x) => !Object.keys(colors).includes(x), ); if (missingKeys.length > 0) { @@ -446,7 +433,7 @@ const run = async () => { `Theme color property \`${colorKey}\` should not start with '#'`, ); invalidColors = true; - } else if (!isHexColor(colorValue)) { + } else if (!isValidHexColor(colorValue)) { errors.push( `Theme color property \`${colorKey}\` is not a valid hex color: #${colorValue}`, ); @@ -476,6 +463,7 @@ const run = async () => { const iconColor = colors.icon_color; const textColor = colors.text_color; const bgColor = colors.bg_color; + const borderColor = colors.border_color; const url = getGRSLink(colors); const colorPairs = { title_color: [titleColor, bgColor], @@ -503,7 +491,9 @@ const run = async () => { \r${warnings.map((warning) => `- :warning: ${warning}.\n`).join("")} - \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} + \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor}${ + borderColor ? ` | border_color: #${borderColor}` : "" + } \r[Preview Link](${url}) From aaf710c024632cbcc782815b43d2953885b2a0dd Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 10:35:11 +0200 Subject: [PATCH 39/88] ci: fix e2e test --- tests/e2e/e2e.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index 91c9c38f..8a29712e 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -16,7 +16,7 @@ const REPO = "dummy-cra"; const USER = "grsdummy"; const STATS_DATA = { name: "grsdummy", - totalPRs: 1, + totalPRs: 2, totalCommits: 2, totalIssues: 1, totalStars: 1, From f86059f097fc624a44a037a05efee597e2abac7f Mon Sep 17 00:00:00 2001 From: Jongwoo Han Date: Sun, 2 Oct 2022 17:38:07 +0900 Subject: [PATCH 40/88] chore: Update workflows to cache dependencies (#2083) --- .github/workflows/e2e-test.yml | 12 ++++++++++++ .github/workflows/generate-theme-doc.yml | 13 +++++++++---- .github/workflows/preview-theme.yml | 12 ++++++++++-- .github/workflows/test.yml | 10 +++++++--- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 4699b67d..804a2008 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -8,12 +8,24 @@ jobs: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] + steps: - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - name: Install dependencies run: npm ci env: CI: true + - name: Run end-to-end tests. run: npm run test:e2e env: diff --git a/.github/workflows/generate-theme-doc.yml b/.github/workflows/generate-theme-doc.yml index 23ea0210..ef076f3a 100644 --- a/.github/workflows/generate-theme-doc.yml +++ b/.github/workflows/generate-theme-doc.yml @@ -10,13 +10,18 @@ on: jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] steps: - - uses: actions/checkout@v1 - - name: setup node - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 with: - node-version: "16.x" + node-version: ${{ matrix.node-version }} + cache: npm - name: npm install, generate readme run: | diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index 709cba4c..5c5cf9a1 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -11,16 +11,24 @@ on: jobs: previewTheme: runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] name: Install & Preview steps: - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + + - name: Setup Node + uses: actions/setup-node@v3 with: - node-version: 16 + node-version: ${{ matrix.node-version }} + cache: npm + - uses: bahmutov/npm-install@v1 with: useLockFile: false + - run: npm run preview-theme env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 57fabc5e..c051f96b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,14 +11,18 @@ on: jobs: build: runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Node - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: - node-version: "16.x" + node-version: ${{ matrix.node-version }} + cache: npm - name: Install & Test run: | From 098331069a271d93db8de3e87daf394c66fc9288 Mon Sep 17 00:00:00 2001 From: Oscar Dominguez Date: Sun, 2 Oct 2022 10:51:37 +0200 Subject: [PATCH 41/88] ci(label-pr): upgrade actions/labeler to v4 (#2080) Co-authored-by: rickstaa --- .github/workflows/label-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-pr.yml b/.github/workflows/label-pr.yml index 93cb767b..c401d32e 100644 --- a/.github/workflows/label-pr.yml +++ b/.github/workflows/label-pr.yml @@ -6,6 +6,6 @@ jobs: triage: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v2 + - uses: actions/labeler@v4 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" From 51e7887b9553cf97c6e74e9655597a33ba696f0b Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 10:52:33 +0200 Subject: [PATCH 42/88] ci: fix e2e test --- tests/e2e/e2e.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index 8a29712e..7e59acb4 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -20,7 +20,7 @@ const STATS_DATA = { totalCommits: 2, totalIssues: 1, totalStars: 1, - contributedTo: 1, + contributedTo: 2, rank: { level: "A+", score: 51.01622937949586, From b8faef6857c1c9c9baad3c64daa8a8807a8b0205 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 2 Oct 2022 11:05:13 +0200 Subject: [PATCH 43/88] ci: add stale theme pull request closer action push (#2067) This commit adds the `stale-theme-pr-closer` closer action. This action is used to close theme pull requests with an `invalid` label that has been stale for a given number of `STALE_DAYS`. --- .github/workflows/e2e-test.yml | 3 +- .github/workflows/empty-issues-closer.yaml | 1 + .github/workflows/generate-theme-doc.yml | 4 +- .github/workflows/preview-theme.yml | 3 +- .github/workflows/stale-theme-pr-closer.yaml | 30 ++++ .github/workflows/test.yml | 2 +- package.json | 1 + scripts/close-stale-theme-prs.js | 161 +++++++++++++++++++ scripts/helpers.js | 40 +++++ scripts/preview-theme.js | 40 +---- 10 files changed, 242 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/stale-theme-pr-closer.yaml create mode 100644 scripts/close-stale-theme-prs.js create mode 100644 scripts/helpers.js diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 804a2008..b9d275f5 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -3,10 +3,11 @@ on: deployment_status: jobs: - preview: + e2eTests: if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' + name: Perform 2e2 tests runs-on: ubuntu-latest strategy: matrix: diff --git a/.github/workflows/empty-issues-closer.yaml b/.github/workflows/empty-issues-closer.yaml index 5f050fe0..b20eef32 100644 --- a/.github/workflows/empty-issues-closer.yaml +++ b/.github/workflows/empty-issues-closer.yaml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 # NOTE: Retrieve issue templates. + - name: Run empty issues closer action uses: rickstaa/empty-issues-closer-action@v1 env: diff --git a/.github/workflows/generate-theme-doc.yml b/.github/workflows/generate-theme-doc.yml index ef076f3a..d5fac063 100644 --- a/.github/workflows/generate-theme-doc.yml +++ b/.github/workflows/generate-theme-doc.yml @@ -1,5 +1,4 @@ name: Generate Theme Readme - on: push: branches: @@ -8,8 +7,9 @@ on: - "themes/index.js" jobs: - build: + generateThemeDoc: runs-on: ubuntu-latest + name: Generate theme doc strategy: matrix: node-version: [16.x] diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index 5c5cf9a1..132d4eb7 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -1,5 +1,4 @@ name: Theme preview - on: pull_request_target: types: [opened, edited, reopened, synchronize] @@ -10,11 +9,11 @@ on: jobs: previewTheme: + name: Install & Preview runs-on: ubuntu-latest strategy: matrix: node-version: [16.x] - name: Install & Preview steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/stale-theme-pr-closer.yaml b/.github/workflows/stale-theme-pr-closer.yaml new file mode 100644 index 00000000..8b1c78b4 --- /dev/null +++ b/.github/workflows/stale-theme-pr-closer.yaml @@ -0,0 +1,30 @@ +name: Close stale theme pull requests that have the 'invalid' label. +on: + schedule: + - cron: "0 0 */7 * *" + +jobs: + closeOldThemePrs: + name: Close stale 'invalid' theme PRs + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [16.x] + + steps: + - uses: actions/checkout@v3 + + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: npm + + - uses: bahmutov/npm-install@v1 + with: + useLockFile: false + + - run: npm run close-stale-theme-prs + env: + STALE_DAYS: 15 + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c051f96b..fe34668d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,4 @@ name: Test - on: push: branches: @@ -10,6 +9,7 @@ on: jobs: build: + name: Perform tests runs-on: ubuntu-latest strategy: matrix: diff --git a/package.json b/package.json index b1bce12b..ffadefde 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "test:e2e": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config jest.e2e.config.js", "theme-readme-gen": "node scripts/generate-theme-doc", "preview-theme": "node scripts/preview-theme", + "close-stale-theme-prs": "node scripts/close-stale-theme-prs", "generate-langs-json": "node scripts/generate-langs-json", "format": "./node_modules/.bin/prettier --write .", "format:check": "./node_modules/.bin/prettier --check ." diff --git a/scripts/close-stale-theme-prs.js b/scripts/close-stale-theme-prs.js new file mode 100644 index 00000000..69e5e193 --- /dev/null +++ b/scripts/close-stale-theme-prs.js @@ -0,0 +1,161 @@ +/** + * @file Script that can be used to close stale theme PRs that have a `invalid` label. + */ +import * as dotenv from "dotenv"; +dotenv.config(); + +import { debug, setFailed } from "@actions/core"; +import github from "@actions/github"; +import { RequestError } from "@octokit/request-error"; +import { getGithubToken, getRepoInfo } from "./helpers.js"; + +// Script parameters +const CLOSING_COMMENT = ` + \rThis PR has been automatically closed due to inactivity. Please feel free to reopen it if you need to continue working on it.\ + \rThank you for your contributions. +`; + +/** + * Fetch open PRs from a given repository. + * @param user The user name of the repository owner. + * @param repo The name of the repository. + * @returns The open PRs. + */ +export const fetchOpenPRs = async (octokit, user, repo) => { + const openPRs = []; + let hasNextPage = true; + let endCursor; + while (hasNextPage) { + try { + const { repository } = await octokit.graphql( + ` + { + repository(owner: "${user}", name: "${repo}") { + open_prs: pullRequests(${ + endCursor ? `after: "${endCursor}", ` : "" + } + first: 100, states: OPEN, orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + number + commits(last:1){ + nodes{ + commit{ + pushedDate + } + } + } + labels(first: 100, orderBy:{field: CREATED_AT, direction: DESC}) { + nodes { + name + } + } + reviews(first: 1, states: CHANGES_REQUESTED, author: "github-actions[bot]") { + nodes { + updatedAt + } + } + } + pageInfo { + endCursor + hasNextPage + } + } + } + } + `, + ); + openPRs.push(...repository.open_prs.nodes); + hasNextPage = repository.open_prs.pageInfo.hasNextPage; + endCursor = repository.open_prs.pageInfo.endCursor; + } catch (error) { + if (error instanceof RequestError) { + setFailed(`Could not retrieve top PRs using GraphQl: ${error.message}`); + } + throw error; + } + } + return openPRs; +}; + +/** + * Retrieve pull requests that have a given label. + * @param pull The pull requests to check. + * @param label The label to check for. + */ +export const pullsWithLabel = (pulls, label) => { + return pulls.filter((pr) => { + return pr.labels.nodes.some((lab) => lab.name === label); + }); +}; + +/** + * Check if PR is stale. Meaning that it hasn't been updated in a given time. + * @param {Object} pullRequest request object. + * @param {number} days number of days. + * @returns Boolean indicating if PR is stale. + */ +const isStale = (pullRequest, staleDays) => { + const lastCommitDate = new Date( + pullRequest.commits.nodes[0].commit.pushedDate, + ); + if (pullRequest.reviews.nodes[0]) { + const lastReviewDate = new Date(pullRequest.reviews.nodes[0].updatedAt); + const lastUpdateDate = + lastCommitDate >= lastReviewDate ? lastCommitDate : lastReviewDate; + const now = new Date(); + return now - lastUpdateDate > 1000 * 60 * 60 * 24 * staleDays; + } else { + return false; + } +}; + +/** + * Main function. + */ +const run = async () => { + try { + // Create octokit client. + const dryRun = process.env.DRY_RUN === "true" || false; + const staleDays = process.env.STALE_DAYS || 15; + debug("Creating octokit client..."); + const octokit = github.getOctokit(getGithubToken()); + const { owner, repo } = getRepoInfo(github.context); + + // Retrieve all theme pull requests. + debug("Retrieving all theme pull requests..."); + const prs = await fetchOpenPRs(octokit, owner, repo); + const themePRs = pullsWithLabel(prs, "themes"); + const invalidThemePRs = pullsWithLabel(themePRs, "invalid"); + debug("Retrieving stale themePRs..."); + const staleThemePRs = invalidThemePRs.filter((pr) => + isStale(pr, staleDays), + ); + const staleThemePRsNumbers = staleThemePRs.map((pr) => pr.number); + debug(`Found ${staleThemePRs.length} stale theme PRs`); + + // Loop through all stale invalid theme pull requests and close them. + for (const prNumber of staleThemePRsNumbers) { + debug(`Closing #${prNumber} because it is stale...`); + if (!dryRun) { + await octokit.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body: CLOSING_COMMENT, + }); + await octokit.pulls.update({ + owner, + repo, + pull_number: prNumber, + state: "closed", + }); + } else { + debug("Dry run enabled, skipping..."); + } + } + } catch (error) { + setFailed(error.message); + } +}; + +run(); diff --git a/scripts/helpers.js b/scripts/helpers.js new file mode 100644 index 00000000..fabf300f --- /dev/null +++ b/scripts/helpers.js @@ -0,0 +1,40 @@ +/** + * @file Contains helper functions used in the scripts. + */ + +// Script variables. +const OWNER = "anuraghazra"; +const REPO = "github-readme-stats"; + +/** + * Retrieve information about the repository that ran the action. + * + * @param {Object} context Action context. + * @returns {Object} Repository information. + */ +export const getRepoInfo = (ctx) => { + try { + return { + owner: ctx.repo.owner, + repo: ctx.repo.repo, + }; + } catch (error) { + return { + owner: OWNER, + repo: REPO, + }; + } +}; + +/** + * Retrieve github token and throw error if it is not found. + * + * @returns {string} Github token. + */ +export const getGithubToken = () => { + const token = core.getInput("github_token") || process.env.GITHUB_TOKEN; + if (!token) { + throw Error("Could not find github token"); + } + return token; +}; diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index c6312b40..94145fb2 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -4,7 +4,7 @@ import * as dotenv from "dotenv"; dotenv.config(); -import core, { debug, setFailed } from "@actions/core"; +import { debug, setFailed } from "@actions/core"; import github from "@actions/github"; import ColorContrastChecker from "color-contrast-checker"; import { info } from "console"; @@ -14,10 +14,9 @@ import parse from "parse-diff"; import { inspect } from "util"; import { isValidHexColor } from "../src/common/utils.js"; import { themes } from "../themes/index.js"; +import { getGithubToken, getRepoInfo } from "./helpers.js"; -// Script variables -const OWNER = "anuraghazra"; -const REPO = "github-readme-stats"; +// Script variables. const COMMENTER = "github-actions[bot]"; const COMMENT_TITLE = "Automated Theme Preview"; @@ -43,26 +42,6 @@ const REQUIRED_COLOR_PROPS = [ const INVALID_REVIEW_COMMENT = (commentUrl) => `Some themes are invalid. See the [Automated Theme Preview](${commentUrl}) comment above for more information.`; -/** - * Retrieve information about the repository that ran the action. - * - * @param {Object} context Action context. - * @returns {Object} Repository information. - */ -export const getRepoInfo = (ctx) => { - try { - return { - owner: ctx.repo.owner, - repo: ctx.repo.repo, - }; - } catch (error) { - return { - owner: OWNER, - repo: REPO, - }; - } -}; - /** * Retrieve PR number from the event payload. * @@ -86,19 +65,6 @@ const getCommenter = () => { return process.env.COMMENTER ? process.env.COMMENTER : COMMENTER; }; -/** - * Retrieve github token and throw error if it is not found. - * - * @returns {string} Github token. - */ -const getGithubToken = () => { - const token = core.getInput("github_token") || process.env.GITHUB_TOKEN; - if (!token) { - throw Error("Could not find github token"); - } - return token; -}; - /** * Returns whether the comment is a preview comment. * From 406dbc5656ea8e12ff224967cd7ebacc5f0d8729 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 2 Oct 2022 11:45:55 +0200 Subject: [PATCH 44/88] feat: add transparent theme Adds a transparent theme with a contrast ratio of 4.5 on both black and white (see https://ux.stackexchange.com/a/86226). --- themes/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/themes/index.js b/themes/index.js index 6ca5fde6..d5c0e4c2 100644 --- a/themes/index.js +++ b/themes/index.js @@ -12,6 +12,13 @@ export const themes = { text_color: "434d58", bg_color: "fffefe", }, + transparent: { + title_color: "006AFF", + icon_color: "0579C3", + text_color: "417E87", + bg_color: "ffffff00", + border_color: "e4e2e2", + }, dark: { title_color: "fff", icon_color: "79ff97", From 510cf6266cdae5c8c81cd9e541b593413b86e5e5 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 11:47:56 +0200 Subject: [PATCH 45/88] feat: remove border color from transparent theme --- themes/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/index.js b/themes/index.js index d5c0e4c2..4279317b 100644 --- a/themes/index.js +++ b/themes/index.js @@ -17,7 +17,6 @@ export const themes = { icon_color: "0579C3", text_color: "417E87", bg_color: "ffffff00", - border_color: "e4e2e2", }, dark: { title_color: "fff", From 3a07cb02db0a69238cb75d802b6485537d73c27e Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 12:27:34 +0200 Subject: [PATCH 46/88] ci: fix e2e test --- tests/e2e/e2e.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index 7e59acb4..becf5c82 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -23,7 +23,7 @@ const STATS_DATA = { contributedTo: 2, rank: { level: "A+", - score: 51.01622937949586, + score: 51.01013099671447, }, }; const LANGS_DATA = { From f0daab11c8ab9e6a2eb00cd5794075a41b47c9e0 Mon Sep 17 00:00:00 2001 From: Jagruti Tiwari Date: Sun, 2 Oct 2022 17:33:22 +0530 Subject: [PATCH 47/88] feat: added default options to readme (#2051) * feat: added default options to readme * Update readme.md Co-authored-by: Rick Staa * fix: added default values for stats card * style: some small readme changes Co-authored-by: Rick Staa --- readme.md | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/readme.md b/readme.md index 3ef40724..6f457556 100644 --- a/readme.md +++ b/readme.md @@ -160,16 +160,16 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you #### Common Options: -- `title_color` - Card's title color _(hex color)_ -- `text_color` - Body text color _(hex color)_ -- `icon_color` - Icons color if available _(hex color)_ -- `border_color` - Card's border color _(hex color)_. (Does not apply when `hide_border` is enabled) -- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_ -- `hide_border` - Hides the card's border _(boolean)_ -- `theme` - name of the theme, choose from [all available themes](./themes/README.md) -- `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_ -- `locale` - set the language in the card _(e.g. cn, de, es, etc.)_ -- `border_radius` - Corner rounding on the card +- `title_color` - Card's title color _(hex color)_. Default: `2f80ed`. +- `text_color` - Body text color _(hex color)_. Default: `434d58`. +- `icon_color` - Icons color if available _(hex color)_. Default: `4c71f2`. +- `border_color` - Card's border color _(hex color)_. Default: `e4e2e2` (Does not apply when `hide_border` is enabled). +- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_. Default: `fffefe` +- `hide_border` - Hides the card's border _(boolean)_. Default: `false` +- `theme` - name of the theme, choose from [all available themes](./themes/README.md). Default: `default` theme. +- `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_. Default: `14400 seconds (4 hours)`. +- `locale` - set the language in the card _(e.g. cn, de, es, etc.)_. Default: `en`. +- `border_radius` - Corner rounding on the card. Default: `4.5`. > Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. @@ -185,18 +185,21 @@ You can provide multiple comma-separated values in the bg_color option to render #### Stats Card Exclusive Options: -- `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_ -- `hide_title` - _(boolean)_ -- `card_width` - Set the card's width manually _(number)_ -- `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width -- `show_icons` - _(boolean)_ -- `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_ -- `count_private` - Count private commits _(boolean)_ -- `line_height` - Sets the line-height between text _(number)_ -- `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_ -- `custom_title` - Sets a custom title for the card -- `text_bold` - Use bold text _(boolean)_ -- `disable_animations` - Disables all animations in the card _(boolean)_ +- `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`. +- `hide_title` - _(boolean)_. Default: `false`. +- `card_width` - Set the card's width manually _(number)_. Default: `500px (approx.)`. +- `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width. Default: `false`. +- `show_icons` - _(boolean)_. Default: `false`. +- `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_. Default: `false`. +- `count_private` - Count private commits _(boolean)_. Default: `false`. +- `line_height` - Sets the line-height between text _(number)_. Default: `25`. +- `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. +- `custom_title` - Sets a custom title for the card. Default: ` Github Stats`. +- `text_bold` - Use bold text _(boolean)_. Default: `true`. +- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`. + +> Note on `hide_rank`: +When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. #### Repo Card Exclusive Options: @@ -454,4 +457,3 @@ Thanks! :heart: Contributions are welcome! <3 Made with :heart: and JavaScript. - From 6f8bd9fe1019dccb7bea99d52cfd51342d388b25 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 14:15:25 +0200 Subject: [PATCH 48/88] ci: increase top-issues dashboard update frequency --- .github/workflows/top-issues-dashboard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/top-issues-dashboard.yml b/.github/workflows/top-issues-dashboard.yml index 97947947..2b36e529 100644 --- a/.github/workflows/top-issues-dashboard.yml +++ b/.github/workflows/top-issues-dashboard.yml @@ -1,7 +1,7 @@ name: Update top issues dashboard on: schedule: - - cron: "0 0 */7 * *" + - cron: "0 0 */3 * *" jobs: showAndLabelTopIssues: From d56b294ca16e63c58567ac3b54fabf30bb508446 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 2 Oct 2022 14:50:03 +0200 Subject: [PATCH 49/88] style: improve code style --- scripts/close-stale-theme-prs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/close-stale-theme-prs.js b/scripts/close-stale-theme-prs.js index 69e5e193..8c14c1e3 100644 --- a/scripts/close-stale-theme-prs.js +++ b/scripts/close-stale-theme-prs.js @@ -126,7 +126,7 @@ const run = async () => { const prs = await fetchOpenPRs(octokit, owner, repo); const themePRs = pullsWithLabel(prs, "themes"); const invalidThemePRs = pullsWithLabel(themePRs, "invalid"); - debug("Retrieving stale themePRs..."); + debug("Retrieving stale theme PRs..."); const staleThemePRs = invalidThemePRs.filter((pr) => isStale(pr, staleDays), ); From 84c9d354b3fabec196b1a4fc9cb4700582b803dd Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sun, 2 Oct 2022 21:01:38 +0530 Subject: [PATCH 50/88] docs(theme): Auto update theme readme (#2091) Co-authored-by: Github Readme Stats Bot --- themes/README.md | 84 +++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/themes/README.md b/themes/README.md index e8b22b26..b8649d43 100644 --- a/themes/README.md +++ b/themes/README.md @@ -16,26 +16,27 @@ Use `?theme=THEME_NAME` parameter like so :- | | | | | :--: | :--: | :--: | -| `default` ![default][default] | `dark` ![dark][dark] | `radical` ![radical][radical] | -| `merko` ![merko][merko] | `gruvbox` ![gruvbox][gruvbox] | `gruvbox_light` ![gruvbox_light][gruvbox_light] | -| `tokyonight` ![tokyonight][tokyonight] | `onedark` ![onedark][onedark] | `cobalt` ![cobalt][cobalt] | -| `synthwave` ![synthwave][synthwave] | `highcontrast` ![highcontrast][highcontrast] | `dracula` ![dracula][dracula] | -| `prussian` ![prussian][prussian] | `monokai` ![monokai][monokai] | `vue` ![vue][vue] | -| `vue-dark` ![vue-dark][vue-dark] | `shades-of-purple` ![shades-of-purple][shades-of-purple] | `nightowl` ![nightowl][nightowl] | -| `buefy` ![buefy][buefy] | `blue-green` ![blue-green][blue-green] | `algolia` ![algolia][algolia] | -| `great-gatsby` ![great-gatsby][great-gatsby] | `darcula` ![darcula][darcula] | `bear` ![bear][bear] | -| `solarized-dark` ![solarized-dark][solarized-dark] | `solarized-light` ![solarized-light][solarized-light] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark] | -| `nord` ![nord][nord] | `gotham` ![gotham][gotham] | `material-palenight` ![material-palenight][material-palenight] | -| `graywhite` ![graywhite][graywhite] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark] | `ayu-mirage` ![ayu-mirage][ayu-mirage] | -| `midnight-purple` ![midnight-purple][midnight-purple] | `calm` ![calm][calm] | `flag-india` ![flag-india][flag-india] | -| `omni` ![omni][omni] | `react` ![react][react] | `jolly` ![jolly][jolly] | -| `maroongold` ![maroongold][maroongold] | `yeblu` ![yeblu][yeblu] | `blueberry` ![blueberry][blueberry] | -| `slateorange` ![slateorange][slateorange] | `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | -| `ocean_dark` ![ocean_dark][ocean_dark] | `city_lights` ![city_lights][city_lights] | `github_dark` ![github_dark][github_dark] | -| `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | `aura_dark` ![aura_dark][aura_dark] | `panda` ![panda][panda] | -| `noctis_minimus` ![noctis_minimus][noctis_minimus] | `cobalt2` ![cobalt2][cobalt2] | `swift` ![swift][swift] | -| `aura` ![aura][aura] | `apprentice` ![apprentice][apprentice] | `moltack` ![moltack][moltack] | -| `codeSTACKr` ![codeSTACKr][codeSTACKr] | `rose_pine` ![rose_pine][rose_pine] | [Add your theme][add-theme] | +| `default` ![default][default] | `transparent` ![transparent][transparent] | `dark` ![dark][dark] | +| `radical` ![radical][radical] | `merko` ![merko][merko] | `gruvbox` ![gruvbox][gruvbox] | +| `gruvbox_light` ![gruvbox_light][gruvbox_light] | `tokyonight` ![tokyonight][tokyonight] | `onedark` ![onedark][onedark] | +| `cobalt` ![cobalt][cobalt] | `synthwave` ![synthwave][synthwave] | `highcontrast` ![highcontrast][highcontrast] | +| `dracula` ![dracula][dracula] | `prussian` ![prussian][prussian] | `monokai` ![monokai][monokai] | +| `vue` ![vue][vue] | `vue-dark` ![vue-dark][vue-dark] | `shades-of-purple` ![shades-of-purple][shades-of-purple] | +| `nightowl` ![nightowl][nightowl] | `buefy` ![buefy][buefy] | `blue-green` ![blue-green][blue-green] | +| `algolia` ![algolia][algolia] | `great-gatsby` ![great-gatsby][great-gatsby] | `darcula` ![darcula][darcula] | +| `bear` ![bear][bear] | `solarized-dark` ![solarized-dark][solarized-dark] | `solarized-light` ![solarized-light][solarized-light] | +| `chartreuse-dark` ![chartreuse-dark][chartreuse-dark] | `nord` ![nord][nord] | `gotham` ![gotham][gotham] | +| `material-palenight` ![material-palenight][material-palenight] | `graywhite` ![graywhite][graywhite] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark] | +| `ayu-mirage` ![ayu-mirage][ayu-mirage] | `midnight-purple` ![midnight-purple][midnight-purple] | `calm` ![calm][calm] | +| `flag-india` ![flag-india][flag-india] | `omni` ![omni][omni] | `react` ![react][react] | +| `jolly` ![jolly][jolly] | `maroongold` ![maroongold][maroongold] | `yeblu` ![yeblu][yeblu] | +| `blueberry` ![blueberry][blueberry] | `slateorange` ![slateorange][slateorange] | `kacho_ga` ![kacho_ga][kacho_ga] | +| `outrun` ![outrun][outrun] | `ocean_dark` ![ocean_dark][ocean_dark] | `city_lights` ![city_lights][city_lights] | +| `github_dark` ![github_dark][github_dark] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | `aura_dark` ![aura_dark][aura_dark] | +| `panda` ![panda][panda] | `noctis_minimus` ![noctis_minimus][noctis_minimus] | `cobalt2` ![cobalt2][cobalt2] | +| `swift` ![swift][swift] | `aura` ![aura][aura] | `apprentice` ![apprentice][apprentice] | +| `moltack` ![moltack][moltack] | `codeSTACKr` ![codeSTACKr][codeSTACKr] | `rose_pine` ![rose_pine][rose_pine] | +| [Add your theme][add-theme] | | | ## Repo Card @@ -43,30 +44,32 @@ Use `?theme=THEME_NAME` parameter like so :- | | | | | :--: | :--: | :--: | -| `default_repocard` ![default_repocard][default_repocard_repo] | `dark` ![dark][dark_repo] | `radical` ![radical][radical_repo] | -| `merko` ![merko][merko_repo] | `gruvbox` ![gruvbox][gruvbox_repo] | `gruvbox_light` ![gruvbox_light][gruvbox_light_repo] | -| `tokyonight` ![tokyonight][tokyonight_repo] | `onedark` ![onedark][onedark_repo] | `cobalt` ![cobalt][cobalt_repo] | -| `synthwave` ![synthwave][synthwave_repo] | `highcontrast` ![highcontrast][highcontrast_repo] | `dracula` ![dracula][dracula_repo] | -| `prussian` ![prussian][prussian_repo] | `monokai` ![monokai][monokai_repo] | `vue` ![vue][vue_repo] | -| `vue-dark` ![vue-dark][vue-dark_repo] | `shades-of-purple` ![shades-of-purple][shades-of-purple_repo] | `nightowl` ![nightowl][nightowl_repo] | -| `buefy` ![buefy][buefy_repo] | `blue-green` ![blue-green][blue-green_repo] | `algolia` ![algolia][algolia_repo] | -| `great-gatsby` ![great-gatsby][great-gatsby_repo] | `darcula` ![darcula][darcula_repo] | `bear` ![bear][bear_repo] | -| `solarized-dark` ![solarized-dark][solarized-dark_repo] | `solarized-light` ![solarized-light][solarized-light_repo] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark_repo] | -| `nord` ![nord][nord_repo] | `gotham` ![gotham][gotham_repo] | `material-palenight` ![material-palenight][material-palenight_repo] | -| `graywhite` ![graywhite][graywhite_repo] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark_repo] | `ayu-mirage` ![ayu-mirage][ayu-mirage_repo] | -| `midnight-purple` ![midnight-purple][midnight-purple_repo] | `calm` ![calm][calm_repo] | `flag-india` ![flag-india][flag-india_repo] | -| `omni` ![omni][omni_repo] | `react` ![react][react_repo] | `jolly` ![jolly][jolly_repo] | -| `maroongold` ![maroongold][maroongold_repo] | `yeblu` ![yeblu][yeblu_repo] | `blueberry` ![blueberry][blueberry_repo] | -| `slateorange` ![slateorange][slateorange_repo] | `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | -| `ocean_dark` ![ocean_dark][ocean_dark_repo] | `city_lights` ![city_lights][city_lights_repo] | `github_dark` ![github_dark][github_dark_repo] | -| `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | `aura_dark` ![aura_dark][aura_dark_repo] | `panda` ![panda][panda_repo] | -| `noctis_minimus` ![noctis_minimus][noctis_minimus_repo] | `cobalt2` ![cobalt2][cobalt2_repo] | `swift` ![swift][swift_repo] | -| `aura` ![aura][aura_repo] | `apprentice` ![apprentice][apprentice_repo] | `moltack` ![moltack][moltack_repo] | -| `codeSTACKr` ![codeSTACKr][codeSTACKr_repo] | `rose_pine` ![rose_pine][rose_pine_repo] | [Add your theme][add-theme] | +| `default_repocard` ![default_repocard][default_repocard_repo] | `transparent` ![transparent][transparent_repo] | `dark` ![dark][dark_repo] | +| `radical` ![radical][radical_repo] | `merko` ![merko][merko_repo] | `gruvbox` ![gruvbox][gruvbox_repo] | +| `gruvbox_light` ![gruvbox_light][gruvbox_light_repo] | `tokyonight` ![tokyonight][tokyonight_repo] | `onedark` ![onedark][onedark_repo] | +| `cobalt` ![cobalt][cobalt_repo] | `synthwave` ![synthwave][synthwave_repo] | `highcontrast` ![highcontrast][highcontrast_repo] | +| `dracula` ![dracula][dracula_repo] | `prussian` ![prussian][prussian_repo] | `monokai` ![monokai][monokai_repo] | +| `vue` ![vue][vue_repo] | `vue-dark` ![vue-dark][vue-dark_repo] | `shades-of-purple` ![shades-of-purple][shades-of-purple_repo] | +| `nightowl` ![nightowl][nightowl_repo] | `buefy` ![buefy][buefy_repo] | `blue-green` ![blue-green][blue-green_repo] | +| `algolia` ![algolia][algolia_repo] | `great-gatsby` ![great-gatsby][great-gatsby_repo] | `darcula` ![darcula][darcula_repo] | +| `bear` ![bear][bear_repo] | `solarized-dark` ![solarized-dark][solarized-dark_repo] | `solarized-light` ![solarized-light][solarized-light_repo] | +| `chartreuse-dark` ![chartreuse-dark][chartreuse-dark_repo] | `nord` ![nord][nord_repo] | `gotham` ![gotham][gotham_repo] | +| `material-palenight` ![material-palenight][material-palenight_repo] | `graywhite` ![graywhite][graywhite_repo] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark_repo] | +| `ayu-mirage` ![ayu-mirage][ayu-mirage_repo] | `midnight-purple` ![midnight-purple][midnight-purple_repo] | `calm` ![calm][calm_repo] | +| `flag-india` ![flag-india][flag-india_repo] | `omni` ![omni][omni_repo] | `react` ![react][react_repo] | +| `jolly` ![jolly][jolly_repo] | `maroongold` ![maroongold][maroongold_repo] | `yeblu` ![yeblu][yeblu_repo] | +| `blueberry` ![blueberry][blueberry_repo] | `slateorange` ![slateorange][slateorange_repo] | `kacho_ga` ![kacho_ga][kacho_ga_repo] | +| `outrun` ![outrun][outrun_repo] | `ocean_dark` ![ocean_dark][ocean_dark_repo] | `city_lights` ![city_lights][city_lights_repo] | +| `github_dark` ![github_dark][github_dark_repo] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | `aura_dark` ![aura_dark][aura_dark_repo] | +| `panda` ![panda][panda_repo] | `noctis_minimus` ![noctis_minimus][noctis_minimus_repo] | `cobalt2` ![cobalt2][cobalt2_repo] | +| `swift` ![swift][swift_repo] | `aura` ![aura][aura_repo] | `apprentice` ![apprentice][apprentice_repo] | +| `moltack` ![moltack][moltack_repo] | `codeSTACKr` ![codeSTACKr][codeSTACKr_repo] | `rose_pine` ![rose_pine][rose_pine_repo] | +| [Add your theme][add-theme] | | | [default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default [default_repocard]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default_repocard +[transparent]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=transparent [dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=dark [radical]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=radical [merko]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=merko @@ -129,6 +132,7 @@ Use `?theme=THEME_NAME` parameter like so :- [default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default [default_repocard_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default_repocard +[transparent_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=transparent [dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=dark [radical_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=radical [merko_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=merko From 822efbf6cb991732ed3fe7460c6831e48a407a38 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 2 Oct 2022 17:41:28 +0200 Subject: [PATCH 51/88] ci: fix small bugs in theme-preview action (#2093) * ci: fix small bugs in theme-preview action * ci: format code --- scripts/helpers.js | 4 +++- scripts/preview-theme.js | 49 ++++++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/scripts/helpers.js b/scripts/helpers.js index fabf300f..3fc5fc7d 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -2,6 +2,8 @@ * @file Contains helper functions used in the scripts. */ +import { getInput } from "@actions/core"; + // Script variables. const OWNER = "anuraghazra"; const REPO = "github-readme-stats"; @@ -32,7 +34,7 @@ export const getRepoInfo = (ctx) => { * @returns {string} Github token. */ export const getGithubToken = () => { - const token = core.getInput("github_token") || process.env.GITHUB_TOKEN; + const token = getInput("github_token") || process.env.GITHUB_TOKEN; if (!token) { throw Error("Could not find github token"); } diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 94145fb2..6bb29e68 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -33,12 +33,15 @@ const THEME_CONTRIB_GUIDELINESS = ` \r> Also, note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection, you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization). `; -const REQUIRED_COLOR_PROPS = [ - "title_color", - "icon_color", - "text_color", - "bg_color", -]; +const COLOR_PROPS = { + title_color: 6, + icon_color: 6, + text_color: 6, + bg_color: 8, + border_color: 6, +}; +const ACCEPTED_COLOR_PROPS = Object.keys(COLOR_PROPS); +const REQUIRED_COLOR_PROPS = ACCEPTED_COLOR_PROPS.slice(0, 4); const INVALID_REVIEW_COMMENT = (commentUrl) => `Some themes are invalid. See the [Automated Theme Preview](${commentUrl}) comment above for more information.`; @@ -271,11 +274,11 @@ const parseJSON = (json) => { } } catch (error) { let parsedJson = json - .split(/(?:\s*)(}\s*,?)(?:\s*)(?=\s*[a-z_"]+:+)/) + .split(/([\s\r\s]*}[\s\r\s]*,[\s\r\s]*)(?=[\w"-]+:)/) .filter((x) => typeof x !== "string" || !!x.trim()); if (parsedJson[0].replace(/\s+/g, "") === "},") { parsedJson[0] = "},"; - if (!/\s*}\s*,?\s*$/.test(parsedJson[0])) { + if (!/\s*}\s*,?\s*$/.test(parsedJson[1])) { parsedJson.push(parsedJson.shift()); } else { parsedJson.shift(); @@ -299,7 +302,7 @@ const themeNameAlreadyExists = (name) => { /** * Main function. */ -const run = async () => { +export const run = async (prNumber) => { try { const dryRun = process.env.DRY_RUN === "true" || false; debug("Retrieve action information from context..."); @@ -310,7 +313,7 @@ const run = async () => { `; const ccc = new ColorContrastChecker(); const octokit = github.getOctokit(getGithubToken()); - const pullRequestId = getPrNumber(); + const pullRequestId = prNumber ? prNumber : getPrNumber(); const commenter = getCommenter(); const { owner, repo } = getRepoInfo(github.context); debug(`Owner: ${owner}`); @@ -387,10 +390,19 @@ const run = async () => { const missingKeys = REQUIRED_COLOR_PROPS.filter( (x) => !Object.keys(colors).includes(x), ); - if (missingKeys.length > 0) { + const extraKeys = Object.keys(colors).filter( + (x) => !ACCEPTED_COLOR_PROPS.includes(x), + ); + if (missingKeys.length > 0 || extraKeys.length > 0) { for (const missingKey of missingKeys) { errors.push(`Theme color properties \`${missingKey}\` are missing`); } + + for (const extraKey of extraKeys) { + warnings.push( + `Theme color properties \`${extraKey}\` is not supported`, + ); + } invalidColors = true; } else { for (const [colorKey, colorValue] of Object.entries(colors)) { @@ -399,6 +411,11 @@ const run = async () => { `Theme color property \`${colorKey}\` should not start with '#'`, ); invalidColors = true; + } else if (colorValue.length > COLOR_PROPS[colorKey]) { + errors.push( + `Theme color property \`${colorKey}\` can not be longer than \`${COLOR_PROPS[colorKey]}\` characters`, + ); + invalidColors = true; } else if (!isValidHexColor(colorValue)) { errors.push( `Theme color property \`${colorKey}\` is not a valid hex color: #${colorValue}`, @@ -437,8 +454,10 @@ const run = async () => { text_color: [textColor, bgColor], }; Object.keys(colorPairs).forEach((item) => { - const color1 = colorPairs[item][0]; - const color2 = colorPairs[item][1]; + let color1 = colorPairs[item][0]; + let color2 = colorPairs[item][1]; + color1 = color1.length === 4 ? color1.slice(0, 3) : color1.slice(0, 6); + color2 = color2.length === 4 ? color2.slice(0, 3) : color2.slice(0, 6); if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) { const permalink = getWebAimLink(color1, color2); warnings.push( @@ -543,4 +562,6 @@ const run = async () => { } }; -run(); +if (typeof require !== "undefined" && require.main === module) { + run(); +} From 5d42af59c0214de3627788c7b1a4e22c5f32a655 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 17:42:58 +0200 Subject: [PATCH 52/88] ci: fix small bug in theme-preview action --- scripts/preview-theme.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 6bb29e68..58aad028 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -562,6 +562,4 @@ export const run = async (prNumber) => { } }; -if (typeof require !== "undefined" && require.main === module) { - run(); -} +run(); From 2faf9c54fff7f18fe4818a2427c5bbe1f81e062b Mon Sep 17 00:00:00 2001 From: ianbromwichuos <112479962+ianbromwichuos@users.noreply.github.com> Date: Sun, 2 Oct 2022 16:47:14 +0100 Subject: [PATCH 53/88] docs: fix link to go India logo svg (#2085) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6f457556..f7a04fb3 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@

-Give india logo +Give india logo Are you considering supporting the project by donating? Please DON'T!! From c2c984a872fef19d605de51907c3e60a0e73c4de Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 17:58:34 +0200 Subject: [PATCH 54/88] docs: format readme --- readme.md | 192 ++++++++++++++++++++++++++---------------------------- 1 file changed, 94 insertions(+), 98 deletions(-) diff --git a/readme.md b/readme.md index f7a04fb3..51c7229b 100644 --- a/readme.md +++ b/readme.md @@ -61,7 +61,6 @@

Love the project? Please consider donating to help it improve! -

Give india logo @@ -72,25 +71,25 @@ Are you considering supporting the project by donating? Please DON'T!! Instead, Help India fight the 2nd deadly wave of COVID-19. Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure. -Visit [https://indiafightscorona.giveindia.org](https://indiafightscorona.giveindia.org) and make a small donation to help us fight COVID and overcome this crisis. +Visit and make a small donation to help us fight COVID and overcome this crisis. A small donation goes a long way. :heart: -

+

# Features -- [GitHub Stats Card](#github-stats-card) -- [GitHub Extra Pins](#github-extra-pins) -- [Top Languages Card](#top-languages-card) -- [Wakatime Week Stats](#wakatime-week-stats) -- [Themes](#themes) -- [Customization](#customization) - - [Common Options](#common-options) - - [Stats Card Exclusive Options](#stats-card-exclusive-options) - - [Repo Card Exclusive Options](#repo-card-exclusive-options) - - [Language Card Exclusive Options](#language-card-exclusive-options) - - [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options) -- [Deploy Yourself](#deploy-on-your-own-vercel-instance) +- [GitHub Stats Card](#github-stats-card) +- [GitHub Extra Pins](#github-extra-pins) +- [Top Languages Card](#top-languages-card) +- [Wakatime Week Stats](#wakatime-week-stats) +- [Themes](#themes) +- [Customization](#customization) + - [Common Options](#common-options) + - [Stats Card Exclusive Options](#stats-card-exclusive-options) + - [Repo Card Exclusive Options](#repo-card-exclusive-options) + - [Language Card Exclusive Options](#language-card-exclusive-options) + - [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options) +- [Deploy Yourself](#deploy-on-your-own-vercel-instance) # GitHub Stats Card @@ -160,16 +159,16 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you #### Common Options: -- `title_color` - Card's title color _(hex color)_. Default: `2f80ed`. -- `text_color` - Body text color _(hex color)_. Default: `434d58`. -- `icon_color` - Icons color if available _(hex color)_. Default: `4c71f2`. -- `border_color` - Card's border color _(hex color)_. Default: `e4e2e2` (Does not apply when `hide_border` is enabled). -- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_. Default: `fffefe` -- `hide_border` - Hides the card's border _(boolean)_. Default: `false` -- `theme` - name of the theme, choose from [all available themes](./themes/README.md). Default: `default` theme. -- `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_. Default: `14400 seconds (4 hours)`. -- `locale` - set the language in the card _(e.g. cn, de, es, etc.)_. Default: `en`. -- `border_radius` - Corner rounding on the card. Default: `4.5`. +- `title_color` - Card's title color _(hex color)_. Default: `2f80ed`. +- `text_color` - Body text color _(hex color)_. Default: `434d58`. +- `icon_color` - Icons color if available _(hex color)_. Default: `4c71f2`. +- `border_color` - Card's border color _(hex color)_. Default: `e4e2e2` (Does not apply when `hide_border` is enabled). +- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_. Default: `fffefe` +- `hide_border` - Hides the card's border _(boolean)_. Default: `false` +- `theme` - name of the theme, choose from [all available themes](./themes/README.md). Default: `default` theme. +- `cache_seconds` - set the cache header manually _(min: 7200, max: 86400)_. Default: `14400 seconds (4 hours)`. +- `locale` - set the language in the card _(e.g. cn, de, es, etc.)_. Default: `en`. +- `border_radius` - Corner rounding on the card. Default: `4.5`. > Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. @@ -177,43 +176,41 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you You can provide multiple comma-separated values in the bg_color option to render a gradient, with the following format: -``` -&bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 -``` + &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 > Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k, otherwise, it's 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. #### Stats Card Exclusive Options: -- `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`. -- `hide_title` - _(boolean)_. Default: `false`. -- `card_width` - Set the card's width manually _(number)_. Default: `500px (approx.)`. -- `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width. Default: `false`. -- `show_icons` - _(boolean)_. Default: `false`. -- `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_. Default: `false`. -- `count_private` - Count private commits _(boolean)_. Default: `false`. -- `line_height` - Sets the line-height between text _(number)_. Default: `25`. -- `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. -- `custom_title` - Sets a custom title for the card. Default: ` Github Stats`. -- `text_bold` - Use bold text _(boolean)_. Default: `true`. -- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`. +- `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`. +- `hide_title` - _(boolean)_. Default: `false`. +- `card_width` - Set the card's width manually _(number)_. Default: `500px (approx.)`. +- `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width. Default: `false`. +- `show_icons` - _(boolean)_. Default: `false`. +- `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_. Default: `false`. +- `count_private` - Count private commits _(boolean)_. Default: `false`. +- `line_height` - Sets the line-height between text _(number)_. Default: `25`. +- `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. +- `custom_title` - Sets a custom title for the card. Default: ` Github Stats`. +- `text_bold` - Use bold text _(boolean)_. Default: `true`. +- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`. > Note on `hide_rank`: -When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. +> When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. #### Repo Card Exclusive Options: -- `show_owner` - Show the repo's owner name _(boolean)_ +- `show_owner` - Show the repo's owner name _(boolean)_ #### Language Card Exclusive Options: -- `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_ -- `layout` - Switch between two available layouts `default` & `compact` -- `card_width` - Set the card's width manually _(number)_ -- `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_ -- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_ -- `custom_title` - Sets a custom title for the card +- `hide` - Hide the languages specified from the card _(Comma-separated values)_ +- `hide_title` - _(boolean)_ +- `layout` - Switch between two available layouts `default` & `compact` +- `card_width` - Set the card's width manually _(number)_ +- `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_ +- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_ +- `custom_title` - Sets a custom title for the card > :warning: **Important:** > Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding) @@ -222,17 +219,17 @@ When hide_rank=`true`, the minimum card width is 270 px + the title length and p #### Wakatime Card Exclusive Options: -- `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_ -- `line_height` - Sets the line-height between text _(number)_ -- `hide_progress` - Hides the progress bar and percentage _(boolean)_ -- `custom_title` - Sets a custom title for the card -- `layout` - Switch between two available layouts `default` & `compact` -- `langs_count` - Limit the number of languages on the card, defaults to all reported languages -- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) -- `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. +- `hide` - Hide the languages specified from the card _(Comma-separated values)_ +- `hide_title` - _(boolean)_ +- `line_height` - Sets the line-height between text _(number)_ +- `hide_progress` - Hides the progress bar and percentage _(boolean)_ +- `custom_title` - Sets a custom title for the card +- `layout` - Switch between two available layouts `default` & `compact` +- `langs_count` - Limit the number of languages on the card, defaults to all reported languages +- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) +- `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. ---- +* * * # GitHub Extra Pins @@ -310,7 +307,7 @@ You can use the `&layout=compact` option to change the card design. [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) -- Compact layout +- Compact layout [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&layout=compact)](https://github.com/anuraghazra/github-readme-stats) @@ -330,65 +327,65 @@ Change the `?username=` value to your [Wakatime](https://wakatime.com) username. [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod&hide_progress=true)](https://github.com/anuraghazra/github-readme-stats) -- Compact layout +- Compact layout [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod&layout=compact)](https://github.com/anuraghazra/github-readme-stats) ---- +* * * ### All Demos -- Default +- Default ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra) -- Hiding specific stats +- Hiding specific stats ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&hide=contribs,issues) -- Showing icons +- Showing icons ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&hide=issues&show_icons=true) -- Customize Border Color +- Customize Border Color ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&border_color=2e4058) -- Include All Commits +- Include All Commits ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&include_all_commits=true) -- Themes +- Themes Choose from any of the [default themes](#themes) ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) -- Gradient +- Gradient ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&bg_color=30,e96443,904e95&title_color=fff&text_color=fff) -- Customizing stats card +- Customizing stats card ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api/?username=anuraghazra&show_icons=true&title_color=fff&icon_color=79ff97&text_color=9f9f9f&bg_color=151515) -- Setting card locale +- Setting card locale ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api/?username=anuraghazra&locale=es) -- Customizing repo card +- Customizing repo card ![Customized Card](https://github-readme-stats.vercel.app/api/pin?username=anuraghazra&repo=github-readme-stats&title_color=fff&icon_color=f9f9f9&text_color=9f9f9f&bg_color=151515) -- Top languages +- Top languages [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) -- Wakatime card +- Wakatime card [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod)](https://github.com/anuraghazra/github-readme-stats) ---- +* * * ### Quick Tip (Align The Repo Cards) @@ -416,23 +413,23 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
Guide on setting up Vercel 🔨 -1. Go to [vercel.com](https://vercel.com/) -1. Click on `Log in` - ![](https://files.catbox.moe/tct1wg.png) -1. Sign in with GitHub by pressing `Continue with GitHub` - ![](https://files.catbox.moe/btd78j.jpeg) -1. Sign in to GitHub and allow access to all repositories, if prompted -1. Fork this repo -1. After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10` -1. Go back to your [Vercel dashboard](https://vercel.com/dashboard) -1. Select `Import Project` - ![](https://files.catbox.moe/qckos0.png) -1. Select `Import Git Repository`. Select root and keep everything as is. - ![](https://files.catbox.moe/pqub9q.png) -1. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats) -1. Add the PAT as an environment variable named `PAT_1` (as shown). - ![](https://files.catbox.moe/0ez4g7.png) -1. Click deploy, and you're good to go. See your domains to use the API! +1. Go to [vercel.com](https://vercel.com/) +2. Click on `Log in` + ![](https://files.catbox.moe/tct1wg.png) +3. Sign in with GitHub by pressing `Continue with GitHub` + ![](https://files.catbox.moe/btd78j.jpeg) +4. Sign in to GitHub and allow access to all repositories, if prompted +5. Fork this repo +6. After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10` +7. Go back to your [Vercel dashboard](https://vercel.com/dashboard) +8. Select `Import Project` + ![](https://files.catbox.moe/qckos0.png) +9. Select `Import Git Repository`. Select root and keep everything as is. + ![](https://files.catbox.moe/pqub9q.png) +10. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats) +11. Add the PAT as an environment variable named `PAT_1` (as shown). + ![](https://files.catbox.moe/0ez4g7.png) +12. Click deploy, and you're good to go. See your domains to use the API!
@@ -443,17 +440,16 @@ this takes time. You can use this service for free. However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it:- -- Giving proper credit when you use github-readme-stats on your readme, linking back to it :D -- Starring and sharing the project :rocket: -- [![paypal.me/anuraghazra](https://ionicabizau.github.io/badges/paypal.svg)](https://www.paypal.me/anuraghazra) - You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea: +- Giving proper credit when you use github-readme-stats on your readme, linking back to it :D +- Starring and sharing the project :rocket: +- [![paypal.me/anuraghazra](https://ionicabizau.github.io/badges/paypal.svg)](https://www.paypal.me/anuraghazra) - You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea: Thanks! :heart: ---- +* * * [![https://vercel.com?utm_source=github_readme_stats_team&utm_campaign=oss](./powered-by-vercel.svg)](https://vercel.com?utm_source=github_readme_stats_team&utm_campaign=oss) - -Contributions are welcome! <3 +Contributions are welcome! <3 Made with :heart: and JavaScript. From c5bea57638b16002da1a93f880ebd43c01980b17 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 2 Oct 2022 18:07:43 +0200 Subject: [PATCH 55/88] docs: fix india care logo --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 51c7229b..ae803885 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@

-Give india logo +Give india logo Are you considering supporting the project by donating? Please DON'T!! From aa084f31c4f076c1d1f2fbe6855f8de30afad6aa Mon Sep 17 00:00:00 2001 From: Manan1612 Date: Mon, 3 Oct 2022 02:42:32 -0400 Subject: [PATCH 56/88] Added Contributors Badge (#2096) --- readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/readme.md b/readme.md index ae803885..b18cdf64 100644 --- a/readme.md +++ b/readme.md @@ -6,6 +6,9 @@

Tests Passing + + + GitHub Contributors From 9e1fc0b7da0e8f3721958c6db4d7b59ff841e5a3 Mon Sep 17 00:00:00 2001 From: Ayushi Vishwakarma Date: Mon, 3 Oct 2022 12:44:37 +0530 Subject: [PATCH 57/88] update default values in readme (#2094) * update default values in readme * docs: improve formatting * docs: improve readme punctation Co-authored-by: rickstaa --- readme.md | 8 ++++---- src/cards/repo-card.js | 2 +- src/cards/top-languages-card.js | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index b18cdf64..2f183364 100644 --- a/readme.md +++ b/readme.md @@ -203,12 +203,12 @@ You can provide multiple comma-separated values in the bg_color option to render #### Repo Card Exclusive Options: -- `show_owner` - Show the repo's owner name _(boolean)_ +- `show_owner` - Show the repo's owner name _(boolean)_. Defaults to `false`. #### Language Card Exclusive Options: - `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_ +- `hide_title` - _(boolean)_. Defaults to `false`. - `layout` - Switch between two available layouts `default` & `compact` - `card_width` - Set the card's width manually _(number)_ - `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_ @@ -223,8 +223,8 @@ You can provide multiple comma-separated values in the bg_color option to render #### Wakatime Card Exclusive Options: - `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_ -- `line_height` - Sets the line-height between text _(number)_ +- `hide_title` - _(boolean)_. Defaults to `false`. +- `line_height` - Sets the line-height between text _(number)_. Default Value: `25`. - `hide_progress` - Hides the progress bar and percentage _(boolean)_ - `custom_title` - Sets a custom title for the card - `layout` - Switch between two available layouts `default` & `compact` diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 7c9c4b57..5730ea4f 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -88,7 +88,7 @@ const renderRepoCard = (repo, options = {}) => { icon_color, text_color, bg_color, - show_owner, + show_owner = false, theme = "default_repocard", border_radius, border_color, diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index b181fc12..b837b358 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -235,7 +235,7 @@ const useLanguages = (topLangs, hide, langs_count) => { */ const renderTopLanguages = (topLangs, options = {}) => { const { - hide_title, + hide_title = false, hide_border, card_width, title_color, From c03bb2f250f6d65802ca16101aa38baef1022a5c Mon Sep 17 00:00:00 2001 From: Jagruti Tiwari Date: Mon, 3 Oct 2022 16:33:23 +0530 Subject: [PATCH 58/88] fix: adding docstrings to the files where it was missing (#2101) * fix: adding docstrings to missing files * style: format code * style: improve formatting Co-authored-by: Jagruti Tiwari Co-authored-by: rickstaa --- src/calculateRank.js | 24 +++++++++++++++++++++++- src/cards/stats-card.js | 13 +++++++++++++ src/common/retryer.js | 9 +++++++++ src/common/utils.js | 19 ++++++++++++++----- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index bbfece15..6c161f3f 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -1,4 +1,14 @@ -// https://stackoverflow.com/a/5263759/10629172 +/** + * Calculates the probability of x taking on x or a value less than x in a normal distribution + * with mean and standard deviation. + * + * @see https://stackoverflow.com/a/5263759/10629172 + * + * @param {string} mean + * @param {number} sigma + * @param {number} to + * @returns {number} Probability. + */ function normalcdf(mean, sigma, to) { var z = (to - mean) / Math.sqrt(2 * sigma * sigma); var t = 1 / (1 + 0.3275911 * Math.abs(z)); @@ -16,6 +26,18 @@ function normalcdf(mean, sigma, to) { return (1 / 2) * (1 + sign * erf); } +/** + * Calculates the users rank. + * + * @param {number} totalRepos + * @param {number} totalCommits + * @param {number} contributions + * @param {number} followers + * @param {number} prs + * @param {number} issues + * @param {number} stargazers + * @returns {{level: string, score: number}}} The users rank. + */ function calculateRank({ totalRepos, totalCommits, diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 4b0cd33a..f880560e 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -12,6 +12,19 @@ import { import { getStyles } from "../getStyles.js"; import { statCardLocales } from "../translations.js"; +/** + * Create a stats card text item. + * + * @param {object[]} createTextNodeParams Object that contains the createTextNode parameters. + * @param {string} createTextNodeParams.label The label to display. + * @param {string} createTextNodeParams.value The value to display. + * @param {string} createTextNodeParams.id The id of the stat. + * @param {number} createTextNodeParams.index The index of the stat. + * @param {boolean} createTextNodeParams.showIcons Whether to show icons. + * @param {number} createTextNodeParams.shiftValuePos Number of pixels the value has to be shifted to the right. + * @param {boolean} createTextNodeParams.bold Whether to bold the label. + * @returns + */ const createTextNode = ({ icon, label, diff --git a/src/common/retryer.js b/src/common/retryer.js index c898ef3f..859e94b0 100644 --- a/src/common/retryer.js +++ b/src/common/retryer.js @@ -1,5 +1,14 @@ import { CustomError, logger } from "./utils.js"; +/** + * Try to execute the fetcher function until it succeeds or the max number of retries is reached. + * + * @param {object[]} retryerParams Object that contains the createTextNode parameters. + * @param {object[]} retryerParams.fetcher The fetcher function. + * @param {object[]} retryerParams.variables Object with arguments to pass to the fetcher function. + * @param {number} retryerParams.retries How many times to retry. + * @returns Promise + */ const retryer = async (fetcher, variables, retries = 0) => { if (retries > 7) { throw new CustomError("Maximum retries exceeded", CustomError.MAX_RETRY); diff --git a/src/common/utils.js b/src/common/utils.js index 7660bbd1..ba61cf81 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -74,7 +74,10 @@ function parseBoolean(value) { } /** - * @param {string} str + * Parse string to array of strings. + * + * @param {string} str The string to parse. + * @returns {string[]} The array of strings. */ function parseArray(str) { if (!str) return []; @@ -82,9 +85,12 @@ function parseArray(str) { } /** - * @param {number} number - * @param {number} min - * @param {number} max + * Clamp the given number between the given range. + * + * @param {number} number The number to clamp. + * @param {number} min The minimum value. + * @param {number} max The maximum value. + * returns {number} The clamped number. */ function clampValue(number, min, max) { // @ts-ignore @@ -93,7 +99,10 @@ function clampValue(number, min, max) { } /** - * @param {string[]} colors + * Check if the given string is a valid gradient. + * + * @param {string[]} colors Array of colors. + * returns {boolean} True if the given string is a valid gradient. */ function isValidGradient(colors) { return isValidHexColor(colors[1]) && isValidHexColor(colors[2]); From 7accd1a8d7ead16ba32ac119f12941d7c17683e7 Mon Sep 17 00:00:00 2001 From: Aditya Shelke <103348863+adi-uchiha@users.noreply.github.com> Date: Tue, 4 Oct 2022 12:28:18 +0530 Subject: [PATCH 59/88] feat: default values for wakatime and language (#2103) * default values for wakatime and language * docs: update formatting Co-authored-by: rickstaa --- readme.md | 58 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/readme.md b/readme.md index 2f183364..0b6a54cc 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,7 @@

Tests Passing - + GitHub Contributors @@ -64,9 +64,8 @@

Love the project? Please consider donating to help it improve! -

-Give india logo + Give india logo Are you considering supporting the project by donating? Please DON'T!! @@ -74,8 +73,7 @@ Are you considering supporting the project by donating? Please DON'T!! Instead, Help India fight the 2nd deadly wave of COVID-19. Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure. -Visit and make a small donation to help us fight COVID and overcome this crisis. -A small donation goes a long way. :heart: +Visit and make a small donation to help us fight COVID and overcome this crisis. A small donation goes a long way. :heart:

@@ -142,13 +140,13 @@ To enable icons, you can pass `show_icons=true` in the query param, like so: With inbuilt themes, you can customize the look of the card without doing any [manual customization](#customization). -Use `&theme=THEME_NAME` parameter like so :- +Use `&theme=THEME_NAME` parameter like so : ```md ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) ``` -#### All inbuilt themes:- +#### All inbuilt themes dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula @@ -160,7 +158,7 @@ You can look at a preview for [all available themes](./themes/README.md) or chec You can customize the appearance of your `Stats Card` or `Repo Card` however you wish with URL params. -#### Common Options: +#### Common Options - `title_color` - Card's title color _(hex color)_. Default: `2f80ed`. - `text_color` - Body text color _(hex color)_. Default: `434d58`. @@ -183,7 +181,7 @@ You can provide multiple comma-separated values in the bg_color option to render > Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k, otherwise, it's 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. -#### Stats Card Exclusive Options: +#### Stats Card Exclusive Options - `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`. - `hide_title` - _(boolean)_. Default: `false`. @@ -201,36 +199,36 @@ You can provide multiple comma-separated values in the bg_color option to render > Note on `hide_rank`: > When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. -#### Repo Card Exclusive Options: +#### Repo Card Exclusive Options -- `show_owner` - Show the repo's owner name _(boolean)_. Defaults to `false`. +- `show_owner` - Show the repo's owner name _(boolean)_. Default: `false`. -#### Language Card Exclusive Options: +#### Language Card Exclusive Options -- `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_. Defaults to `false`. -- `layout` - Switch between two available layouts `default` & `compact` -- `card_width` - Set the card's width manually _(number)_ -- `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_ -- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_ -- `custom_title` - Sets a custom title for the card +- `hide` - Hide the languages specified from the card _(Comma-separated values)_ .Default: `[] (blank array)`. +- `hide_title` - _(boolean)_. Default: `false`. +- `layout` - Switch between two available layouts `default` & `compact`. Default: `default`. +- `card_width` - Set the card's width manually _(number)_. Default `300`. +- `langs_count` - Show more languages on the card, between 1-10 _(number)_. Default `5`. +- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. +- `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`. > :warning: **Important:** > Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding) > (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.) You can use > [urlencoder.org](https://www.urlencoder.org/) to help you do this automatically. -#### Wakatime Card Exclusive Options: +#### Wakatime Card Exclusive Options -- `hide` - Hide the languages specified from the card _(Comma-separated values)_ -- `hide_title` - _(boolean)_. Defaults to `false`. -- `line_height` - Sets the line-height between text _(number)_. Default Value: `25`. -- `hide_progress` - Hides the progress bar and percentage _(boolean)_ -- `custom_title` - Sets a custom title for the card -- `layout` - Switch between two available layouts `default` & `compact` -- `langs_count` - Limit the number of languages on the card, defaults to all reported languages -- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) -- `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. +- `hide` - Hide the languages specified from the card _(Comma-separated values)_. Default: `[] (blank array)`. +- `hide_title` - _(boolean)_. Default `false`. +- `line_height` - Sets the line-height between text _(number)_. Default `25`. +- `hide_progress` - Hides the progress bar and percentage _(boolean)_. Default `false`. +- `custom_title` - Sets a custom title for the card _(string)_. Default `Wakatime Stats`. +- `layout` - Switch between two available layouts `default` & `compact`. Default `default`. +- `langs_count` - Limit the number of languages on the card, defaults to all reported languages _(number)_. Default `50`. +- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) _(string)_. Default `Wakapi`. +- `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. _(YYYY-MM, last_7_days, last_30_days, last_6_months, last_year, or all_time)_. Default `all_time`. * * * @@ -441,7 +439,7 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we I open-source almost everything I can, and I try to reply to everyone needing help using these projects. Obviously, this takes time. You can use this service for free. -However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it:- +However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it: - Giving proper credit when you use github-readme-stats on your readme, linking back to it :D - Starring and sharing the project :rocket: From e6a6384eff601d201a9a37b75d004b5e555c3c49 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 4 Oct 2022 09:19:37 +0200 Subject: [PATCH 60/88] docs: improve readme syntax (#2106) --- readme.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/readme.md b/readme.md index 0b6a54cc..6f741b74 100644 --- a/readme.md +++ b/readme.md @@ -68,9 +68,9 @@ Give india logo -Are you considering supporting the project by donating? Please DON'T!! +Are you considering supporting the project by donating? Please DO NOT!! -Instead, Help India fight the 2nd deadly wave of COVID-19. +Instead, Help India fight the second deadly wave of COVID-19. Thousands of people are dying in India because of a lack of Oxygen & also COVID-related infrastructure. Visit and make a small donation to help us fight COVID and overcome this crisis. A small donation goes a long way. :heart: @@ -94,7 +94,7 @@ Visit and make a small donation to hel # GitHub Stats Card -Copy-paste this into your markdown content, and that's it. Simple! +Copy-paste this into your markdown content, and that is it. Simple! Change the `?username=` value to your GitHub username. @@ -108,7 +108,7 @@ The implementation can be investigated at [src/calculateRank.js](./src/calculate ### Hiding individual stats -To hide any specific stats, you can pass a query parameter `&hide=` with comma-separated values. +You can pass a query parameter `&hide=` to hide any specific stats with comma-separated values. > Options: `&hide=stars,commits,prs,issues,contribs` @@ -120,7 +120,7 @@ To hide any specific stats, you can pass a query parameter `&hide=` with comma-s You can add the count of all your private contributions to the total commits count by using the query parameter `&count_private=true`. -_Note: If you are deploying this project yourself, the private contributions will be counted by default. Otherwise, you need to choose to share your private contribution counts._ +_Note: If you are deploying this project yourself, the private contributions will be counted by default. If you are using the public Vercel instance, you need to choose to [share your private contributions](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/showing-your-private-contributions-and-achievements-on-your-profile)._ > Options: `&count_private=true` @@ -148,7 +148,7 @@ Use `&theme=THEME_NAME` parameter like so : #### All inbuilt themes -dark, radical, merko, gruvbox, tokyonight, onedark, cobalt, synthwave, highcontrast, dracula +Github readme stats comes with several built-in themes (e.g. `dark`, `radical`, `merko`, `gruvbox`, `tokyonight`, `onedark`, `cobalt`, `synthwave`, `highcontrast`, `dracula`). GitHub Readme Stats Themes @@ -156,7 +156,7 @@ You can look at a preview for [all available themes](./themes/README.md) or chec ### Customization -You can customize the appearance of your `Stats Card` or `Repo Card` however you wish with URL params. +You can customize the appearance of your `Stats Card` or `Repo Card` however you wish with URL parameters. #### Common Options @@ -175,11 +175,11 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you ##### Gradient in bg_color -You can provide multiple comma-separated values in the bg_color option to render a gradient, with the following format: +You can provide multiple comma-separated values in the bg_color option to render a gradient with the following format: &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 -> Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k, otherwise, it's 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. +> Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. #### Stats Card Exclusive Options @@ -190,7 +190,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `show_icons` - _(boolean)_. Default: `false`. - `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_. Default: `false`. - `count_private` - Count private commits _(boolean)_. Default: `false`. -- `line_height` - Sets the line-height between text _(number)_. Default: `25`. +- `line_height` - Sets the line height between text _(number)_. Default: `25`. - `exclude_repo` - Exclude stars from specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. - `custom_title` - Sets a custom title for the card. Default: ` Github Stats`. - `text_bold` - Use bold text _(boolean)_. Default: `true`. @@ -205,7 +205,7 @@ You can provide multiple comma-separated values in the bg_color option to render #### Language Card Exclusive Options -- `hide` - Hide the languages specified from the card _(Comma-separated values)_ .Default: `[] (blank array)`. +- `hide` - Hide the languages specified from the card _(Comma-separated values)_. Default: `[] (blank array)`. - `hide_title` - _(boolean)_. Default: `false`. - `layout` - Switch between two available layouts `default` & `compact`. Default: `default`. - `card_width` - Set the card's width manually _(number)_. Default `300`. @@ -214,7 +214,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`. > :warning: **Important:** -> Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding) +> Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding) > (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.) You can use > [urlencoder.org](https://www.urlencoder.org/) to help you do this automatically. @@ -222,19 +222,19 @@ You can provide multiple comma-separated values in the bg_color option to render - `hide` - Hide the languages specified from the card _(Comma-separated values)_. Default: `[] (blank array)`. - `hide_title` - _(boolean)_. Default `false`. -- `line_height` - Sets the line-height between text _(number)_. Default `25`. +- `line_height` - Sets the line height between text _(number)_. Default `25`. - `hide_progress` - Hides the progress bar and percentage _(boolean)_. Default `false`. - `custom_title` - Sets a custom title for the card _(string)_. Default `Wakatime Stats`. - `layout` - Switch between two available layouts `default` & `compact`. Default `default`. -- `langs_count` - Limit the number of languages on the card, defaults to all reported languages _(number)_. Default `50`. -- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) _(string)_. Default `Wakapi`. +- `langs_count` - Limit the number of languages on the card, defaults to all reported languages _(number)_. +- `api_domain` - Set a custom API domain for the card, e.g. to use services like [Hakatime](https://github.com/mujx/hakatime) or [Wakapi](https://github.com/muety/wakapi) _(string)_. Default `Waka API`. - `range` – Request a range different from your WakaTime default, e.g. `last_7_days`. See [WakaTime API docs](https://wakatime.com/developers#stats) for a list of available options. _(YYYY-MM, last_7_days, last_30_days, last_6_months, last_year, or all_time)_. Default `all_time`. * * * # GitHub Extra Pins -GitHub extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile. +GitHub extra pins allow you to pin more than six repositories in your profile using a GitHub readme profile. Yay! You are no longer limited to 6 pinned repositories. @@ -260,7 +260,7 @@ Use [show_owner](#customization) variable to include the repo's owner username The top languages card shows a GitHub user's most frequently used top language. -_NOTE: Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It's a new feature of github-readme-stats._ +_NOTE: Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It is a new feature of github-readme-stats._ ### Usage @@ -274,7 +274,7 @@ Endpoint: `api/top-langs?username=anuraghazra` ### Exclude individual repositories -You can use `&exclude_repo=repo1,repo2` parameter to exclude individual repositories. +You can use the `&exclude_repo=repo1,repo2` parameter to exclude individual repositories. ```md [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&exclude_repo=github-readme-stats,anuraghazra.github.io)](https://github.com/anuraghazra/github-readme-stats) @@ -382,7 +382,7 @@ Choose from any of the [default themes](#themes) [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) -- Wakatime card +- WakaTime card [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod)](https://github.com/anuraghazra/github-readme-stats) @@ -390,7 +390,7 @@ Choose from any of the [default themes](#themes) ### Quick Tip (Align The Repo Cards) -You usually won't be able to layout the images side by side. To do that you can use this approach: +By default, GitHub does not lay out the cards side by side. To do that, you can use this approach: ```html @@ -405,7 +405,7 @@ You usually won't be able to layout the images side by side. To do that you can #### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107) -Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you don't have to worry about anything. Click on the deploy button to get started! +Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Click on the deploy button to get started! NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we should be able to handle more than 5k requests and have no issues with downtime :D @@ -436,7 +436,7 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we ## :sparkling_heart: Support the project -I open-source almost everything I can, and I try to reply to everyone needing help using these projects. Obviously, +I open-source almost everything I can and try to reply to everyone needing help using these projects. Obviously, this takes time. You can use this service for free. However, if you are using this project and are happy with it or just want to encourage me to continue creating stuff, there are a few ways you can do it: From 388ba06a8fb3880cae8734498c8564bb70a99e7c Mon Sep 17 00:00:00 2001 From: Akshat Goel <98082704+DecryptAG@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:02:40 +0530 Subject: [PATCH 61/88] Update the Vercel deployement guide (#2102) * Update the Vercel deployement guide Updated Readme.md - The guide on deploying your own Vercel instance * docs: fix some small grammer errors Co-authored-by: rickstaa --- readme.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/readme.md b/readme.md index 6f741b74..8130a334 100644 --- a/readme.md +++ b/readme.md @@ -414,22 +414,22 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
Guide on setting up Vercel 🔨 -1. Go to [vercel.com](https://vercel.com/) -2. Click on `Log in` - ![](https://files.catbox.moe/tct1wg.png) -3. Sign in with GitHub by pressing `Continue with GitHub` - ![](https://files.catbox.moe/btd78j.jpeg) -4. Sign in to GitHub and allow access to all repositories, if prompted -5. Fork this repo -6. After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10` -7. Go back to your [Vercel dashboard](https://vercel.com/dashboard) -8. Select `Import Project` - ![](https://files.catbox.moe/qckos0.png) -9. Select `Import Git Repository`. Select root and keep everything as is. - ![](https://files.catbox.moe/pqub9q.png) -10. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats) +1. Go to [vercel.com](https://vercel.com/). +2. Click on `Log in`. + ![](https://files.catbox.moe/pcxk33.png) +3. Sign in with GitHub by pressing `Continue with GitHub`. + ![](https://files.catbox.moe/b9oxey.png) +4. Sign in to GitHub and allow access to all repositories if prompted. +5. Fork this repo. +6. After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10`. +7. Go back to your [Vercel dashboard](https://vercel.com/dashboard). +8. To import a project, click the `Add New...` button and select the `Project` option. + ![](https://files.catbox.moe/3n76fh.png) +9. Click the `Continue with GitHub` button, search for the required Git Repository and import it by clicking the `Import` button. Alternatively, you can import a Third-Party Git Repository using the `Import Third-Party Git Repository ->` link at the bottom of the page. + ![](https://files.catbox.moe/mg5p04.png) +10. Create a personal access token (PAT) [here](https://github.com/settings/tokens/new) and enable the `repo` permissions (this allows access to see private repo stats). 11. Add the PAT as an environment variable named `PAT_1` (as shown). - ![](https://files.catbox.moe/0ez4g7.png) + ![](https://files.catbox.moe/0yclio.png) 12. Click deploy, and you're good to go. See your domains to use the API!
From acbc03dc0f2e70da946fbb75822bbe9d041fb729 Mon Sep 17 00:00:00 2001 From: nekiwo <58634064+nekiwo@users.noreply.github.com> Date: Tue, 4 Oct 2022 03:00:48 -0500 Subject: [PATCH 62/88] Fix card length during error (#2105) * Fix card length during error Fixes #1774 The size of the box should be 550px to allow 25px padding from both sides I found the width of the text using `getComputedTextLength()` method * fix: improve error card size Co-authored-by: rickstaa --- src/common/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/utils.js b/src/common/utils.js index ba61cf81..fc462d32 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -11,13 +11,13 @@ import { themes } from "../../themes/index.js"; */ const renderError = (message, secondaryMessage = "") => { return ` - + - + Something went wrong! file an issue at https://tiny.one/readme-stats ${encodeHTML(message)} From af97e5765bea4945e3208e63d272248b91da2b3c Mon Sep 17 00:00:00 2001 From: Matteo Pierro Date: Tue, 4 Oct 2022 12:10:50 +0100 Subject: [PATCH 63/88] fix: fetch all repos for for the stats card (#2100) * fetch all stars * stop fetching when there are repos with zero stars * remove not needed parameters from the query * add docstring * removed not needed mock * style: update formatting Co-authored-by: rickstaa --- src/fetchers/stats-fetcher.js | 78 ++++++++++++++++++++++++---- tests/api.test.js | 20 +++++++- tests/fetchStats.test.js | 95 ++++++++++++++++++++++++++++++++--- 3 files changed, 175 insertions(+), 18 deletions(-) diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index b9493adf..8f8a8200 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -29,10 +29,10 @@ const fetcher = (variables, token) => { totalCommitContributions restrictedContributionsCount } - repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) { + repositoriesContributedTo(contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) { totalCount } - pullRequests(first: 1) { + pullRequests { totalCount } openIssues: issues(states: OPEN) { @@ -44,14 +44,41 @@ const fetcher = (variables, token) => { followers { totalCount } - repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}) { + repositories(ownerAffiliations: OWNER) { totalCount + } + } + } + `, + variables, + }, + { + Authorization: `bearer ${token}`, + }, + ); +}; + +/** + * @param {import('axios').AxiosRequestHeaders} variables + * @param {string} token + */ +const repositoriesFetcher = (variables, token) => { + return request( + { + query: ` + query userInfo($login: String!, $after: String) { + user(login: $login) { + repositories(first: 100, ownerAffiliations: OWNER, orderBy: {direction: DESC, field: STARGAZERS}, after: $after) { nodes { name stargazers { totalCount } } + pageInfo { + hasNextPage + endCursor + } } } } @@ -99,6 +126,43 @@ const totalCommitsFetcher = async (username) => { return 0; }; +/** + * Fetch all the stars for all the repositories of a given username + * @param {string} username + * @param {array} repoToHide + */ +const totalStarsFetcher = async (username, repoToHide) => { + let nodes = []; + let hasNextPage = true; + let endCursor = null; + while (hasNextPage) { + const variables = { login: username, first: 100, after: endCursor }; + let res = await retryer(repositoriesFetcher, variables); + + if (res.data.errors) { + logger.error(res.data.errors); + throw new CustomError( + res.data.errors[0].message || "Could not fetch user", + CustomError.USER_NOT_FOUND, + ); + } + + const allNodes = res.data.data.user.repositories.nodes; + const nodesWithStars = allNodes.filter( + (node) => node.stargazers.totalCount !== 0, + ); + nodes.push(...nodesWithStars); + hasNextPage = + allNodes.length === nodesWithStars.length && + res.data.data.user.repositories.pageInfo.hasNextPage; + endCursor = res.data.data.user.repositories.pageInfo.endCursor; + } + + return nodes + .filter((data) => !repoToHide[data.name]) + .reduce((prev, curr) => prev + curr.stargazers.totalCount, 0); +}; + /** * @param {string} username * @param {boolean} count_private @@ -166,13 +230,7 @@ async function fetchStats( stats.contributedTo = user.repositoriesContributedTo.totalCount; // Retrieve stars while filtering out repositories to be hidden - stats.totalStars = user.repositories.nodes - .filter((data) => { - return !repoToHide[data.name]; - }) - .reduce((prev, curr) => { - return prev + curr.stargazers.totalCount; - }, 0); + stats.totalStars = await totalStarsFetcher(username, repoToHide); stats.rank = calculateRank({ totalCommits: stats.totalCommits, diff --git a/tests/api.test.js b/tests/api.test.js index b0dfc59f..a6bb0920 100644 --- a/tests/api.test.js +++ b/tests/api.test.js @@ -40,7 +40,20 @@ const data = { followers: { totalCount: 0 }, repositories: { totalCount: 1, + }, + }, + }, +}; + +const repositoriesData = { + data: { + user: { + repositories: { nodes: [{ stargazers: { totalCount: 100 } }], + pageInfo: { + hasNextPage: false, + cursor: "cursor", + }, }, }, }, @@ -70,7 +83,11 @@ const faker = (query, data) => { setHeader: jest.fn(), send: jest.fn(), }; - mock.onPost("https://api.github.com/graphql").reply(200, data); + mock + .onPost("https://api.github.com/graphql") + .replyOnce(200, data) + .onPost("https://api.github.com/graphql") + .replyOnce(200, repositoriesData); return { req, res }; }; @@ -138,7 +155,6 @@ describe("Test /api/", () => { it("should have proper cache", async () => { const { req, res } = faker({}, data); - mock.onPost("https://api.github.com/graphql").reply(200, data); await api(req, res); diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js index f8eae981..9ccdcb21 100644 --- a/tests/fetchStats.test.js +++ b/tests/fetchStats.test.js @@ -19,13 +19,61 @@ const data = { followers: { totalCount: 100 }, repositories: { totalCount: 5, + }, + }, + }, +}; + +const firstRepositoriesData = { + data: { + user: { + repositories: { nodes: [ { name: "test-repo-1", stargazers: { totalCount: 100 } }, { name: "test-repo-2", stargazers: { totalCount: 100 } }, { name: "test-repo-3", stargazers: { totalCount: 100 } }, + ], + pageInfo: { + hasNextPage: true, + cursor: "cursor", + }, + }, + }, + }, +}; + +const secondRepositoriesData = { + data: { + user: { + repositories: { + nodes: [ { name: "test-repo-4", stargazers: { totalCount: 50 } }, { name: "test-repo-5", stargazers: { totalCount: 50 } }, ], + pageInfo: { + hasNextPage: false, + cursor: "cursor", + }, + }, + }, + }, +}; + +const repositoriesWithZeroStarsData = { + data: { + user: { + repositories: { + nodes: [ + { name: "test-repo-1", stargazers: { totalCount: 100 } }, + { name: "test-repo-2", stargazers: { totalCount: 100 } }, + { name: "test-repo-3", stargazers: { totalCount: 100 } }, + { name: "test-repo-4", stargazers: { totalCount: 0 } }, + { name: "test-repo-5", stargazers: { totalCount: 0 } }, + ], + pageInfo: { + hasNextPage: true, + cursor: "cursor", + }, }, }, }, @@ -44,14 +92,22 @@ const error = { const mock = new MockAdapter(axios); +beforeEach(() => { + mock + .onPost("https://api.github.com/graphql") + .replyOnce(200, data) + .onPost("https://api.github.com/graphql") + .replyOnce(200, firstRepositoriesData) + .onPost("https://api.github.com/graphql") + .replyOnce(200, secondRepositoriesData); +}); + afterEach(() => { mock.reset(); }); describe("Test fetchStats", () => { it("should fetch correct stats", async () => { - mock.onPost("https://api.github.com/graphql").reply(200, data); - let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ totalCommits: 100, @@ -74,7 +130,38 @@ describe("Test fetchStats", () => { }); }); + it("should stop fetching when there are repos with zero stars", async () => { + mock.reset(); + mock + .onPost("https://api.github.com/graphql") + .replyOnce(200, data) + .onPost("https://api.github.com/graphql") + .replyOnce(200, repositoriesWithZeroStarsData); + + let stats = await fetchStats("anuraghazra"); + const rank = calculateRank({ + totalCommits: 100, + totalRepos: 5, + followers: 100, + contributions: 61, + stargazers: 300, + prs: 300, + issues: 200, + }); + + expect(stats).toStrictEqual({ + contributedTo: 61, + name: "Anurag Hazra", + totalCommits: 100, + totalIssues: 200, + totalPRs: 300, + totalStars: 300, + rank, + }); + }); + it("should throw error", async () => { + mock.reset(); mock.onPost("https://api.github.com/graphql").reply(200, error); await expect(fetchStats("anuraghazra")).rejects.toThrow( @@ -83,8 +170,6 @@ describe("Test fetchStats", () => { }); it("should fetch and add private contributions", async () => { - mock.onPost("https://api.github.com/graphql").reply(200, data); - let stats = await fetchStats("anuraghazra", true); const rank = calculateRank({ totalCommits: 150, @@ -108,7 +193,6 @@ describe("Test fetchStats", () => { }); it("should fetch total commits", async () => { - mock.onPost("https://api.github.com/graphql").reply(200, data); mock .onGet("https://api.github.com/search/commits?q=author:anuraghazra") .reply(200, { total_count: 1000 }); @@ -136,7 +220,6 @@ describe("Test fetchStats", () => { }); it("should exclude stars of the `test-repo-1` repository", async () => { - mock.onPost("https://api.github.com/graphql").reply(200, data); mock .onGet("https://api.github.com/search/commits?q=author:anuraghazra") .reply(200, { total_count: 1000 }); From 94d0978d2bf7c5324513ac924cb42afe1e7774cc Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Tue, 4 Oct 2022 14:19:30 +0200 Subject: [PATCH 64/88] docs: fix readme logo alignment (#2112) --- readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8130a334..c905155f 100644 --- a/readme.md +++ b/readme.md @@ -62,7 +62,8 @@ Türkçe

-

Love the project? Please consider donating to help it improve! + +

Love the project? Please consider donating to help it improve!

Give india logo From aae83cb22e64e48b3b0546b719bb25c328c31aa3 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Wed, 5 Oct 2022 00:47:14 +0200 Subject: [PATCH 65/88] fix: temporary disable multi page star fetch --- src/fetchers/stats-fetcher.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 8f8a8200..4fa26044 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -152,9 +152,10 @@ const totalStarsFetcher = async (username, repoToHide) => { (node) => node.stargazers.totalCount !== 0, ); nodes.push(...nodesWithStars); - hasNextPage = - allNodes.length === nodesWithStars.length && - res.data.data.user.repositories.pageInfo.hasNextPage; + // hasNextPage = + // allNodes.length === nodesWithStars.length && + // res.data.data.user.repositories.pageInfo.hasNextPage; + hasNextPage = false // NOTE: Temporarily disable fetching of multiple pages. endCursor = res.data.data.user.repositories.pageInfo.endCursor; } From cea4a39548e81f387b819b9dab81e88f41ff1c20 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 11:09:31 +0200 Subject: [PATCH 66/88] ci: improve theme preview action This commit makes sure that theme PRs that contain invalid JSON are labeled `invalid` and changes are requested. --- scripts/preview-theme.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 58aad028..f7c07194 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -24,7 +24,7 @@ const THEME_PR_FAIL_TEXT = ":x: Theme PR does not adhere to our guidelines."; const THEME_PR_SUCCESS_TEXT = ":heavy_check_mark: Theme PR does adhere to our guidelines."; const FAIL_TEXT = ` - \rUnfortunately, your theme PR does not adhere to our [theme guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). Please fix the issues below, and we will review your\ + \r Unfortunately, your theme PR contains an error or does not adhere to our [theme guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). Please fix the issues below, and we will review your\ \r PR again. This pull request will **automatically close in 15 days** if no changes are made. After this time, you must re-open the PR for it to be reviewed. `; const THEME_CONTRIB_GUIDELINESS = ` @@ -558,6 +558,21 @@ export const run = async (prNumber) => { info(`DRY_RUN: Review reason: ${reviewReason}`); } } catch (error) { + debug("Set review state to `REQUEST_CHANGES` and add `invalid` label..."); + if (!dryRun) { + await addReview( + octokit, + pullRequestId, + owner, + repo, + "REQUEST_CHANGES", + error.message, + ); + await addRemoveLabel(octokit, pullRequestId, owner, repo, "invalid", true); + } else { + info(`DRY_RUN: Review state: REQUEST_CHANGES`); + info(`DRY_RUN: Review reason: ${error.message}`); + } setFailed(error.message); } }; From 04595dfe62fca2f0cf6a7a7b9d24d3694cf6c4b0 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 11:10:48 +0200 Subject: [PATCH 67/88] style: improve formatting --- scripts/preview-theme.js | 9 ++++++++- src/fetchers/stats-fetcher.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index f7c07194..1747ee97 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -568,7 +568,14 @@ export const run = async (prNumber) => { "REQUEST_CHANGES", error.message, ); - await addRemoveLabel(octokit, pullRequestId, owner, repo, "invalid", true); + await addRemoveLabel( + octokit, + pullRequestId, + owner, + repo, + "invalid", + true, + ); } else { info(`DRY_RUN: Review state: REQUEST_CHANGES`); info(`DRY_RUN: Review reason: ${error.message}`); diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 4fa26044..40947564 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -155,7 +155,7 @@ const totalStarsFetcher = async (username, repoToHide) => { // hasNextPage = // allNodes.length === nodesWithStars.length && // res.data.data.user.repositories.pageInfo.hasNextPage; - hasNextPage = false // NOTE: Temporarily disable fetching of multiple pages. + hasNextPage = false; // NOTE: Temporarily disable fetching of multiple pages. endCursor = res.data.data.user.repositories.pageInfo.endCursor; } From bcb8ae92818de7430a9b340e2b78cd8437ee65e6 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 11:13:01 +0200 Subject: [PATCH 68/88] style: improve small syntax error --- scripts/preview-theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 1747ee97..0dc3da25 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -24,7 +24,7 @@ const THEME_PR_FAIL_TEXT = ":x: Theme PR does not adhere to our guidelines."; const THEME_PR_SUCCESS_TEXT = ":heavy_check_mark: Theme PR does adhere to our guidelines."; const FAIL_TEXT = ` - \r Unfortunately, your theme PR contains an error or does not adhere to our [theme guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). Please fix the issues below, and we will review your\ + \rUnfortunately, your theme PR contains an error or does not adhere to our [theme guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). Please fix the issues below, and we will review your\ \r PR again. This pull request will **automatically close in 15 days** if no changes are made. After this time, you must re-open the PR for it to be reviewed. `; const THEME_CONTRIB_GUIDELINESS = ` From e8dfbde7bb4e05e3e6600e3837ebbdd1b9ff5f3b Mon Sep 17 00:00:00 2001 From: Taehyun Hwang Date: Fri, 7 Oct 2022 19:33:54 +0900 Subject: [PATCH 69/88] Add format script to pre-commit hook (#2146) * Add format script to pre-commit hook * build: add husky prepare step * build: add lint-staged * build: add lint-staged Co-authored-by: rickstaa --- .husky/.gitignore | 1 + .husky/pre-commit | 5 + package-lock.json | 1259 +++++++++++++++++++++++++++++++-------------- package.json | 14 +- 4 files changed, 889 insertions(+), 390 deletions(-) create mode 100644 .husky/.gitignore create mode 100755 .husky/pre-commit diff --git a/.husky/.gitignore b/.husky/.gitignore new file mode 100644 index 00000000..31354ec1 --- /dev/null +++ b/.husky/.gitignore @@ -0,0 +1 @@ +_ diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..e1c12eb0 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm test +npx lint-staged diff --git a/package-lock.json b/package-lock.json index 2235a4b4..048c316b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,10 +25,11 @@ "axios-mock-adapter": "^1.18.1", "color-contrast-checker": "^2.1.0", "hjson": "^3.2.2", - "husky": "^4.2.5", + "husky": "^8.0.0", "jest": "^29.0.3", "jest-environment-jsdom": "^29.0.3", "js-yaml": "^4.1.0", + "lint-staged": "^13.0.3", "lodash.snakecase": "^4.1.1", "parse-diff": "^0.7.0", "prettier": "^2.1.2" @@ -1427,12 +1428,6 @@ "integrity": "sha512-Sq1itGUKUX1ap7GgZlrzdBydjbsJL/NSQt/4wkAxUJ7/OS5c2WkoN6WSpWc2Yc5wtKMZOUA0VCs/j2XJadN3HA==", "dev": true }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "node_modules/@types/prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", @@ -1542,6 +1537,19 @@ "node": ">= 6.0.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1609,6 +1617,15 @@ "node": ">=6.0" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1869,18 +1886,99 @@ "node": ">=10" } }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "node_modules/cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1932,6 +2030,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1944,11 +2048,14 @@ "node": ">= 0.8" } }, - "node_modules/compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true + "node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } }, "node_modules/concat-map": { "version": "0.0.1", @@ -1965,22 +2072,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2142,6 +2233,12 @@ "node": ">=10" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "node_modules/electron-to-chromium": { "version": "1.4.260", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.260.tgz", @@ -2373,21 +2470,6 @@ "node": ">=8" } }, - "node_modules/find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "dependencies": { - "semver-regex": "^3.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -2611,33 +2693,18 @@ } }, "node_modules/husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", + "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", "dev": true, - "hasInstallScript": true, - "dependencies": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, "bin": { - "husky-run": "bin/run.js", - "husky-upgrade": "lib/upgrader/bin.js" + "husky": "lib/bin.js" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/husky" + "url": "https://github.com/sponsors/typicode" } }, "node_modules/iconv-lite": { @@ -2652,22 +2719,6 @@ "node": ">=0.10.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -3920,12 +3971,218 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/lint-staged": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz", + "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==", + "dev": true, + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.17", + "commander": "^9.3.0", + "debug": "^4.3.4", + "execa": "^6.1.0", + "lilconfig": "2.0.5", + "listr2": "^4.0.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.2", + "pidtree": "^0.6.0", + "string-argv": "^0.3.1", + "yaml": "^2.1.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", + "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^3.0.1", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", + "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "dev": true, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3950,6 +4207,55 @@ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", "dev": true }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -4166,6 +4472,15 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4190,15 +4505,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true, - "bin": { - "opencollective-postinstall": "index.js" - } - }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -4258,6 +4564,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -4267,18 +4588,6 @@ "node": ">=6" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse-diff": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.7.1.tgz", @@ -4348,15 +4657,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4375,6 +4675,18 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -4384,73 +4696,6 @@ "node": ">= 6" } }, - "node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "dependencies": { - "semver-compare": "^1.0.0" - } - }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -4613,15 +4858,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -4631,6 +4867,34 @@ "node": ">=10" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -4664,24 +4928,6 @@ "semver": "bin/semver.js" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true - }, - "node_modules/semver-regex": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", - "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4724,6 +4970,46 @@ "node": ">=8" } }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.1.tgz", + "integrity": "sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -4761,6 +5047,15 @@ "node": ">=10" } }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -4915,6 +5210,12 @@ "node": ">=8" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -4969,6 +5270,12 @@ "node": ">=12" } }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -5178,15 +5485,6 @@ "node": ">= 8" } }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -5283,12 +5581,12 @@ "dev": true }, "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz", + "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==", "dev": true, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/yargs": { @@ -6471,12 +6769,6 @@ "integrity": "sha512-Sq1itGUKUX1ap7GgZlrzdBydjbsJL/NSQt/4wkAxUJ7/OS5c2WkoN6WSpWc2Yc5wtKMZOUA0VCs/j2XJadN3HA==", "dev": true }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, "@types/prettier": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", @@ -6570,6 +6862,16 @@ "debug": "4" } }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6616,6 +6918,12 @@ "integrity": "sha512-eigU3vhqSO+Z8BKDnVLN/ompjhf3pYzecKXz8+whRy+9gZu8n1TCGfwzQUUPnqdHl9ax1Hr9031orZ+UOEYr7Q==", "dev": true }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6808,18 +7116,71 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "cjs-module-lexer": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -6864,6 +7225,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -6873,10 +7240,10 @@ "delayed-stream": "~1.0.0" } }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", "dev": true }, "concat-map": { @@ -6894,19 +7261,6 @@ "safe-buffer": "~5.1.1" } }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -7035,6 +7389,12 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==" }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, "electron-to-chromium": { "version": "1.4.260", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.260.tgz", @@ -7208,15 +7568,6 @@ "path-exists": "^4.0.0" } }, - "find-versions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", - "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", - "dev": true, - "requires": { - "semver-regex": "^3.1.2" - } - }, "follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -7371,22 +7722,10 @@ "dev": true }, "husky": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", - "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^4.0.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^5.0.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - } + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", + "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", + "dev": true }, "iconv-lite": { "version": "0.6.3", @@ -7397,16 +7736,6 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -8354,12 +8683,145 @@ "type-check": "~0.3.2" } }, + "lilconfig": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "dev": true + }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "lint-staged": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.0.3.tgz", + "integrity": "sha512-9hmrwSCFroTSYLjflGI8Uk+GWAwMB4OlpU4bMJEAT5d/llQwtYKoim4bLOyLCuWFAhWEupE0vkIFqtw/WIsPug==", + "dev": true, + "requires": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.17", + "commander": "^9.3.0", + "debug": "^4.3.4", + "execa": "^6.1.0", + "lilconfig": "2.0.5", + "listr2": "^4.0.5", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.2", + "pidtree": "^0.6.0", + "string-argv": "^0.3.1", + "yaml": "^2.1.1" + }, + "dependencies": { + "execa": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", + "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^3.0.1", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + } + }, + "human-signals": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", + "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "dev": true + }, + "is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true + }, + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true + }, + "npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, + "requires": { + "path-key": "^4.0.0" + } + }, + "onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "requires": { + "mimic-fn": "^4.0.0" + } + }, + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + }, + "strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true + } + } + }, + "listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -8381,6 +8843,42 @@ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", "dev": true }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -8552,6 +9050,12 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8570,12 +9074,6 @@ "mimic-fn": "^2.1.0" } }, - "opencollective-postinstall": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", - "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", - "dev": true - }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -8619,21 +9117,21 @@ } } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, "parse-diff": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.7.1.tgz", @@ -8685,12 +9183,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -8703,60 +9195,18 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true + }, "pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -8878,18 +9328,37 @@ } } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -8917,18 +9386,6 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true - }, - "semver-regex": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", - "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", - "dev": true - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8962,6 +9419,30 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.1.tgz", + "integrity": "sha512-qDOv24WjnYuL+wbwHdlsYZFy+cgPtrYw0Tn7GLORicQp9BkQLzrgI3Pm4VyR9ERZ41YTn7KlMPuL1n05WdZvmg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8993,6 +9474,12 @@ "escape-string-regexp": "^2.0.0" } }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -9102,6 +9589,12 @@ "minimatch": "^3.0.4" } }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -9144,6 +9637,12 @@ "punycode": "^2.1.1" } }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "dev": true + }, "tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -9292,12 +9791,6 @@ "isexe": "^2.0.0" } }, - "which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -9362,9 +9855,9 @@ "dev": true }, "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.3.tgz", + "integrity": "sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==", "dev": true }, "yargs": { diff --git a/package.json b/package.json index ffadefde..5fc44927 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,9 @@ "preview-theme": "node scripts/preview-theme", "close-stale-theme-prs": "node scripts/close-stale-theme-prs", "generate-langs-json": "node scripts/generate-langs-json", - "format": "./node_modules/.bin/prettier --write .", - "format:check": "./node_modules/.bin/prettier --check ." + "format": "prettier --write .", + "format:check": "prettier --check .", + "prepare": "husky install" }, "author": "Anurag Hazra", "license": "MIT", @@ -27,10 +28,11 @@ "axios-mock-adapter": "^1.18.1", "color-contrast-checker": "^2.1.0", "hjson": "^3.2.2", - "husky": "^4.2.5", + "husky": "^8.0.0", "jest": "^29.0.3", "jest-environment-jsdom": "^29.0.3", "js-yaml": "^4.1.0", + "lint-staged": "^13.0.3", "lodash.snakecase": "^4.1.1", "parse-diff": "^0.7.0", "prettier": "^2.1.2" @@ -43,9 +45,7 @@ "upgrade": "^1.1.0", "word-wrap": "^1.2.3" }, - "husky": { - "hooks": { - "pre-commit": "npm test" - } + "lint-staged": { + "*.{js,css,md}": "prettier --write" } } From 15620a11db5c57c5ac066ba4b0caf31a09c65ea7 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 12:42:04 +0200 Subject: [PATCH 70/88] test: fix tests --- src/fetchers/stats-fetcher.js | 2 +- tests/fetchStats.test.js | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 40947564..941c7e14 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -155,7 +155,7 @@ const totalStarsFetcher = async (username, repoToHide) => { // hasNextPage = // allNodes.length === nodesWithStars.length && // res.data.data.user.repositories.pageInfo.hasNextPage; - hasNextPage = false; // NOTE: Temporarily disable fetching of multiple pages. + hasNextPage = false; // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. endCursor = res.data.data.user.repositories.pageInfo.endCursor; } diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js index 9ccdcb21..192146ea 100644 --- a/tests/fetchStats.test.js +++ b/tests/fetchStats.test.js @@ -97,9 +97,9 @@ beforeEach(() => { .onPost("https://api.github.com/graphql") .replyOnce(200, data) .onPost("https://api.github.com/graphql") - .replyOnce(200, firstRepositoriesData) - .onPost("https://api.github.com/graphql") - .replyOnce(200, secondRepositoriesData); + .replyOnce(200, firstRepositoriesData); + // .onPost("https://api.github.com/graphql") // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + // .replyOnce(200, secondRepositoriesData); // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. }); afterEach(() => { @@ -114,7 +114,8 @@ describe("Test fetchStats", () => { totalRepos: 5, followers: 100, contributions: 61, - stargazers: 400, + // stargazers: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + stargazers: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. prs: 300, issues: 200, }); @@ -125,7 +126,8 @@ describe("Test fetchStats", () => { totalCommits: 100, totalIssues: 200, totalPRs: 300, - totalStars: 400, + // totalStars: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + totalStars: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. rank, }); }); @@ -176,7 +178,8 @@ describe("Test fetchStats", () => { totalRepos: 5, followers: 100, contributions: 61, - stargazers: 400, + // stargazers: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + stargazers: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. prs: 300, issues: 200, }); @@ -187,7 +190,8 @@ describe("Test fetchStats", () => { totalCommits: 150, totalIssues: 200, totalPRs: 300, - totalStars: 400, + // totalStars: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + totalStars: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. rank, }); }); @@ -203,7 +207,8 @@ describe("Test fetchStats", () => { totalRepos: 5, followers: 100, contributions: 61, - stargazers: 400, + // stargazers: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + stargazers: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. prs: 300, issues: 200, }); @@ -214,7 +219,8 @@ describe("Test fetchStats", () => { totalCommits: 1050, totalIssues: 200, totalPRs: 300, - totalStars: 400, + // totalStars: 400, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + totalStars: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. rank, }); }); @@ -230,7 +236,8 @@ describe("Test fetchStats", () => { totalRepos: 5, followers: 100, contributions: 61, - stargazers: 300, + // stargazers: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + stargazers: 200, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. prs: 300, issues: 200, }); @@ -241,7 +248,8 @@ describe("Test fetchStats", () => { totalCommits: 1050, totalIssues: 200, totalPRs: 300, - totalStars: 300, + // totalStars: 300, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. + totalStars: 200, // NOTE: Temporarily disable fetching of multiple pages. Done because of #2130. rank, }); }); From df243efdd54231d597f825d8578f9012aaf9c6e7 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 14:32:01 +0200 Subject: [PATCH 71/88] docs: update readme --- readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index c905155f..90c2723c 100644 --- a/readme.md +++ b/readme.md @@ -406,14 +406,16 @@ By default, GitHub does not lay out the cards side by side. To do that, you can #### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107) +> **NOTE**: If you are on the [hobby (i.e. free)](https://vercel.com/pricing) Vercel plan, please make sure you change the `maxDuration` parameter in the [vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) file from `30` to `10` (see #1416 for more information). +> Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Click on the deploy button to get started! -NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we should be able to handle more than 5k requests and have no issues with downtime :D +**NOTE:** Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58), we should be able to handle more than 5k requests and have fewer issues with downtime :grin:. [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats)
- Guide on setting up Vercel 🔨 + :hammer_and_wrench: Step-by-step guide on setting up your own Vercel instance 1. Go to [vercel.com](https://vercel.com/). 2. Click on `Log in`. From 15533596e6d6702606644e9ec2492e35db13c35b Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 14:40:19 +0200 Subject: [PATCH 72/88] docs: add admonition boxes --- readme.md | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index 90c2723c..7dabb06b 100644 --- a/readme.md +++ b/readme.md @@ -103,9 +103,8 @@ Change the `?username=` value to your GitHub username. [![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) ``` -_Note: Available ranks are S+ (top 1%), S (top 25%), A++ (top 45%), A+ (top 60%), and B+ (everyone). -The values are calculated by using the [cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) using commits, contributions, issues, stars, pull requests, followers, and owned repositories. -The implementation can be investigated at [src/calculateRank.js](./src/calculateRank.js)._ +> **Note** +> Available ranks are S+ (top 1%), S (top 25%), A++ (top 45%), A+ (top 60%), and B+ (everyone). The values are calculated by using the [cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) using commits, contributions, issues, stars, pull requests, followers, and owned repositories. The implementation can be investigated at [src/calculateRank.js](./src/calculateRank.js). ### Hiding individual stats @@ -121,7 +120,8 @@ You can pass a query parameter `&hide=` to hide any specific stats with comma-se You can add the count of all your private contributions to the total commits count by using the query parameter `&count_private=true`. -_Note: If you are deploying this project yourself, the private contributions will be counted by default. If you are using the public Vercel instance, you need to choose to [share your private contributions](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/showing-your-private-contributions-and-achievements-on-your-profile)._ +> **Note** +> If you are deploying this project yourself, the private contributions will be counted by default. If you are using the public Vercel instance, you need to choose to [share your private contributions](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-settings-on-your-profile/showing-your-private-contributions-and-achievements-on-your-profile). > Options: `&count_private=true` @@ -172,7 +172,8 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_. Default: `en`. - `border_radius` - Corner rounding on the card. Default: `4.5`. -> Note: The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. +> **Note** +> The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. ##### Gradient in bg_color @@ -180,6 +181,7 @@ You can provide multiple comma-separated values in the bg_color option to render &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 +> **Note** > Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. #### Stats Card Exclusive Options @@ -197,8 +199,8 @@ You can provide multiple comma-separated values in the bg_color option to render - `text_bold` - Use bold text _(boolean)_. Default: `true`. - `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`. -> Note on `hide_rank`: -> When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. +> **Note** +> Note on `hide_rank`: When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. #### Repo Card Exclusive Options @@ -321,7 +323,8 @@ Change the `?username=` value to your [Wakatime](https://wakatime.com) username. [![willianrod's wakatime stats](https://github-readme-stats.vercel.app/api/wakatime?username=willianrod)](https://github.com/anuraghazra/github-readme-stats) ``` -> Note: Please be aware that we currently only show data from Wakatime profiles that are public. +> **Note**: +> Please be aware that we currently only show data from Wakatime profiles that are public. ### Demo @@ -406,11 +409,13 @@ By default, GitHub does not lay out the cards side by side. To do that, you can #### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107) -> **NOTE**: If you are on the [hobby (i.e. free)](https://vercel.com/pricing) Vercel plan, please make sure you change the `maxDuration` parameter in the [vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) file from `30` to `10` (see #1416 for more information). +> **Warning** +> If you are on the [hobby (i.e. free)](https://vercel.com/pricing) Vercel plan, please make sure you change the `maxDuration` parameter in the [vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) file from `30` to `10` (see #1416 for more information). > Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Click on the deploy button to get started! -**NOTE:** Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58), we should be able to handle more than 5k requests and have fewer issues with downtime :grin:. +> **Note** +> Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58), we should be able to handle more than 5k requests and have fewer issues with downtime :grin:. [![Deploy to Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/anuraghazra/github-readme-stats) From 5c514dbda09999decf13b97b9576087403f216aa Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 14:43:16 +0200 Subject: [PATCH 73/88] docs: improve admonition boxes --- readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 7dabb06b..be15bee7 100644 --- a/readme.md +++ b/readme.md @@ -182,7 +182,7 @@ You can provide multiple comma-separated values in the bg_color option to render &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 > **Note** -> Note on cache: Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. +> Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. #### Stats Card Exclusive Options @@ -200,7 +200,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`. > **Note** -> Note on `hide_rank`: When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. +> When hide_rank=`true`, the minimum card width is 270 px + the title length and padding. #### Repo Card Exclusive Options @@ -216,7 +216,7 @@ You can provide multiple comma-separated values in the bg_color option to render - `exclude_repo` - Exclude specified repositories _(Comma-separated values)_. Default: `[] (blank array)`. - `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`. -> :warning: **Important:** +> **Warning** > Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding) > (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.) You can use > [urlencoder.org](https://www.urlencoder.org/) to help you do this automatically. @@ -263,7 +263,8 @@ Use [show_owner](#customization) variable to include the repo's owner username The top languages card shows a GitHub user's most frequently used top language. -_NOTE: Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It is a new feature of github-readme-stats._ +> **Note** +> Top Languages does not indicate my skill level or anything like that; it's a GitHub metric to determine which languages have the most code on GitHub. It is a new feature of github-readme-stats._ ### Usage From d7451d8288d700d9695689a8d2a3076994e29d22 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 14:53:51 +0200 Subject: [PATCH 74/88] docs: improve caching documentation --- readme.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index be15bee7..9c35b708 100644 --- a/readme.md +++ b/readme.md @@ -172,8 +172,8 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you - `locale` - set the language in the card _(e.g. cn, de, es, etc.)_. Default: `en`. - `border_radius` - Corner rounding on the card. Default: `4.5`. -> **Note** -> The minimum of cache_seconds is currently 4 hours as a temporary fix for PATs exhaustion. +> **Warning** +> We use caching to decrease the load on our servers (see https://github.com/anuraghazra/github-readme-stats/issues/1471#issuecomment-1271551425). Our cards have a default cache of 4 hours (14400 seconds). Also, note that the cache is clamped to a minimum of 4 hours and a maximum of 24 hours. ##### Gradient in bg_color @@ -181,9 +181,6 @@ You can provide multiple comma-separated values in the bg_color option to render &bg_color=DEG,COLOR1,COLOR2,COLOR3...COLOR10 -> **Note** -> Repo cards have a default cache of 4 hours (14400 seconds) if the fork count & star count is less than 1k; otherwise, it is 2 hours (7200 seconds). Also, note that the cache is clamped to a minimum of 2 hours and a maximum of 24 hours. - #### Stats Card Exclusive Options - `hide` - Hides the [specified items](#hiding-individual-stats) from stats _(Comma-separated values)_. Default: `[] (blank array)`. @@ -411,8 +408,8 @@ By default, GitHub does not lay out the cards side by side. To do that, you can #### [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107) > **Warning** -> If you are on the [hobby (i.e. free)](https://vercel.com/pricing) Vercel plan, please make sure you change the `maxDuration` parameter in the [vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) file from `30` to `10` (see #1416 for more information). -> +> If you are on the [hobby (i.e. free)](https://vercel.com/pricing) Vercel plan, please make sure you change the `maxDuration` parameter in the [vercel.json](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json) file from `30` to `10` (see [#1416](https://github.com/anuraghazra/github-readme-stats/issues/1416#issuecomment-950275476) for more information). + Since the GitHub API only allows 5k requests per hour, my `https://github-readme-stats.vercel.app/api` could possibly hit the rate limiter. If you host it on your own Vercel server, then you do not have to worry about anything. Click on the deploy button to get started! > **Note** From 343058cc1551e91684bd88fbe415fe6038b1eeb0 Mon Sep 17 00:00:00 2001 From: Shivam Kotak Date: Fri, 7 Oct 2022 19:52:02 +0530 Subject: [PATCH 75/88] fix: adding doc strings to files in src folder where it was missing (#2129) * fix: adding doc strings to files in src folder where it was missing * refactor: add docstrings * style: run formatter Co-authored-by: rickstaa --- src/calculateRank.js | 20 ++-- src/cards/repo-card.js | 33 +++++-- src/cards/stats-card.js | 8 +- src/cards/top-languages-card.js | 81 ++++++++++------ src/cards/wakatime-card.js | 64 +++++++------ src/common/Card.js | 18 ++-- src/common/I18n.js | 3 + src/common/createProgressNode.js | 12 +++ src/common/utils.js | 133 ++++++++++++++++---------- src/fetchers/repo-fetcher.js | 15 ++- src/fetchers/stats-fetcher.js | 43 ++++++--- src/fetchers/top-languages-fetcher.js | 15 ++- src/fetchers/wakatime-fetcher.js | 6 +- src/getStyles.js | 32 +++++-- src/translations.js | 13 +++ 15 files changed, 322 insertions(+), 174 deletions(-) diff --git a/src/calculateRank.js b/src/calculateRank.js index 6c161f3f..85d96580 100644 --- a/src/calculateRank.js +++ b/src/calculateRank.js @@ -4,9 +4,9 @@ * * @see https://stackoverflow.com/a/5263759/10629172 * - * @param {string} mean - * @param {number} sigma - * @param {number} to + * @param {string} mean The mean of the normal distribution. + * @param {number} sigma The standard deviation of the normal distribution. + * @param {number} to The value to calculate the probability for. * @returns {number} Probability. */ function normalcdf(mean, sigma, to) { @@ -29,13 +29,13 @@ function normalcdf(mean, sigma, to) { /** * Calculates the users rank. * - * @param {number} totalRepos - * @param {number} totalCommits - * @param {number} contributions - * @param {number} followers - * @param {number} prs - * @param {number} issues - * @param {number} stargazers + * @param {number} totalRepos Total number of repos. + * @param {number} totalCommits Total number of commits. + * @param {number} contributions The number of contributions. + * @param {number} followers The number of followers. + * @param {number} prs The number of pull requests. + * @param {number} issues The number of issues. + * @param {number} stargazers The number of stars. * @returns {{level: string, score: number}}} The users rank. */ function calculateRank({ diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 5730ea4f..a306c1d5 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -14,9 +14,11 @@ import { import { repoCardLocales } from "../translations.js"; /** - * @param {string} label - * @param {string} textColor - * @returns {string} + * Retrieves the repository description and wraps it to fit the card width. + * + * @param {string} label The repository description. + * @param {string} textColor The color of the text. + * @returns {string} Wrapped repo description SVG object. */ const getBadgeSVG = (label, textColor) => ` @@ -34,9 +36,11 @@ const getBadgeSVG = (label, textColor) => ` `; /** - * @param {string} langName - * @param {string} langColor - * @returns {string} + * Creates a node to display the primary programming language of the repository. + * + * @param {string} langName Language name. + * @param {string} langColor Language color. + * @returns {string} Language display SVG object. */ const createLanguageNode = (langName, langColor) => { return ` @@ -48,6 +52,15 @@ const createLanguageNode = (langName, langColor) => { }; const ICON_SIZE = 16; + +/** + * Creates an icon with label to display repository stats like forks, stars, etc. + * + * @param {string} icon The icon to display. + * @param {number|string} label The label to display. + * @param {string} testid The testid to assign to the label. + * @returns {string} Icon with label SVG object. + */ const iconWithLabel = (icon, label, testid) => { if (label <= 0) return ""; const iconSvg = ` @@ -67,9 +80,11 @@ const iconWithLabel = (icon, label, testid) => { }; /** - * @param {import('../fetchers/types').RepositoryData} repo - * @param {Partial} options - * @returns {string} + * Renders repository card details. + * + * @param {import('../fetchers/types').RepositoryData} repo Repository data. + * @param {Partial} options Card options. + * @returns {string} Repository card SVG object. */ const renderRepoCard = (repo, options = {}) => { const { diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index f880560e..c9ab66ec 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -63,9 +63,11 @@ const createTextNode = ({ }; /** - * @param {Partial} stats - * @param {Partial} options - * @returns {string} + * Renders the stats card. + * + * @param {Partial} stats The stats data. + * @param {Partial} options The card options. + * @returns {string} The stats card SVG object. */ const renderStatsCard = (stats = {}, options = { hide: [] }) => { const { diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index b837b358..602d1b81 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -23,7 +23,10 @@ const CARD_PADDING = 25; */ /** - * @param {Lang[]} arr + * Retrieves the programming language whose name is the longest. + * + * @param {Lang[]} arr Array of programming languages. + * @returns {Object} Longest programming language object. */ const getLongestLang = (arr) => arr.reduce( @@ -33,12 +36,15 @@ const getLongestLang = (arr) => ); /** - * @param {{ - * width: number, - * color: string, - * name: string, - * progress: string - * }} props + * Creates a node to display usage of a programming language in percentage + * using text and a horizontal progress bar. + * + * @param {object[]} props Function properties. + * @param {number} props.width The card width + * @param {string} props.name Name of the programming language. + * @param {string} props.color Color of the programming language. + * @param {string} props.progress Usage of the programming language in percentage. + * @returns {string} Programming language SVG node. */ const createProgressTextNode = ({ width, color, name, progress }) => { const paddingRight = 95; @@ -60,7 +66,12 @@ const createProgressTextNode = ({ width, color, name, progress }) => { }; /** - * @param {{ lang: Lang, totalSize: number }} props + * Creates a text only node to display usage of a programming language in percentage. + * + * @param {object[]} props Function properties. + * @param {Lang} props.lang Programming language object. + * @param {number} props.totalSize Total size of all languages. + * @returns {string} Compact layout programming language SVG node. */ const createCompactLangNode = ({ lang, totalSize }) => { const percentage = ((lang.size / totalSize) * 100).toFixed(2); @@ -77,7 +88,12 @@ const createCompactLangNode = ({ lang, totalSize }) => { }; /** - * @param {{ langs: Lang[], totalSize: number }} props + * Creates compact layout of text only language nodes. + * + * @param {object[]} props Function properties. + * @param {Lang[]} props.langs Array of programming languages. + * @param {number} props.totalSize Total size of all languages. + * @returns {string} Programming languages SVG node. */ const createLanguageTextNode = ({ langs, totalSize }) => { const longestLang = getLongestLang(langs); @@ -109,10 +125,12 @@ const createLanguageTextNode = ({ langs, totalSize }) => { }; /** - * @param {Lang[]} langs - * @param {number} width - * @param {number} totalLanguageSize - * @returns {string} + * Renders layout to display user's most frequently used programming languages. + * + * @param {Lang[]} langs Array of programming languages. + * @param {number} width Card width. + * @param {number} totalLanguageSize Total size of all languages. + * @returns {string} Normal layout card SVG object. */ const renderNormalLayout = (langs, width, totalLanguageSize) => { return flexLayout({ @@ -130,10 +148,12 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => { }; /** - * @param {Lang[]} langs - * @param {number} width - * @param {number} totalLanguageSize - * @returns {string} + * Renders compact layout to display user's most frequently used programming languages. + * + * @param {Lang[]} langs Array of programming languages. + * @param {number} width Card width. + * @param {number} totalLanguageSize Total size of all languages. + * @returns {string} Compact layout card SVG object. */ const renderCompactLayout = (langs, width, totalLanguageSize) => { const paddingRight = 50; @@ -181,26 +201,31 @@ const renderCompactLayout = (langs, width, totalLanguageSize) => { }; /** - * @param {number} totalLangs - * @returns {number} + * Calculates height for the compact layout. + * + * @param {number} totalLangs Total number of languages. + * @returns {number} Card height. */ const calculateCompactLayoutHeight = (totalLangs) => { return 90 + Math.round(totalLangs / 2) * 25; }; /** - * @param {number} totalLangs - * @returns {number} + * Calculates height for the normal layout. + * + * @param {number} totalLangs Total number of languages. + * @returns {number} Card height. */ const calculateNormalLayoutHeight = (totalLangs) => { return 45 + (totalLangs + 1) * 40; }; /** + * Hides languages and trims the list to show only the top N languages. * - * @param {Record} topLangs - * @param {string[]} hide - * @param {string} langs_count + * @param {Record} topLangs Top languages. + * @param {string[]} hide Languages to hide. + * @param {string} langs_count Number of languages to show. */ const useLanguages = (topLangs, hide, langs_count) => { let langs = Object.values(topLangs); @@ -229,9 +254,11 @@ const useLanguages = (topLangs, hide, langs_count) => { }; /** - * @param {import('../fetchers/types').TopLangData} topLangs - * @param {Partial} options - * @returns {string} + * Renders card to display user's most frequently used programming languages. + * + * @param {import('../fetchers/types').TopLangData} topLangs User's most frequently used programming languages. + * @param {Partial} options Card options. + * @returns {string} Language card SVG object. */ const renderTopLanguages = (topLangs, options = {}) => { const { diff --git a/src/cards/wakatime-card.js b/src/cards/wakatime-card.js index 24571e7f..8b042fd2 100644 --- a/src/cards/wakatime-card.js +++ b/src/cards/wakatime-card.js @@ -23,7 +23,9 @@ const require = createRequire(import.meta.url); const languageColors = require("../common/languageColors.json"); // now works /** - * @param {{color: string, text: string}} param0 + * Creates the no coding activity SVG node. + * + * @param {{color: string, text: string}} The function prop */ const noCodingActivityNode = ({ color, text }) => { return ` @@ -32,13 +34,13 @@ const noCodingActivityNode = ({ color, text }) => { }; /** + * Create compact WakaTime layout. * - * @param {{ - * lang: import("../fetchers/types").WakaTimeLang, - * totalSize: number, - * x: number, - * y: number - * }} props + * @param {Object[]} args The function arguments. + * @param {import("../fetchers/types").WakaTimeLang[]} languages The languages array. + * @param {number} totalSize The total size of the languages. + * @param {number} x The x position of the language node. + * @param {number} y The y position of the language node. */ const createCompactLangNode = ({ lang, totalSize, x, y }) => { const color = languageColors[lang.name] || "#858585"; @@ -54,12 +56,13 @@ const createCompactLangNode = ({ lang, totalSize, x, y }) => { }; /** - * @param {{ - * langs: import("../fetchers/types").WakaTimeLang[], - * totalSize: number, - * x: number, - * y: number - * }} props + * Create WakaTime language text node item. + * + * @param {Object[]} args The function arguments. + * @param {import("../fetchers/types").WakaTimeLang} lang The language object. + * @param {number} totalSize The total size of the languages. + * @param {number} x The x position of the language node. + * @param {number} y The y position of the language node. */ const createLanguageTextNode = ({ langs, totalSize, x, y }) => { return langs.map((lang, index) => { @@ -81,17 +84,16 @@ const createLanguageTextNode = ({ langs, totalSize, x, y }) => { }; /** + * Create WakaTime text item. * - * @param {{ - * id: string; - * label: string; - * value: string; - * index: number; - * percent: number; - * hideProgress: boolean; - * progressBarColor: string; - * progressBarBackgroundColor: string - * }} props + * @param {Object[]} args The function arguments. + * @param {string} id The id of the text node item. + * @param {string} label The label of the text node item. + * @param {string} value The value of the text node item. + * @param {number} index The index of the text node item. + * @param {percent} percent Percentage of the text node item. + * @param {boolean} hideProgress Whether to hide the progress bar. + * @param {string} progressBarBackgroundColor The color of the progress bar background. */ const createTextNode = ({ id, @@ -132,11 +134,13 @@ const createTextNode = ({ }; /** - * @param {import("../fetchers/types").WakaTimeLang[]} languages + * Recalculating percentages so that, compact layout's progress bar does not break when + * hiding languages. + * + * @param {import("../fetchers/types").WakaTimeLang[]} languages The languages array. + * @return {import("../fetchers/types").WakaTimeLang[]} The recalculated languages array. */ const recalculatePercentages = (languages) => { - // recalculating percentages so that, - // compact layout's progress bar does not break when hiding languages const totalSum = languages.reduce( (totalSum, language) => totalSum + language.percent, 0, @@ -148,9 +152,11 @@ const recalculatePercentages = (languages) => { }; /** - * @param {Partial} stats - * @param {Partial} options - * @returns {string} + * Renders WakaTime card. + * + * @param {Partial} stats WakaTime stats. + * @param {Partial} options Card options. + * @returns {string} WakaTime card SVG. */ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => { let { languages } = stats; diff --git a/src/common/Card.js b/src/common/Card.js index 5fd4b9f3..2f1d9c29 100644 --- a/src/common/Card.js +++ b/src/common/Card.js @@ -3,14 +3,16 @@ import { encodeHTML, flexLayout } from "./utils.js"; class Card { /** - * @param {object} args - * @param {number?=} args.width - * @param {number?=} args.height - * @param {number?=} args.border_radius - * @param {string?=} args.customTitle - * @param {string?=} args.defaultTitle - * @param {string?=} args.titlePrefixIcon - * @param {ReturnType?=} args.colors + * Creates a new card instance. + * + * @param {object} args Card arguments. + * @param {number?=} args.width Card width. + * @param {number?=} args.height Card height. + * @param {number?=} args.border_radius Card border radius. + * @param {string?=} args.customTitle Card custom title. + * @param {string?=} args.defaultTitle Card default title. + * @param {string?=} args.titlePrefixIcon Card title prefix icon. + * @returns {Card} Card instance. */ constructor({ width = 100, diff --git a/src/common/I18n.js b/src/common/I18n.js index 7f607cd9..48242af2 100644 --- a/src/common/I18n.js +++ b/src/common/I18n.js @@ -1,3 +1,6 @@ +/** + * I18n translation class. + */ class I18n { constructor({ locale, translations }) { this.locale = locale; diff --git a/src/common/createProgressNode.js b/src/common/createProgressNode.js index 4cc37476..c36818b1 100644 --- a/src/common/createProgressNode.js +++ b/src/common/createProgressNode.js @@ -1,5 +1,17 @@ import { clampValue } from "./utils.js"; +/** + * Create a node to indicate progress in percentage along a horizontal line. + * + * @param {Object} createProgressNodeParams Object that contains the createProgressNode parameters. + * @param {number} createProgressNodeParams.x X-axis position. + * @param {number} createProgressNodeParams.y Y-axis position. + * @param {number} createProgressNodeParams.width Width of progress bar. + * @param {string} createProgressNodeParams.color Progress color. + * @param {string} createProgressNodeParams.progress Progress value. + * @param {string} createProgressNodeParams.progressBarBackgroundColor Progress bar bg color. + * @returns {string} Progress node. + */ const createProgressNode = ({ x, y, diff --git a/src/common/utils.js b/src/common/utils.js index fc462d32..b41ed0cb 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -5,9 +5,11 @@ import wrap from "word-wrap"; import { themes } from "../../themes/index.js"; /** - * @param {string} message - * @param {string} secondaryMessage - * @returns {string} + * Renders error message on the card. + * + * @param {string} message Main error message. + * @param {string} secondaryMessage The secondary error message. + * @returns {string} The SVG markup. */ const renderError = (message, secondaryMessage = "") => { return ` @@ -28,9 +30,12 @@ const renderError = (message, secondaryMessage = "") => { }; /** + * Encode string as HTML. + * * @see https://stackoverflow.com/a/48073476/10629172 - * @param {string} str - * @returns {string} + * + * @param {string} str String to encode. + * @returns {string} Encoded string. */ function encodeHTML(str) { return str @@ -41,7 +46,10 @@ function encodeHTML(str) { } /** - * @param {number} num + * Retrieves num with suffix k(thousands) precise to 1 decimal if greater than 999. + * + * @param {number} num The number to format. + * @returns {string|number} The formatted number. */ function kFormatter(num) { return Math.abs(num) > 999 @@ -50,8 +58,10 @@ function kFormatter(num) { } /** - * @param {string} hexColor - * @returns {boolean} + * Checks if a string is a valid hex color. + * + * @param {string} hexColor String to check. + * @returns {boolean} True if the given string is a valid hex color. */ function isValidHexColor(hexColor) { return new RegExp( @@ -60,8 +70,10 @@ function isValidHexColor(hexColor) { } /** - * @param {string} value - * @returns {boolean | string} + * Returns boolean if value is either "true" or "false" else the value as it is. + * + * @param {string} value The value to parse. + * @returns {boolean | string} The parsed value. */ function parseBoolean(value) { if (value === "true") { @@ -102,16 +114,18 @@ function clampValue(number, min, max) { * Check if the given string is a valid gradient. * * @param {string[]} colors Array of colors. - * returns {boolean} True if the given string is a valid gradient. + * @returns {boolean} True if the given string is a valid gradient. */ function isValidGradient(colors) { return isValidHexColor(colors[1]) && isValidHexColor(colors[2]); } /** - * @param {string} color - * @param {string} fallbackColor - * @returns {string | string[]} + * Retrieves a gradient if color has more than one valid hex codes else a single color. + * + * @param {string} color The color to parse. + * @param {string} fallbackColor The fallback color. + * @returns {string | string[]} The gradient or color. */ function fallbackColor(color, fallbackColor) { let colors = color.split(","); @@ -128,8 +142,11 @@ function fallbackColor(color, fallbackColor) { } /** - * @param {import('axios').AxiosRequestConfig['data']} data - * @param {import('axios').AxiosRequestConfig['headers']} headers + * Send GraphQL request to GitHub API. + * + * @param {import('axios').AxiosRequestConfig['data']} data Request data. + * @param {import('axios').AxiosRequestConfig['headers']} headers Request headers. + * @returns {Promise} Request response. */ function request(data, headers) { // @ts-ignore @@ -142,17 +159,15 @@ function request(data, headers) { } /** - * @param {object} props - * @param {string[]} props.items - * @param {number} props.gap - * @param {number[]?=} props.sizes - * @param {"column" | "row"?=} props.direction + * Auto layout utility, allows us to layout things vertically or horizontally with + * proper gaping. * - * @returns {string[]} - * - * @description - * Auto layout utility, allows us to layout things - * vertically or horizontally with proper gaping + * @param {object} props Function properties. + * @param {string[]} props.items Array of items to layout. + * @param {number} props.gap Gap between items. + * @param {number[]?=} props.sizes Array of sizes for each item. + * @param {"column" | "row"?=} props.direction Direction to layout items. + * @returns {string[]} Array of items with proper layout. */ function flexLayout({ items, gap, direction, sizes = [] }) { let lastSize = 0; @@ -169,18 +184,17 @@ function flexLayout({ items, gap, direction, sizes = [] }) { } /** - * @typedef {object} CardColors - * @prop {string?=} title_color - * @prop {string?=} text_color - * @prop {string?=} icon_color - * @prop {string?=} bg_color - * @prop {string?=} border_color - * @prop {keyof typeof import('../../themes')?=} fallbackTheme - * @prop {keyof typeof import('../../themes')?=} theme - */ -/** - * returns theme based colors with proper overrides and defaults - * @param {CardColors} options + * Returns theme based colors with proper overrides and defaults. + * + * @param {Object[]} args Function arguments. + * @param {string} args.title_color Card title color. + * @param {string} args.text_color Card text color. + * @param {string} args.icon_color Card icon color. + * @param {string} args.bg_color Card background color. + * @param {string} args.border_color Card border color. + * @param {string} args.theme Card theme. + * @param {string} args.fallbackTheme Fallback theme. + * */ function getCardColors({ title_color, @@ -224,10 +238,12 @@ function getCardColors({ } /** - * @param {string} text - * @param {number} width - * @param {number} maxLines - * @returns {string[]} + * Split text over multiple lines based on the card width. + * + * @param {string} text Text to split. + * @param {number} width Card width. + * @param {number} maxLines Maximum number of lines. + * @returns {string[]} Array of lines. */ function wrapTextMultiline(text, width = 59, maxLines = 3) { const fullWidthComma = ","; @@ -274,10 +290,13 @@ const SECONDARY_ERROR_MESSAGES = { USER_NOT_FOUND: "Make sure the provided username is not an organization", }; +/** + * Custom error class to handle custom GRS errors. + */ class CustomError extends Error { /** - * @param {string} message - * @param {string} type + * @param {string} message Error message. + * @param {string} type Error type. */ constructor(message, type) { super(message); @@ -289,6 +308,9 @@ class CustomError extends Error { static USER_NOT_FOUND = "USER_NOT_FOUND"; } +/** + * Missing query parameter class. + */ class MissingParamError extends Error { /** * @param {string[]} missedParams @@ -305,10 +327,12 @@ class MissingParamError extends Error { } /** + * Retrieve text length. + * * @see https://stackoverflow.com/a/48172630/10629172 - * @param {string} str - * @param {number} fontSize - * @returns + * @param {string} str String to measure. + * @param {number} fontSize Font size. + * @returns {number} Text length. */ function measureText(str, fontSize = 10) { // prettier-ignore @@ -348,10 +372,12 @@ function measureText(str, fontSize = 10) { const lowercaseTrim = (name) => name.toLowerCase().trim(); /** - * @template T - * @param {Array} arr - * @param {number} perChunk - * @returns {Array} + * Split array of languages in two columns. + * + * @template T Langauge object. + * @param {Array} arr Array of languages. + * @param {number} perChunk Number of languages per column. + * @returns {Array} Array of languages split in two columns. */ function chunkArray(arr, perChunk) { return arr.reduce((resultArray, item, index) => { @@ -368,9 +394,10 @@ function chunkArray(arr, perChunk) { } /** + * Parse emoji from string. * - * @param {string} str - * @returns {string} + * @param {string} str String to parse emoji from. + * @returns {string} String with emoji parsed. */ function parseEmojis(str) { if (!str) throw new Error("[parseEmoji]: str argument not provided"); diff --git a/src/fetchers/repo-fetcher.js b/src/fetchers/repo-fetcher.js index 37bce0e7..9ff907c8 100644 --- a/src/fetchers/repo-fetcher.js +++ b/src/fetchers/repo-fetcher.js @@ -3,8 +3,11 @@ import { retryer } from "../common/retryer.js"; import { MissingParamError, request } from "../common/utils.js"; /** - * @param {import('Axios').AxiosRequestHeaders} variables - * @param {string} token + * Repo data fetcher. + * + * @param {import('Axios').AxiosRequestHeaders} variables Fetcher variables. + * @param {string} token Github token. + * @returns {Promise} The response. */ const fetcher = (variables, token) => { return request( @@ -51,9 +54,11 @@ const fetcher = (variables, token) => { const urlExample = "/api/pin?username=USERNAME&repo=REPO_NAME"; /** - * @param {string} username - * @param {string} reponame - * @returns {Promise} + * Fetch repository data. + * + * @param {string} username Github username. + * @param {string} reponame Github repository name. + * @returns {Promise} Repository data. */ async function fetchRepo(username, reponame) { if (!username && !reponame) { diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 941c7e14..6a5a6e94 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -14,8 +14,11 @@ import { dotenv.config(); /** - * @param {import('axios').AxiosRequestHeaders} variables - * @param {string} token + * Stats fetcher object. + * + * @param {import('axios').AxiosRequestHeaders} variables Fetcher variables. + * @param {string} token Github token. + * @returns {Promise} Stats fetcher response. */ const fetcher = (variables, token) => { return request( @@ -59,8 +62,11 @@ const fetcher = (variables, token) => { }; /** - * @param {import('axios').AxiosRequestHeaders} variables - * @param {string} token + * Fetch first 100 repositories for a given username. + * + * @param {import('axios').AxiosRequestHeaders} variables Fetcher variables. + * @param {string} token Github token. + * @returns {Promise} Repositories fetcher response. */ const repositoriesFetcher = (variables, token) => { return request( @@ -91,8 +97,15 @@ const repositoriesFetcher = (variables, token) => { ); }; -// https://github.com/anuraghazra/github-readme-stats/issues/92#issuecomment-661026467 -// https://github.com/anuraghazra/github-readme-stats/pull/211/ +/** + * Fetch all the commits for all the repositories of a given username. + * + * @param {*} username Github username. + * @returns {Promise} Total commits. + * + * @description Done like this because the Github API does not provide a way to fetch all the commits. See + * #92#issuecomment-661026467 and #211 for more information. + */ const totalCommitsFetcher = async (username) => { if (!githubUsernameRegex.test(username)) { logger.log("Invalid username"); @@ -127,9 +140,11 @@ const totalCommitsFetcher = async (username) => { }; /** - * Fetch all the stars for all the repositories of a given username - * @param {string} username - * @param {array} repoToHide + * Fetch all the stars for all the repositories of a given username. + * + * @param {string} username Github username. + * @param {array} repoToHide Repositories to hide. + * @returns {Promise} Total stars. */ const totalStarsFetcher = async (username, repoToHide) => { let nodes = []; @@ -165,10 +180,12 @@ const totalStarsFetcher = async (username, repoToHide) => { }; /** - * @param {string} username - * @param {boolean} count_private - * @param {boolean} include_all_commits - * @returns {Promise} + * Fetch stats for a given username. + * + * @param {string} username Github username. + * @param {boolean} count_private Include private contributions. + * @param {boolean} include_all_commits Include all commits. + * @returns {Promise} Stats data. */ async function fetchStats( username, diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 181375d9..76842131 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -6,8 +6,11 @@ import { logger, MissingParamError, request } from "../common/utils.js"; dotenv.config(); /** - * @param {import('Axios').AxiosRequestHeaders} variables - * @param {string} token + * Top languages fetcher object. + * + * @param {import('Axios').AxiosRequestHeaders} variables Fetcher variables. + * @param {string} token Github token. + * @returns {Promise} Languages fetcher response. */ const fetcher = (variables, token) => { return request( @@ -42,9 +45,11 @@ const fetcher = (variables, token) => { }; /** - * @param {string} username - * @param {string[]} exclude_repo - * @returns {Promise} + * Fetch top languages for a given username. + * + * @param {string} username Github username. + * @param {string[]} exclude_repo List of repositories to exclude. + * @returns {Promise} Top languages data. */ async function fetchTopLanguages(username, exclude_repo = []) { if (!username) throw new MissingParamError(["username"]); diff --git a/src/fetchers/wakatime-fetcher.js b/src/fetchers/wakatime-fetcher.js index 97adcdc8..fa1f3d89 100644 --- a/src/fetchers/wakatime-fetcher.js +++ b/src/fetchers/wakatime-fetcher.js @@ -2,8 +2,10 @@ import axios from "axios"; import { MissingParamError } from "../common/utils.js"; /** - * @param {{username: string, api_domain: string, range: string}} props - * @returns {Promise} + * WakaTime data fetcher. + * + * @param {{username: string, api_domain: string, range: string}} props Fetcher props. + * @returns {Promise} WakaTime data response. */ const fetchWakatimeStats = async ({ username, api_domain, range }) => { if (!username) throw new MissingParamError(["username"]); diff --git a/src/getStyles.js b/src/getStyles.js index 3c77787e..79692e85 100644 --- a/src/getStyles.js +++ b/src/getStyles.js @@ -1,6 +1,9 @@ // @ts-check /** - * @param {number} value + * Calculates progress along the boundary of the circle i.e it's circumference. + * + * @param {number} value The rank value to calculate progress for. + * @returns {number} Progress value. */ const calculateCircleProgress = (value) => { const radius = 40; @@ -13,9 +16,11 @@ const calculateCircleProgress = (value) => { }; /** + * Retrieves the animation to display progress along the circumference of circle + * from the beginning to the given value in a clockwise direction. * - * @param {{progress: number}} param0 - * @returns + * @param {{progress: number}} progress The progress value to animate to. + * @returns {string} Progress animation css. */ const getProgressAnimation = ({ progress }) => { return ` @@ -30,6 +35,11 @@ const getProgressAnimation = ({ progress }) => { `; }; +/** + * Retrieves css animations for a card. + * + * @returns {string} Animation css. + */ const getAnimations = () => { return ` /* Animations */ @@ -53,13 +63,15 @@ const getAnimations = () => { }; /** - * @param {{ - * titleColor?: string | string[] - * textColor?: string | string[] - * iconColor?: string | string[] - * show_icons?: boolean; - * progress?: number; - * }} args + * Retrieves CSS styles for a card. + * + * @param {Object[]} colors The colors to use for the card. + * @param {string} colors.titleColor The title color. + * @param {string} colors.textColor The text color. + * @param {string} colors.iconColor The icon color. + * @param {boolean} colors.show_icons Whether to show icons. + * @param {number} colors.progress The progress value to animate to. + * @returns {string} Card CSS styles. */ const getStyles = ({ titleColor, diff --git a/src/translations.js b/src/translations.js index 3f931bc8..b71d37f9 100644 --- a/src/translations.js +++ b/src/translations.js @@ -1,5 +1,12 @@ import { encodeHTML } from "./common/utils.js"; +/** + * Retrieves stat card labels in the available locales. + * + * @param {string} name The name of the locale. + * @param {string} apostrophe Whether to use apostrophe or not. + * @returns {Object} The locales object. + */ const statCardLocales = ({ name, apostrophe }) => { const encodedName = encodeHTML(name); return { @@ -354,6 +361,12 @@ const wakatimeCardLocales = { const availableLocales = Object.keys(repoCardLocales["repocard.archived"]); +/** + * Checks whether the locale is available or not. + * + * @param {string} locale The locale to check. + * @returns {boolean} Boolean specifying whether the locale is available or not. + */ function isLocaleAvailable(locale) { return availableLocales.includes(locale.toLowerCase()); } From 36a8c392d0dddd9771971f0e045f58a69f5107a4 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 17:40:26 +0200 Subject: [PATCH 76/88] fix: improve graphql error handling --- src/common/retryer.js | 2 ++ src/common/utils.js | 14 ++++++++++--- src/fetchers/stats-fetcher.js | 18 +++++++++++++++-- src/fetchers/top-languages-fetcher.js | 29 ++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/common/retryer.js b/src/common/retryer.js index 859e94b0..77f69d3c 100644 --- a/src/common/retryer.js +++ b/src/common/retryer.js @@ -45,6 +45,8 @@ const retryer = async (fetcher, variables, retries = 0) => { retries++; // directly return from the function return retryer(fetcher, variables, retries); + } else { + return err.response; } } }; diff --git a/src/common/utils.js b/src/common/utils.js index b41ed0cb..33b5f03d 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -4,6 +4,9 @@ import toEmoji from "emoji-name-map"; import wrap from "word-wrap"; import { themes } from "../../themes/index.js"; +// Script parameters. +const ERROR_CARD_LENGTH = 576.5; + /** * Renders error message on the card. * @@ -13,13 +16,15 @@ import { themes } from "../../themes/index.js"; */ const renderError = (message, secondaryMessage = "") => { return ` - + - + Something went wrong! file an issue at https://tiny.one/readme-stats ${encodeHTML(message)} @@ -241,7 +246,7 @@ function getCardColors({ * Split text over multiple lines based on the card width. * * @param {string} text Text to split. - * @param {number} width Card width. + * @param {number} width Line width in number of characters. * @param {number} maxLines Maximum number of lines. * @returns {string[]} Array of lines. */ @@ -288,6 +293,7 @@ const SECONDARY_ERROR_MESSAGES = { MAX_RETRY: "Please add an env variable called PAT_1 with your github token in vercel", USER_NOT_FOUND: "Make sure the provided username is not an organization", + GRAPHQL_ERROR: "Please try again later", }; /** @@ -306,6 +312,7 @@ class CustomError extends Error { static MAX_RETRY = "MAX_RETRY"; static USER_NOT_FOUND = "USER_NOT_FOUND"; + static GRAPHQL_ERROR = "GRAPHQL_ERROR"; } /** @@ -427,4 +434,5 @@ export { lowercaseTrim, chunkArray, parseEmojis, + ERROR_CARD_LENGTH, }; diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 6a5a6e94..d592b758 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -9,6 +9,7 @@ import { logger, MissingParamError, request, + wrapTextMultiline, } from "../common/utils.js"; dotenv.config(); @@ -207,11 +208,24 @@ async function fetchStats( let res = await retryer(fetcher, { login: username }); + // Catch GraphQL errors. if (res.data.errors) { logger.error(res.data.errors); + if (res.data.errors[0].type === "NOT_FOUND") { + throw new CustomError( + res.data.errors[0].message || "Could not fetch user.", + CustomError.USER_NOT_FOUND, + ); + } + if (res.data.errors[0].message) { + throw new CustomError( + wrapTextMultiline(res.data.errors[0].message, 90, 1)[0], + res.statusText, + ); + } throw new CustomError( - res.data.errors[0].message || "Could not fetch user", - CustomError.USER_NOT_FOUND, + "Something went while trying to retrieve the stats data using the GraphQL API.", + CustomError.GRAPHQL_ERROR, ); } diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 76842131..ba3fc72c 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -1,7 +1,13 @@ // @ts-check import * as dotenv from "dotenv"; import { retryer } from "../common/retryer.js"; -import { logger, MissingParamError, request } from "../common/utils.js"; +import { + CustomError, + logger, + MissingParamError, + request, + wrapTextMultiline, +} from "../common/utils.js"; dotenv.config(); @@ -61,6 +67,27 @@ async function fetchTopLanguages(username, exclude_repo = []) { throw Error(res.data.errors[0].message || "Could not fetch user"); } + // Catch GraphQL errors. + if (res.data.errors) { + logger.error(res.data.errors); + if (res.data.errors[0].type === "NOT_FOUND") { + throw new CustomError( + res.data.errors[0].message || "Could not fetch user.", + CustomError.USER_NOT_FOUND, + ); + } + if (res.data.errors[0].message) { + throw new CustomError( + wrapTextMultiline(res.data.errors[0].message, 90, 1)[0], + res.statusText, + ); + } + throw new CustomError( + "Something went while trying to retrieve the language data using the GraphQL API.", + CustomError.GRAPHQL_ERROR, + ); + } + let repoNodes = res.data.data.user.repositories.nodes; let repoToHide = {}; From 06e3e052df417a3c0a55d56069533861123c2467 Mon Sep 17 00:00:00 2001 From: Brian Choromanski Date: Fri, 7 Oct 2022 13:20:57 -0400 Subject: [PATCH 77/88] ci: updated issue template (#2127) * Updated issue templates * style: improve template formatting * style: update formatting Co-authored-by: rickstaa --- .github/ISSUE_TEMPLATE/bug_report.md | 43 ---------------- .github/ISSUE_TEMPLATE/bug_report.yml | 58 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 41 --------------- .github/ISSUE_TEMPLATE/feature_request.yml | 26 ++++++++++ 4 files changed, 84 insertions(+), 84 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 5ed7d3c9..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: "" -labels: "" -assignees: "" ---- - - -**Describe the bug** -A clear and concise description of what the bug is. - -**Expected behaviour** -A clear and concise description of what you expected to happen. - -**Screenshots / Live demo link (paste the github-readme-stats link as markdown image)** -If applicable, add screenshots to help explain your problem. - -**Additional context** -Add any other context about the problem here. - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..1a5a9532 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,58 @@ +name: Bug report +description: Create a report to help us improve +labels: + - "bug" +body: + - type: markdown + attributes: + value: | + > **Warning** + > PLEASE FIRST READ THE FAQ [(#1770)](https://github.com/anuraghazra/github-readme-stats/discussions/1770) AND COMMON ERROR CODES [(#1772)](https://github.com/anuraghazra/github-readme-stats/issues/1772)!!! + - type: textarea + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is. + - type: textarea + attributes: + label: Expected behaviour + description: + A clear and concise description of what you expected to happen. + - type: textarea + attributes: + label: Screenshots / Live demo link + description: If applicable, add screenshots to help explain your problem. + placeholder: Paste the github-readme-stats link as markdown image + - type: textarea + attributes: + label: Additional context + description: Add any other context about the problem here. + - type: markdown + attributes: + value: | + ### FAQ + + Below are some questions that are found in the FAQ. The full FAQ can be found in [#1770](https://github.com/anuraghazra/github-readme-stats/discussions/1770). + + #### Q: My card displays an error + + **Ans:** First, check the common error codes (i.e. https://github.com/anuraghazra/github-readme-stats/issues/1772) and existing issues before creating a new one. + + #### Q: How to hide jupyter Notebook? + + **Ans:** `&hide=jupyter%20notebook`. + + #### Q: I could not figure out how to deploy on my own vercel instance + + **Ans:** Please check: + - Docs: https://github.com/anuraghazra/github-readme-stats/#deploy-on-your-own-vercel-instance + - YT tutorial by codeSTACKr: https://www.youtube.com/watch?v=n6d4KHSKqGk&feature=youtu.be&t=107 + + #### Q: Language Card is incorrect + + **Ans:** Please read these issues/comments before opening any issues regarding language card stats: + - https://github.com/anuraghazra/github-readme-stats/issues/136#issuecomment-665164174 + - https://github.com/anuraghazra/github-readme-stats/issues/136#issuecomment-665172181 + + #### Q: How to count private stats? + + **Ans:** We can only count private commits & we cannot access any other private info of any users, so it's impossible. The only way is to deploy on your own instance & use your own PAT (Personal Access Token). diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 73e080a3..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "" -labels: "" -assignees: "" ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. - - diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..20dc6a8b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,26 @@ +name: Feature request +description: Suggest an idea for this project +labels: + - "enhancement" +body: + - type: textarea + attributes: + label: Is your feature request related to a problem? Please describe. + description: | + A clear and concise description of what the problem is. Ex. I'm always + frustrated when [...] + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + - type: textarea + attributes: + label: Describe alternatives you've considered + description: | + A clear and concise description of any alternative solutions or features + you've considered. + - type: textarea + attributes: + label: Additional context + description: + Add any other context or screenshots about the feature request here. From 80e8233c532bdb0ce317d5da94fd55090c827915 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 19:25:36 +0200 Subject: [PATCH 78/88] style: improve templates formatting --- .github/ISSUE_TEMPLATE/bug_report.yml | 6 +++--- .github/ISSUE_TEMPLATE/feature_request.yml | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1a5a9532..8c6ec2aa 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -6,8 +6,7 @@ body: - type: markdown attributes: value: | - > **Warning** - > PLEASE FIRST READ THE FAQ [(#1770)](https://github.com/anuraghazra/github-readme-stats/discussions/1770) AND COMMON ERROR CODES [(#1772)](https://github.com/anuraghazra/github-readme-stats/issues/1772)!!! + :warning: PLEASE FIRST READ THE FAQ [(#1770)](https://github.com/anuraghazra/github-readme-stats/discussions/1770) AND COMMON ERROR CODES [(#1772)](https://github.com/anuraghazra/github-readme-stats/issues/1772)!!! - type: textarea attributes: label: Describe the bug @@ -29,7 +28,8 @@ body: - type: markdown attributes: value: | - ### FAQ + --- + ### FAQ (Snippet) Below are some questions that are found in the FAQ. The full FAQ can be found in [#1770](https://github.com/anuraghazra/github-readme-stats/discussions/1770). diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 20dc6a8b..7b377f9a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -6,9 +6,8 @@ body: - type: textarea attributes: label: Is your feature request related to a problem? Please describe. - description: | - A clear and concise description of what the problem is. Ex. I'm always - frustrated when [...] + description: + A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - type: textarea attributes: label: Describe the solution you'd like @@ -16,9 +15,8 @@ body: - type: textarea attributes: label: Describe alternatives you've considered - description: | - A clear and concise description of any alternative solutions or features - you've considered. + description: + A clear and concise description of any alternative solutions or features you've considered. - type: textarea attributes: label: Additional context From 39535db38c14cc6b50dd747504ac5577abc4ddac Mon Sep 17 00:00:00 2001 From: rickstaa Date: Fri, 7 Oct 2022 19:46:05 +0200 Subject: [PATCH 79/88] style: update formatting --- .github/ISSUE_TEMPLATE/feature_request.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 7b377f9a..b015add9 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -7,7 +7,8 @@ body: attributes: label: Is your feature request related to a problem? Please describe. description: - A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + A clear and concise description of what the problem is. Ex. I'm always + frustrated when [...] - type: textarea attributes: label: Describe the solution you'd like @@ -16,7 +17,8 @@ body: attributes: label: Describe alternatives you've considered description: - A clear and concise description of any alternative solutions or features you've considered. + A clear and concise description of any alternative solutions or features + you've considered. - type: textarea attributes: label: Additional context From bd9865d5a2c9effda41bd5a66b7e01c02af7e2be Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Fri, 7 Oct 2022 20:01:01 +0200 Subject: [PATCH 80/88] test: burst cache in e2e tests (#2154) --- tests/e2e/e2e.test.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index becf5c82..a5ab79e6 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -82,6 +82,7 @@ const REPOSITORY_DATA = { forkCount: 0, starCount: 1, }; +const CACHE_BURST_STRING = `v=${new Date().getTime()}`; describe("Fetch Cards", () => { let VERCEL_PREVIEW_URL; @@ -104,7 +105,7 @@ describe("Fetch Cards", () => { // Get the Vercel preview stats card response. const serverStatsSvg = await axios.get( - `${VERCEL_PREVIEW_URL}/api?username=${USER}`, + `${VERCEL_PREVIEW_URL}/api?username=${USER}&${CACHE_BURST_STRING}`, ); // Check if stats card from deployment matches the stats card from local. @@ -115,8 +116,13 @@ describe("Fetch Cards", () => { expect(VERCEL_PREVIEW_URL).toBeDefined(); // Check if the Vercel preview instance language card function is up and running. + console.log( + `${VERCEL_PREVIEW_URL}/api/top-langs/?username=${USER}&${CACHE_BURST_STRING}`, + ); await expect( - axios.get(`${VERCEL_PREVIEW_URL}/api/top-langs/?username=${USER}`), + axios.get( + `${VERCEL_PREVIEW_URL}/api/top-langs/?username=${USER}&${CACHE_BURST_STRING}`, + ), ).resolves.not.toThrow(); // Get local language card. @@ -124,7 +130,7 @@ describe("Fetch Cards", () => { // Get the Vercel preview language card response. const severLanguageSVG = await axios.get( - `${VERCEL_PREVIEW_URL}/api/top-langs/?username=${USER}`, + `${VERCEL_PREVIEW_URL}/api/top-langs/?username=${USER}&${CACHE_BURST_STRING}`, ); // Check if language card from deployment matches the local language card. @@ -144,7 +150,7 @@ describe("Fetch Cards", () => { // Get the Vercel preview WakaTime card response. const serverWakaTimeSvg = await axios.get( - `${VERCEL_PREVIEW_URL}/api/wakatime?username=${USER}`, + `${VERCEL_PREVIEW_URL}/api/wakatime?username=${USER}&${CACHE_BURST_STRING}`, ); // Check if WakaTime card from deployment matches the local WakaTime card. @@ -156,7 +162,9 @@ describe("Fetch Cards", () => { // Check if the Vercel preview instance Repo function is up and running. await expect( - axios.get(`${VERCEL_PREVIEW_URL}/api/pin/?username=${USER}&repo=${REPO}`), + axios.get( + `${VERCEL_PREVIEW_URL}/api/pin/?username=${USER}&repo=${REPO}&${CACHE_BURST_STRING}`, + ), ).resolves.not.toThrow(); // Get local repo card. @@ -164,7 +172,7 @@ describe("Fetch Cards", () => { // Get the Vercel preview repo card response. const serverRepoSvg = await axios.get( - `${VERCEL_PREVIEW_URL}/api/pin/?username=${USER}&repo=${REPO}`, + `${VERCEL_PREVIEW_URL}/api/pin/?username=${USER}&repo=${REPO}&${CACHE_BURST_STRING}`, ); // Check if Repo card from deployment matches the local Repo card. From 60012707c7eaa51fd0377ce8ae46da6ebad24342 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sat, 8 Oct 2022 15:04:49 +0200 Subject: [PATCH 81/88] test: increase stats card e2e timeout --- tests/e2e/e2e.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index a5ab79e6..ad8086b0 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -110,7 +110,7 @@ describe("Fetch Cards", () => { // Check if stats card from deployment matches the stats card from local. expect(serverStatsSvg.data).toEqual(localStatsCardSVG); - }); + }, 6000); test("retrieve language card", async () => { expect(VERCEL_PREVIEW_URL).toBeDefined(); From fcd05887866797ec01330aa22888066563862c57 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 9 Oct 2022 15:18:11 +0200 Subject: [PATCH 82/88] test: cleanup tests --- tests/e2e/e2e.test.js | 5 ++++- tests/fetchRepo.test.js | 1 + tests/renderStatsCard.test.js | 20 +++++++++--------- tests/renderTopLanguages.test.js | 36 ++++++++++++++++---------------- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/tests/e2e/e2e.test.js b/tests/e2e/e2e.test.js index ad8086b0..aa023cbd 100644 --- a/tests/e2e/e2e.test.js +++ b/tests/e2e/e2e.test.js @@ -11,7 +11,6 @@ import { renderStatsCard } from "../../src/cards/stats-card.js"; import { renderTopLanguages } from "../../src/cards/top-languages-card.js"; import { renderWakatimeCard } from "../../src/cards/wakatime-card.js"; -// Script variables const REPO = "dummy-cra"; const USER = "grsdummy"; const STATS_DATA = { @@ -26,6 +25,7 @@ const STATS_DATA = { score: 51.01013099671447, }, }; + const LANGS_DATA = { TypeScript: { color: "#3178c6", @@ -48,6 +48,7 @@ const LANGS_DATA = { size: 671, }, }; + const WAKATIME_DATA = { human_readable_range: "last week", is_already_updating: false, @@ -64,6 +65,7 @@ const WAKATIME_DATA = { username: "grsdummy", writes_only: false, }; + const REPOSITORY_DATA = { name: "dummy-cra", nameWithOwner: "grsdummy/dummy-cra", @@ -82,6 +84,7 @@ const REPOSITORY_DATA = { forkCount: 0, starCount: 1, }; + const CACHE_BURST_STRING = `v=${new Date().getTime()}`; describe("Fetch Cards", () => { diff --git a/tests/fetchRepo.test.js b/tests/fetchRepo.test.js index 966f2d89..f74a66ff 100644 --- a/tests/fetchRepo.test.js +++ b/tests/fetchRepo.test.js @@ -23,6 +23,7 @@ const data_user = { organization: null, }, }; + const data_org = { data: { user: null, diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js index d3155986..69708137 100644 --- a/tests/renderStatsCard.test.js +++ b/tests/renderStatsCard.test.js @@ -10,17 +10,17 @@ import "@testing-library/jest-dom"; import { themes } from "../themes/index.js"; -describe("Test renderStatsCard", () => { - const stats = { - name: "Anurag Hazra", - totalStars: 100, - totalCommits: 200, - totalIssues: 300, - totalPRs: 400, - contributedTo: 500, - rank: { level: "A+", score: 40 }, - }; +const stats = { + name: "Anurag Hazra", + totalStars: 100, + totalCommits: 200, + totalIssues: 300, + totalPRs: 400, + contributedTo: 500, + rank: { level: "A+", score: 40 }, +}; +describe("Test renderStatsCard", () => { it("should render correctly", () => { document.body.innerHTML = renderStatsCard(stats); diff --git a/tests/renderTopLanguages.test.js b/tests/renderTopLanguages.test.js index 8c6bcbef..8ae4bbd0 100644 --- a/tests/renderTopLanguages.test.js +++ b/tests/renderTopLanguages.test.js @@ -9,25 +9,25 @@ import "@testing-library/jest-dom"; import { themes } from "../themes/index.js"; -describe("Test renderTopLanguages", () => { - const langs = { - HTML: { - color: "#0f0", - name: "HTML", - size: 200, - }, - javascript: { - color: "#0ff", - name: "javascript", - size: 200, - }, - css: { - color: "#ff0", - name: "css", - size: 100, - }, - }; +const langs = { + HTML: { + color: "#0f0", + name: "HTML", + size: 200, + }, + javascript: { + color: "#0ff", + name: "javascript", + size: 200, + }, + css: { + color: "#ff0", + name: "css", + size: 100, + }, +}; +describe("Test renderTopLanguages", () => { it("should render correctly", () => { document.body.innerHTML = renderTopLanguages(langs); From f77e34e383ce164f39c679e988eb974f2289d435 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 9 Oct 2022 17:31:24 +0200 Subject: [PATCH 83/88] ci: add question template --- .github/ISSUE_TEMPLATE/question.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/question.yml diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 00000000..5199511f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,9 @@ +name: Question +description: Ask a question +body: + - type: markdown + attributes: + value: | + We use the Issues tab for bug reports and feature requests. If you have a question, please start a discussion in the Discussions tab. + + [![Start New Discussion](https://dabuttonfactory.com/button.png?t=Start+New+Discussion&f=Roboto-Bold&ts=26&tc=fff&hp=45&vp=20&c=11&bgt=unicolored&bgc=238636)](https://github.com/anuraghazra/github-readme-stats/discussions/new) From 0a394a625b3244852c4975350d0861d3fc3dab4a Mon Sep 17 00:00:00 2001 From: rickstaa Date: Sun, 9 Oct 2022 17:46:11 +0200 Subject: [PATCH 84/88] ci: add issues template config and remove question template --- .github/ISSUE_TEMPLATE/config.yml | 5 +++++ .github/ISSUE_TEMPLATE/question.yml | 9 --------- 2 files changed, 5 insertions(+), 9 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/question.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..f5830f64 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Question + url: https://github.com/anuraghazra/github-readme-stats/discussions + about: Please ask and answer questions here. diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml deleted file mode 100644 index 5199511f..00000000 --- a/.github/ISSUE_TEMPLATE/question.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: Question -description: Ask a question -body: - - type: markdown - attributes: - value: | - We use the Issues tab for bug reports and feature requests. If you have a question, please start a discussion in the Discussions tab. - - [![Start New Discussion](https://dabuttonfactory.com/button.png?t=Start+New+Discussion&f=Roboto-Bold&ts=26&tc=fff&hp=45&vp=20&c=11&bgt=unicolored&bgc=238636)](https://github.com/anuraghazra/github-readme-stats/discussions/new) From 4df8094e5266f28f7367552980f4e00b0c9421a9 Mon Sep 17 00:00:00 2001 From: Rick Staa Date: Sun, 9 Oct 2022 20:23:31 +0200 Subject: [PATCH 85/88] fix: prevent errors from being cached (#2160) --- api/index.js | 1 + api/pin.js | 1 + api/top-langs.js | 1 + api/wakatime.js | 1 + 4 files changed, 4 insertions(+) diff --git a/api/index.js b/api/index.js index 10dd4847..3b5e949d 100644 --- a/api/index.js +++ b/api/index.js @@ -89,6 +89,7 @@ export default async (req, res) => { }), ); } catch (err) { + res.setHeader("Cache-Control", `no-store`); // Don't cache error responses. return res.send(renderError(err.message, err.secondaryMessage)); } }; diff --git a/api/pin.js b/api/pin.js index e83750a5..84ca4e64 100644 --- a/api/pin.js +++ b/api/pin.js @@ -75,6 +75,7 @@ export default async (req, res) => { }), ); } catch (err) { + res.setHeader("Cache-Control", `no-store`); // Don't cache error responses. return res.send(renderError(err.message, err.secondaryMessage)); } }; diff --git a/api/top-langs.js b/api/top-langs.js index aa29b234..a6a9d286 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -76,6 +76,7 @@ export default async (req, res) => { }), ); } catch (err) { + res.setHeader("Cache-Control", `no-store`); // Don't cache error responses. return res.send(renderError(err.message, err.secondaryMessage)); } }; diff --git a/api/wakatime.js b/api/wakatime.js index bbfb2f2e..60d22b5c 100644 --- a/api/wakatime.js +++ b/api/wakatime.js @@ -78,6 +78,7 @@ export default async (req, res) => { }), ); } catch (err) { + res.setHeader("Cache-Control", `no-store`); // Don't cache error responses. return res.send(renderError(err.message, err.secondaryMessage)); } }; From f0f92c2635952be5820dae162bbdcf810b068c61 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Mon, 10 Oct 2022 12:48:26 +0200 Subject: [PATCH 86/88] test: add cache on error test --- tests/api.test.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/api.test.js b/tests/api.test.js index a6bb0920..c05f25a6 100644 --- a/tests/api.test.js +++ b/tests/api.test.js @@ -174,6 +174,16 @@ describe("Test /api/", () => { ]); }); + it("should not store cache when error", async () => { + const { req, res } = faker({}, error); + await api(req, res); + + expect(res.setHeader.mock.calls).toEqual([ + ["Content-Type", "image/svg+xml"], + ["Cache-Control", `no-store`], + ]); + }); + it("should set proper cache with clamped values", async () => { { let { req, res } = faker({ cache_seconds: 200000 }, data); From c4bfacb9e0cf4df41bf01b75be72cfcd7ea207f7 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Mon, 10 Oct 2022 13:48:35 +0200 Subject: [PATCH 87/88] docs: add fork update guide --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index 9c35b708..aeaadf52 100644 --- a/readme.md +++ b/readme.md @@ -92,6 +92,7 @@ Visit and make a small donation to hel - [Language Card Exclusive Options](#language-card-exclusive-options) - [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options) - [Deploy Yourself](#deploy-on-your-own-vercel-instance) + - [Keep your fork up to date](#keep-your-fork-up-to-date) # GitHub Stats Card @@ -440,6 +441,10 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
+#### Keep your fork up to date + +You can keep your fork, and thus your private Vercel instance up to date with the upstream using GitHubs' [Sync Fork button](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork). You can also use the [pull](https://github.com/wei/pull) package created by [@wei](https://github.com/wei) to automate this process. + ## :sparkling_heart: Support the project I open-source almost everything I can and try to reply to everyone needing help using these projects. Obviously, From 166972d7e4f12ab17ee7aa2b2000d784444bd9fd Mon Sep 17 00:00:00 2001 From: rickstaa Date: Mon, 10 Oct 2022 13:49:48 +0200 Subject: [PATCH 88/88] docs: improve syntax --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index aeaadf52..9c773ff8 100644 --- a/readme.md +++ b/readme.md @@ -441,7 +441,7 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme -#### Keep your fork up to date +### Keep your fork up to date You can keep your fork, and thus your private Vercel instance up to date with the upstream using GitHubs' [Sync Fork button](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork). You can also use the [pull](https://github.com/wei/pull) package created by [@wei](https://github.com/wei) to automate this process.