mirror of
https://github.com/Aviortheking/codestats-readme.git
synced 2025-06-07 16:29:57 +00:00
feat: added isTemplate badge & refactored console.logs (#146)
* feat: template option added husky added for same commit disable console in test \ logger utils added env checked for log modified git ignore * changed are done as per the suggesstion * changed style and font * text color dynamic * fix border and using .bagde class as common * simplified the badge svg code through a common method * chore: updated css & fixed tests Co-authored-by: anuraghazra <hazru.anurag@gmail.com>
This commit is contained in:
parent
03f55e809e
commit
5ed75e11be
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,6 @@
|
|||||||
.env
|
.env
|
||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
*.lock
|
||||||
|
.vscode/
|
||||||
coverage
|
coverage
|
||||||
|
@ -4,6 +4,7 @@ const {
|
|||||||
parseBoolean,
|
parseBoolean,
|
||||||
clampValue,
|
clampValue,
|
||||||
CONSTANTS,
|
CONSTANTS,
|
||||||
|
logger,
|
||||||
} = require("../src/utils");
|
} = require("../src/utils");
|
||||||
const fetchRepo = require("../src/fetchRepo");
|
const fetchRepo = require("../src/fetchRepo");
|
||||||
const renderRepoCard = require("../src/renderRepoCard");
|
const renderRepoCard = require("../src/renderRepoCard");
|
||||||
@ -28,7 +29,7 @@ module.exports = async (req, res) => {
|
|||||||
try {
|
try {
|
||||||
repoData = await fetchRepo(username, repo);
|
repoData = await fetchRepo(username, repo);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
logger.error(err);
|
||||||
return res.send(renderError(err.message));
|
return res.send(renderError(err.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ module.exports = async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.setHeader("Cache-Control", `public, max-age=${cacheSeconds}`);
|
res.setHeader("Cache-Control", `public, max-age=${cacheSeconds}`);
|
||||||
|
|
||||||
res.send(
|
res.send(
|
||||||
renderRepoCard(repoData, {
|
renderRepoCard(repoData, {
|
||||||
title_color,
|
title_color,
|
||||||
|
@ -15,9 +15,15 @@
|
|||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"axios-mock-adapter": "^1.18.1",
|
"axios-mock-adapter": "^1.18.1",
|
||||||
"css-to-object": "^1.1.0",
|
"css-to-object": "^1.1.0",
|
||||||
|
"husky": "^4.2.5",
|
||||||
"jest": "^26.1.0"
|
"jest": "^26.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^8.2.0"
|
"dotenv": "^8.2.0"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "npm test"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ const fetcher = (variables, token) => {
|
|||||||
nameWithOwner
|
nameWithOwner
|
||||||
isPrivate
|
isPrivate
|
||||||
isArchived
|
isArchived
|
||||||
|
isTemplate
|
||||||
stargazers {
|
stargazers {
|
||||||
totalCount
|
totalCount
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { request } = require("./utils");
|
const { request, logger } = require("./utils");
|
||||||
const retryer = require("./retryer");
|
const retryer = require("./retryer");
|
||||||
const calculateRank = require("./calculateRank");
|
const calculateRank = require("./calculateRank");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
@ -61,7 +61,7 @@ async function fetchStats(username) {
|
|||||||
let res = await retryer(fetcher, { login: username });
|
let res = await retryer(fetcher, { login: username });
|
||||||
|
|
||||||
if (res.data.errors) {
|
if (res.data.errors) {
|
||||||
console.log(res.data.errors);
|
logger.error(res.data.errors);
|
||||||
throw Error(res.data.errors[0].message || "Could not fetch user");
|
throw Error(res.data.errors[0].message || "Could not fetch user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const { request } = require("./utils");
|
const { request, logger } = require("./utils");
|
||||||
const retryer = require("./retryer");
|
const retryer = require("./retryer");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ async function fetchTopLanguages(username) {
|
|||||||
let res = await retryer(fetcher, { login: username });
|
let res = await retryer(fetcher, { login: username });
|
||||||
|
|
||||||
if (res.data.errors) {
|
if (res.data.errors) {
|
||||||
console.log(res.data.errors);
|
logger.error(res.data.errors);
|
||||||
throw Error(res.data.errors[0].message || "Could not fetch user");
|
throw Error(res.data.errors[0].message || "Could not fetch user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
primaryLanguage,
|
primaryLanguage,
|
||||||
stargazers,
|
stargazers,
|
||||||
isArchived,
|
isArchived,
|
||||||
|
isTemplate,
|
||||||
forkCount,
|
forkCount,
|
||||||
} = repo;
|
} = repo;
|
||||||
const {
|
const {
|
||||||
@ -49,14 +50,20 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
const totalStars = kFormatter(stargazers.totalCount);
|
const totalStars = kFormatter(stargazers.totalCount);
|
||||||
const totalForks = kFormatter(forkCount);
|
const totalForks = kFormatter(forkCount);
|
||||||
|
|
||||||
const archiveBadge = isArchived
|
const getBadgeSVG = (label) => `
|
||||||
? `
|
<g data-testid="badge" class="badge" transform="translate(320, 38)">
|
||||||
<g data-testid="archive-badge" class="archive-badge" transform="translate(320, 38)">
|
|
||||||
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
<rect stroke="${textColor}" stroke-width="1" width="70" height="20" x="-12" y="-14" ry="10" rx="10"></rect>
|
||||||
<text fill="${textColor}">Archived</text>
|
<text
|
||||||
|
x="23" y="-5"
|
||||||
|
alignment-baseline="central"
|
||||||
|
dominant-baseline="central"
|
||||||
|
text-anchor="middle"
|
||||||
|
fill="${textColor}"
|
||||||
|
>
|
||||||
|
${label}
|
||||||
|
</text>
|
||||||
</g>
|
</g>
|
||||||
`
|
`;
|
||||||
: "";
|
|
||||||
|
|
||||||
const svgLanguage = `
|
const svgLanguage = `
|
||||||
<g transform="translate(30, 100)">
|
<g transform="translate(30, 100)">
|
||||||
@ -90,17 +97,25 @@ const renderRepoCard = (repo, options = {}) => {
|
|||||||
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||||
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
.gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||||
.icon { fill: ${iconColor} }
|
.icon { fill: ${iconColor} }
|
||||||
.archive-badge { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; }
|
.badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; }
|
||||||
.archive-badge rect { opacity: 0.2 }
|
.badge rect { opacity: 0.2 }
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<rect data-testid="card-bg" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
|
<rect data-testid="card-bg" x="0.5" y="0.5" width="399" height="99%" rx="4.5" fill="${bgColor}" stroke="#E4E2E2"/>
|
||||||
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
<svg class="icon" x="25" y="25" viewBox="0 0 16 16" version="1.1" width="16" height="16">
|
||||||
${icons.contribs}
|
${icons.contribs}
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
${archiveBadge}
|
|
||||||
|
|
||||||
<text x="50" y="38" class="header">${header}</text>
|
<text x="50" y="38" class="header">${header}</text>
|
||||||
|
|
||||||
|
${
|
||||||
|
isTemplate
|
||||||
|
? getBadgeSVG("Template")
|
||||||
|
: isArchived
|
||||||
|
? getBadgeSVG("Archived")
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
|
||||||
<text class="description" x="25" y="70">${encodeHTML(desc)}</text>
|
<text class="description" x="25" y="70">${encodeHTML(desc)}</text>
|
||||||
|
|
||||||
${svgLanguage}
|
${svgLanguage}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
const { logger } = require("./utils");
|
||||||
|
|
||||||
const retryer = async (fetcher, variables, retries = 0) => {
|
const retryer = async (fetcher, variables, retries = 0) => {
|
||||||
if (retries > 7) {
|
if (retries > 7) {
|
||||||
throw new Error("Maximum retries exceeded");
|
throw new Error("Maximum retries exceeded");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
console.log(`Trying PAT_${retries + 1}`);
|
logger.log(`Trying PAT_${retries + 1}`);
|
||||||
|
|
||||||
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
|
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
|
||||||
let response = await fetcher(
|
let response = await fetcher(
|
||||||
@ -18,7 +20,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
|||||||
// if rate limit is hit increase the RETRIES and recursively call the retryer
|
// if rate limit is hit increase the RETRIES and recursively call the retryer
|
||||||
// with username, and current RETRIES
|
// with username, and current RETRIES
|
||||||
if (isRateExceeded) {
|
if (isRateExceeded) {
|
||||||
console.log(`PAT_${retries + 1} Failed`);
|
logger.log(`PAT_${retries + 1} Failed`);
|
||||||
retries++;
|
retries++;
|
||||||
// directly return from the function
|
// directly return from the function
|
||||||
return retryer(fetcher, variables, retries);
|
return retryer(fetcher, variables, retries);
|
||||||
@ -32,7 +34,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
|||||||
const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";
|
const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";
|
||||||
|
|
||||||
if (isBadCredential) {
|
if (isBadCredential) {
|
||||||
console.log(`PAT_${retries + 1} Failed`);
|
logger.log(`PAT_${retries + 1} Failed`);
|
||||||
retries++;
|
retries++;
|
||||||
// directly return from the function
|
// directly return from the function
|
||||||
return retryer(fetcher, variables, retries);
|
return retryer(fetcher, variables, retries);
|
||||||
|
@ -116,6 +116,10 @@ function getCardColors({
|
|||||||
return { titleColor, iconColor, textColor, bgColor };
|
return { titleColor, iconColor, textColor, bgColor };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn = () => {};
|
||||||
|
// return console instance based on the environment
|
||||||
|
const logger = process.env.NODE_ENV !== "test" ? console : { log: fn, error: fn };
|
||||||
|
|
||||||
const CONSTANTS = {
|
const CONSTANTS = {
|
||||||
THIRTY_MINUTES: 1800,
|
THIRTY_MINUTES: 1800,
|
||||||
TWO_HOURS: 7200,
|
TWO_HOURS: 7200,
|
||||||
@ -133,5 +137,6 @@ module.exports = {
|
|||||||
FlexLayout,
|
FlexLayout,
|
||||||
getCardColors,
|
getCardColors,
|
||||||
clampValue,
|
clampValue,
|
||||||
|
logger,
|
||||||
CONSTANTS,
|
CONSTANTS,
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ const data_repo = {
|
|||||||
name: "TypeScript",
|
name: "TypeScript",
|
||||||
},
|
},
|
||||||
forkCount: 100,
|
forkCount: 100,
|
||||||
|
isTemplate: false
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,17 +217,6 @@ describe("Test renderRepoCard", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should render archive badge if repo is archived", () => {
|
|
||||||
document.body.innerHTML = renderRepoCard({
|
|
||||||
...data_repo.repository,
|
|
||||||
isArchived: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(queryByTestId(document.body, "archive-badge")).toHaveTextContent(
|
|
||||||
"Archived"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should not render star count or fork count if either of the are zero", () => {
|
it("should not render star count or fork count if either of the are zero", () => {
|
||||||
document.body.innerHTML = renderRepoCard({
|
document.body.innerHTML = renderRepoCard({
|
||||||
...data_repo.repository,
|
...data_repo.repository,
|
||||||
@ -235,7 +224,7 @@ describe("Test renderRepoCard", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
||||||
expect(queryByTestId(document.body, "forkcount")).toBeDefined();
|
expect(queryByTestId(document.body, "forkcount")).toBeInTheDocument();
|
||||||
|
|
||||||
document.body.innerHTML = renderRepoCard({
|
document.body.innerHTML = renderRepoCard({
|
||||||
...data_repo.repository,
|
...data_repo.repository,
|
||||||
@ -243,7 +232,7 @@ describe("Test renderRepoCard", () => {
|
|||||||
forkCount: 0,
|
forkCount: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(queryByTestId(document.body, "stargazers")).toBeDefined();
|
expect(queryByTestId(document.body, "stargazers")).toBeInTheDocument();
|
||||||
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
||||||
|
|
||||||
document.body.innerHTML = renderRepoCard({
|
document.body.innerHTML = renderRepoCard({
|
||||||
@ -255,4 +244,26 @@ describe("Test renderRepoCard", () => {
|
|||||||
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
expect(queryByTestId(document.body, "stargazers")).toBeNull();
|
||||||
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
expect(queryByTestId(document.body, "forkcount")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should render badges", () => {
|
||||||
|
document.body.innerHTML = renderRepoCard({
|
||||||
|
...data_repo.repository,
|
||||||
|
isArchived: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Archived");
|
||||||
|
|
||||||
|
document.body.innerHTML = renderRepoCard({
|
||||||
|
...data_repo.repository,
|
||||||
|
isTemplate: true,
|
||||||
|
});
|
||||||
|
expect(queryByTestId(document.body, "badge")).toHaveTextContent("Template");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not render template", () => {
|
||||||
|
document.body.innerHTML = renderRepoCard({
|
||||||
|
...data_repo.repository,
|
||||||
|
});
|
||||||
|
expect(queryByTestId(document.body, "badge")).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
require("@testing-library/jest-dom");
|
require("@testing-library/jest-dom");
|
||||||
const retryer = require("../src/retryer");
|
const retryer = require("../src/retryer");
|
||||||
|
const { logger } = require("../src/utils");
|
||||||
|
|
||||||
const fetcher = jest.fn((variables, token) => {
|
const fetcher = jest.fn((variables, token) => {
|
||||||
console.log(variables, token);
|
logger.log(variables, token);
|
||||||
return new Promise((res, rej) => res({ data: "ok" }));
|
return new Promise((res, rej) => res({ data: "ok" }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user