diff --git a/dist/cli.js b/dist/cli.js index e75332b..ff795c0 100755 --- a/dist/cli.js +++ b/dist/cli.js @@ -1,5 +1,6 @@ #!/usr/bin/env node "use strict"; +/* eslint-disable no-case-declarations */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -46,8 +47,20 @@ var figlet_1 = __importDefault(require("figlet")); var process_1 = __importDefault(require("process")); var node_fetch_1 = __importDefault(require("node-fetch")); var node_emoji_1 = __importDefault(require("node-emoji")); +var ActivityTypes = [ + "PushEvent", + "WatchEvent", + "CreateEvent", + "DeleteEvent", + "ForkEvent", + "PullRequestEvent", + "PullRequestReviewCommentEvent", + "IssuesEvent", + "IssueCommentEvent", + "PublicEvent", +]; (function () { return __awaiter(void 0, void 0, void 0, function () { - var username, baseUrl, res, user; + var username, baseUrl, res, failure, user, res2, repos, languages, res3, activities; return __generator(this, function (_a) { switch (_a.label) { case 0: @@ -71,16 +84,13 @@ var node_emoji_1 = __importDefault(require("node-emoji")); return [4 /*yield*/, node_fetch_1.default(baseUrl + "/users/" + username)]; case 1: res = _a.sent(); - if (res.status === 404) { - console.log(chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Shoot! that username does not exist on github")); - return [2 /*return*/]; - } - if (res.status !== 200) { - console.log(chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Error: " + res.statusText)); + return [4 /*yield*/, checkResponse(res, chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Shoot! that username does not exist on github"))]; + case 2: + failure = _a.sent(); + if (failure) return [2 /*return*/]; - } return [4 /*yield*/, res.json()]; - case 2: + case 3: user = _a.sent(); console.log(node_emoji_1.default.get("star") + " " + chalk_1.default.bold.rgb(255, 22, 84)(user.login) + " " + chalk_1.default.rgb(255, 22, 84)(user.name)); console.log(user.html_url); @@ -93,19 +103,119 @@ var node_emoji_1 = __importDefault(require("node-emoji")); printPair("Repos", user.public_repos.toString()); printPair("Followers", user.followers.toString()); printPair("Following", user.following.toString()); + return [4 /*yield*/, node_fetch_1.default(baseUrl + "/users/" + username + "/repos")]; + case 4: + res2 = _a.sent(); + return [4 /*yield*/, checkResponse(res2, chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Shoot! repos not found"))]; + case 5: + failure = _a.sent(); + if (failure) + return [2 /*return*/]; + return [4 /*yield*/, res2.json()]; + case 6: + repos = _a.sent(); + languages = repos.map(function (repo) { return repo.language; }); + languages = languages.filter(function (a, b) { return languages.indexOf(a) === b; }); + console.log(); + console.log(node_emoji_1.default.get("rainbow") + chalk_1.default.bold.rgb(255, 22, 84)(" Languages")); + console.log(languages.join(" ")); + return [4 /*yield*/, node_fetch_1.default(baseUrl + "/users/" + username + "/events")]; + case 7: + res3 = _a.sent(); + return [4 /*yield*/, checkResponse(res2, chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Shoot! activity not found"))]; + case 8: + failure = _a.sent(); + if (failure) + return [2 /*return*/]; + return [4 /*yield*/, res3.json()]; + case 9: + activities = _a.sent(); + console.log(); + console.log(node_emoji_1.default.get("rocket") + chalk_1.default.bold.rgb(255, 22, 84)(" Activity")); + activities + .filter(function (activity) { return ActivityTypes.includes(activity.type); }) + .slice(0, 5) + .map(function (activity) { return console.log(parseActivity(activity)); }); return [2 /*return*/]; } }); }); })(); function printPair(left, right) { if (right !== null) { - console.log(chalk_1.default.bold.green(left) + ": " + right); + console.log(chalk_1.default.bold(left) + ": " + right); } } +function beautifyTime(t) { + return new Date(t).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }); +} function beautifyDate(s) { return new Date(s).toLocaleDateString([], { month: "short", day: "numeric", - year: "numeric" + year: "numeric", + }); +} +function parseActivity(activity) { + //set repo url for referencing + var repo = chalk_1.default.bold.rgb(255, 159, 28)(activity.repo.name); + switch (activity.type) { + case "PushEvent": + var commit = "commit"; + if (activity.payload.size > 1) { + commit += "s"; + } + return chalk_1.default.bold("Pushed") + " " + activity.payload.size + " " + commit + " to https://github.com/" + repo; + case "WatchEvent": + return chalk_1.default.bold("Starred") + " https://github.com/" + repo; + case "CreateEvent": + return chalk_1.default.bold("Created") + " a " + activity.payload.ref_type + " at https://github.com/" + repo; + case "DeleteEvent": + return chalk_1.default.bold("Deleted") + " a " + activity.payload.ref_type + " at https://github.com/" + repo; + case "ForkEvent": + return chalk_1.default.bold("Forked") + " a repo from " + activity.payload.forkee.html_url; + case "PullRequestEvent": + return chalk_1.default.bold(activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1)) + " a PR in https://github.com/" + repo; + case "PullRequestReviewCommentEvent": + return chalk_1.default.bold(activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1)) + " a comment on a PR in https://github.com/" + repo; + case "IssuesEvent": + return chalk_1.default.bold(activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1)) + " an issue in https://github.com/" + repo; + case "IssueCommentEvent": + return chalk_1.default.bold(activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1)) + " an issue in https://github.com/" + repo; + case "PublicEvent": + return chalk_1.default.bold("Made") + " https://github.com/" + repo + " public"; + } + return ""; +} +function checkResponse(res, err) { + return __awaiter(this, void 0, void 0, function () { + var lim, err_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (res.status === 404) { + console.log(chalk_1.default.redBright.bold(err)); + return [2 /*return*/, true]; + } + if (!(res.status === 403)) return [3 /*break*/, 3]; + return [4 /*yield*/, node_fetch_1.default("https://github.com/rate_limit")]; + case 1: + lim = _a.sent(); + return [4 /*yield*/, lim.json()]; + case 2: + err_1 = _a.sent(); + console.log(chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Shoot! Rate limit exceeded till " + + beautifyTime(err_1.resources.core.reset * 1000))); + return [2 /*return*/, true]; + case 3: + if (res.status !== 200) { + console.log(chalk_1.default.redBright.bold(node_emoji_1.default.get("anger") + " Error: " + res.statusText)); + return [2 /*return*/, true]; + } + return [2 /*return*/, false]; + } + }); }); } diff --git a/src/cli.ts b/src/cli.ts index e1d629a..b531259 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,4 +1,5 @@ #!/usr/bin/env node +/* eslint-disable no-case-declarations */ import chalk from "chalk"; import clear from "clear"; @@ -23,6 +24,19 @@ type User = { created_at: string; }; +const ActivityTypes: string[] = [ + "PushEvent", + "WatchEvent", + "CreateEvent", + "DeleteEvent", + "ForkEvent", + "PullRequestEvent", + "PullRequestReviewCommentEvent", + "IssuesEvent", + "IssueCommentEvent", + "PublicEvent", +]; + (async () => { // IIFE Used to get async/await on top level clear(); @@ -54,16 +68,11 @@ type User = { const res = await fetch(`${baseUrl}/users/${username}`); - if (res.status === 404) { - console.log( - chalk.redBright.bold(`${emoji.get("anger")} Shoot! that username does not exist on github`) - ); - return; - } - if (res.status !== 200) { - console.log(chalk.redBright.bold(`${emoji.get("anger")} Error: ${res.statusText}`)); - return; - } + let failure = await checkResponse( + res, + chalk.redBright.bold(`${emoji.get("anger")} Shoot! that username does not exist on github`) + ); + if (failure) return; const user: User = await res.json(); @@ -84,14 +93,56 @@ type User = { printPair("Repos", user.public_repos.toString()); printPair("Followers", user.followers.toString()); printPair("Following", user.following.toString()); + + const res2 = await fetch(`${baseUrl}/users/${username}/repos`); + + failure = await checkResponse( + res2, + chalk.redBright.bold(`${emoji.get("anger")} Shoot! repos not found`) + ); + if (failure) return; + + const repos: { [key: string]: any }[] = await res2.json(); + + let languages = repos.map((repo) => repo.language); + languages = languages.filter((a, b) => languages.indexOf(a) === b); + + console.log(); + console.log(emoji.get("rainbow") + chalk.bold.rgb(255, 22, 84)(" Languages")); + console.log(languages.join(" ")); + + const res3 = await fetch(`${baseUrl}/users/${username}/events`); + + failure = await checkResponse( + res2, + chalk.redBright.bold(`${emoji.get("anger")} Shoot! activity not found`) + ); + if (failure) return; + + const activities: { [key: string]: any }[] = await res3.json(); + + console.log(); + console.log(emoji.get("rocket") + chalk.bold.rgb(255, 22, 84)(" Activity")); + + activities + .filter((activity) => ActivityTypes.includes(activity.type)) + .slice(0, 5) + .map((activity) => console.log(parseActivity(activity))); })(); function printPair(left: string, right: string) { if (right !== null) { - console.log(`${chalk.bold.green(left)}: ${right}`); + console.log(`${chalk.bold(left)}: ${right}`); } } +function beautifyTime(t: number): string { + return new Date(t).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }); +} + function beautifyDate(s: string): string { return new Date(s).toLocaleDateString([], { month: "short", @@ -99,3 +150,72 @@ function beautifyDate(s: string): string { year: "numeric", }); } + +function parseActivity(activity: { [key: string]: any }): string { + //set repo url for referencing + const repo = chalk.bold.rgb(255, 159, 28)(activity.repo.name); + switch (activity.type) { + case "PushEvent": + let commit = "commit"; + if (activity.payload.size > 1) { + commit += "s"; + } + return `${chalk.bold("Pushed")} ${ + activity.payload.size + } ${commit} to https://github.com/${repo}`; + case "WatchEvent": + return `${chalk.bold("Starred")} https://github.com/${repo}`; + case "CreateEvent": + return `${chalk.bold("Created")} a ${ + activity.payload.ref_type + } at https://github.com/${repo}`; + case "DeleteEvent": + return `${chalk.bold("Deleted")} a ${ + activity.payload.ref_type + } at https://github.com/${repo}`; + case "ForkEvent": + return `${chalk.bold("Forked")} a repo from ${activity.payload.forkee.html_url}`; + case "PullRequestEvent": + return `${chalk.bold( + activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1) + )} a PR in https://github.com/${repo}`; + case "PullRequestReviewCommentEvent": + return `${chalk.bold( + activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1) + )} a comment on a PR in https://github.com/${repo}`; + case "IssuesEvent": + return `${chalk.bold( + activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1) + )} an issue in https://github.com/${repo}`; + case "IssueCommentEvent": + return `${chalk.bold( + activity.payload.action.charAt(0).toUpperCase() + activity.payload.action.slice(1) + )} an issue in https://github.com/${repo}`; + case "PublicEvent": + return `${chalk.bold("Made")} https://github.com/${repo} public`; + } + return ""; +} + +async function checkResponse(res: any, err: string): Promise { + if (res.status === 404) { + console.log(chalk.redBright.bold(err)); + return true; + } + if (res.status === 403) { + const lim = await fetch(`https://github.com/rate_limit`); + const err = await lim.json(); + console.log( + chalk.redBright.bold( + `${emoji.get("anger")} Shoot! Rate limit exceeded till ` + + beautifyTime(err.resources.core.reset * 1000) + ) + ); + return true; + } + if (res.status !== 200) { + console.log(chalk.redBright.bold(`${emoji.get("anger")} Error: ${res.statusText}`)); + return true; + } + return false; +}