diff --git a/src/contribution.ts b/src/contribution.ts index db74a72..469ebc0 100644 --- a/src/contribution.ts +++ b/src/contribution.ts @@ -1,41 +1,41 @@ -import type { IncomingMessage } from "node:http"; -import { get } from "node:https"; +import type { IncomingMessage } from 'node:http'; +import { get } from 'node:https'; import { - GitHubStats, - parseContributions, - parseGitHubStats, -} from "./transformers"; + GitHubStats, + parseContributions, + parseGitHubStats, +} from './transformers'; interface Options { - onSuccess?: (stats: GitHubStats) => unknown; - onFailure?: (error: IncomingMessage) => unknown; + onSuccess?: (stats: GitHubStats) => unknown; + onFailure?: (error: IncomingMessage) => unknown; } const fetchStats = ( - username: string, - options?: Options, + username: string, + options?: Options, ): Promise => - new Promise((resolve, reject) => { - get(`https://github.com/users/${username}/contributions`, (response) => { - let body = ""; - response.setEncoding("utf8"); - response.on("data", (chunk) => { - body += chunk; - }); - response.on("end", () => { - if (response.statusCode === 404) { - if (options?.onFailure) return options.onFailure(response); - return reject(response); - } + new Promise((resolve, reject) => { + get(`https://github.com/users/${username}/contributions`, (response) => { + let body = ''; + response.setEncoding('utf8'); + response.on('data', (chunk) => { + body += chunk; + }); + response.on('end', () => { + if (response.statusCode === 404) { + if (options?.onFailure) return options.onFailure(response); + return reject(response); + } - const contributions = parseContributions(body); - const gitHubStats = parseGitHubStats(contributions); + const contributions = parseContributions(body); + const gitHubStats = parseGitHubStats(contributions); - if (options?.onSuccess) return options.onSuccess(gitHubStats); - return resolve(gitHubStats); - }); - }); - }); + if (options?.onSuccess) return options.onSuccess(gitHubStats); + return resolve(gitHubStats); + }); + }); + }); export { GitHubStats, fetchStats }; diff --git a/src/transformers.ts b/src/transformers.ts index 361b0cb..5b921ca 100644 --- a/src/transformers.ts +++ b/src/transformers.ts @@ -1,67 +1,67 @@ export interface GitHubStats { - streak: { - best: number; - current: number; - isAtRisk: boolean; - previous: number; - }; - contributions: { - best: number; - total: number; - current: number; - }; + streak: { + best: number; + current: number; + isAtRisk: boolean; + previous: number; + }; + contributions: { + best: number; + total: number; + current: number; + }; } interface ParsedContributions { - [key: string]: number; + [key: string]: number; } export const parseContributions = (body: string): ParsedContributions => { - const bodyMatches = body.matchAll( - /data-date="(\d{4}-\d{2}-\d{2}).*>(\d+|No) contribution/g, - ); - const contributions: ParsedContributions = {}; - for (const [match, date, contribution] of bodyMatches) { - contributions[date] = - contribution === "No" ? 0 : Number.parseInt(contribution); - } - const sortedContributionData = Object.fromEntries( - Object.entries(contributions).sort( - ([a], [b]) => +new Date(a) - +new Date(b), - ), - ); - return sortedContributionData; + const bodyMatches = body.matchAll( + /data-date="(\d{4}-\d{2}-\d{2}).*>(\d+|No) contribution/g, + ); + const contributions: ParsedContributions = {}; + for (const [match, date, contribution] of bodyMatches) { + contributions[date] = + contribution === 'No' ? 0 : Number.parseInt(contribution); + } + const sortedContributionData = Object.fromEntries( + Object.entries(contributions).sort( + ([a], [b]) => +new Date(a) - +new Date(b), + ), + ); + return sortedContributionData; }; export const parseGitHubStats = ( - parsedContributions: ParsedContributions, + parsedContributions: ParsedContributions, ): GitHubStats => { - const stats = { - streak: { best: 0, current: 0, isAtRisk: false, previous: 0 }, - contributions: { best: 0, total: 0, current: 0 }, - }; - let previousStreak = 0; + const stats = { + streak: { best: 0, current: 0, isAtRisk: false, previous: 0 }, + contributions: { best: 0, total: 0, current: 0 }, + }; + let previousStreak = 0; - for (const [date, contribution] of Object.entries(parsedContributions)) { - // Contributions - stats.contributions.total += contribution; - stats.contributions.current = contribution; - if (contribution > stats.contributions.best) { - stats.contributions.best = contribution; - } + for (const [date, contribution] of Object.entries(parsedContributions)) { + // Contributions + stats.contributions.total += contribution; + stats.contributions.current = contribution; + if (contribution > stats.contributions.best) { + stats.contributions.best = contribution; + } - // Streak - stats.streak.current = contribution > 0 ? stats.streak.current + 1 : 0; - if (stats.streak.current > stats.streak.best) { - stats.streak.best = stats.streak.current; - } - stats.streak.isAtRisk = stats.streak.current === 0 && previousStreak > 0; - if (stats.streak.isAtRisk) { - stats.streak.previous = previousStreak; - } + // Streak + stats.streak.current = contribution > 0 ? stats.streak.current + 1 : 0; + if (stats.streak.current > stats.streak.best) { + stats.streak.best = stats.streak.current; + } + stats.streak.isAtRisk = stats.streak.current === 0 && previousStreak > 0; + if (stats.streak.isAtRisk) { + stats.streak.previous = previousStreak; + } - previousStreak = stats.streak.current; - } + previousStreak = stats.streak.current; + } - return stats; + return stats; };