diff --git a/app/backend.js b/app/backend.js index ffabe5219ddea2b1b48dabc9cc41b460815d4272..71d1e5d6181a1dd649c4d53a346008d061358866 100644 --- a/app/backend.js +++ b/app/backend.js @@ -25,12 +25,12 @@ if (__DEV__) { lastHash = stats.hash; console.info(stats.toString({ cached: false, - colors: true + colors: true, })); try { if (httpServer) httpServer.close(); - delete require.cache[require.resolve(backendBuildPath)]; + Object.keys(require.cache).forEach(key => delete require.cache[key]); const app = require(backendBuildPath).default; httpServer = app.listen(proxyPort); } catch (e) { diff --git a/app/frontend.js b/app/frontend.js index 6fb66341501b01a51127e3d456b5554a6504e3f3..ca297c63ca999d7f82c598e981abd50fde811645 100644 --- a/app/frontend.js +++ b/app/frontend.js @@ -21,7 +21,7 @@ if (__DEV__) { app.use(webpackDev(compiler, { stats: { cached: false, - colors: true + colors: true, }, })); app.use(webpackHot(compiler)); diff --git a/environment.js b/environment.js index c16429eb0a07e39f9745e994b5894aada7fdd4b2..12c4f93f4954eb75165c008a651df099ea13fc81 100644 --- a/environment.js +++ b/environment.js @@ -8,10 +8,6 @@ const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, - GITHUB_BOT_USERNAME, - GITHUB_BOT_PASSWORD, - GITHUB_ORG = 'algorithm-visualizer', - GITHUB_REPO = 'algorithms', } = process.env; const __PROD__ = NODE_ENV === 'production'; @@ -22,12 +18,6 @@ const proxyPort = parseInt(PROXY_PORT); const githubClientId = GITHUB_CLIENT_ID; const githubClientSecret = GITHUB_CLIENT_SECRET; -const githubBotAuth = { - username: GITHUB_BOT_USERNAME, - password: GITHUB_BOT_PASSWORD, -}; -const githubOrg = GITHUB_ORG; -const githubRepo = GITHUB_REPO; const buildPath = path.resolve(__dirname, 'build'); const frontendBuildPath = path.resolve(buildPath, 'frontend'); @@ -46,9 +36,6 @@ module.exports = { proxyPort, githubClientId, githubClientSecret, - githubBotAuth, - githubOrg, - githubRepo, frontendBuildPath, backendBuildPath, frontendSrcPath, diff --git a/package.json b/package.json index e441bc74ebd0fdb1ff2b712060d7f537b7b1a306..c13beff0d56ad08132a8c07a00dbdf9c6691e140 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.7.0", "express": "^4.15.4", - "github-api": "^3.0.0", "html-webpack-plugin": "^3.2.0", "http-proxy-middleware": "^0.18.0", "imagemin-webpack-plugin": "^2.1.1", diff --git a/src/backend/apis/index.js b/src/backend/apis/index.js new file mode 100644 index 0000000000000000000000000000000000000000..807c50381a852b43cb98a444dc3d80f8f422c4d9 --- /dev/null +++ b/src/backend/apis/index.js @@ -0,0 +1,64 @@ +import Promise from 'bluebird'; +import axios from 'axios'; + +axios.interceptors.response.use(response => { + return response.data; +}, error => { + return Promise.reject(error.response.data); +}); + +const request = (url, process) => { + const tokens = url.split('/'); + const baseURL = /^https?:\/\//i.test(url) ? '' : 'https://api.github.com'; + return (...args) => { + return new Promise((resolve, reject) => { + const mappedURL = baseURL + tokens.map((token, i) => token.startsWith(':') ? args.shift() : token).join('/'); + return resolve(process(mappedURL, args)); + }); + }; +}; + +const GET = URL => { + return request(URL, (mappedURL, args) => { + const [params] = args; + return axios.get(mappedURL, { params }); + }); +}; + +const DELETE = URL => { + return request(URL, (mappedURL, args) => { + const [params] = args; + return axios.delete(mappedURL, { params }); + }); +}; + +const POST = URL => { + return request(URL, (mappedURL, args) => { + const [body, params] = args; + return axios.post(mappedURL, body, { params }); + }); +}; + +const PUT = URL => { + return request(URL, (mappedURL, args) => { + const [body, params] = args; + return axios.put(mappedURL, body, { params }); + }); +}; + +const PATCH = URL => { + return request(URL, (mappedURL, args) => { + const [body, params] = args; + return axios.patch(mappedURL, body, { params }); + }); +}; + +const GitHubApi = { + auth: (client_id, client_secret) => axios.defaults.params = { client_id, client_secret }, + listCommits: GET('/repos/:owner/:repo/commits'), + getAccessToken: code => axios.post('https://github.com/login/oauth/access_token', { code }, { headers: { Accept: 'application/json' } }), +}; + +export { + GitHubApi, +}; \ No newline at end of file diff --git a/src/backend/common/github.js b/src/backend/common/github.js deleted file mode 100644 index f28cc5fab326bda0e31cd65bd484104132389101..0000000000000000000000000000000000000000 --- a/src/backend/common/github.js +++ /dev/null @@ -1,9 +0,0 @@ -import GitHub from 'github-api'; -import { githubBotAuth, githubOrg, githubRepo } from '/environment'; - -const gh = new GitHub(githubBotAuth); -const repo = gh.getRepo(githubOrg, githubRepo); - -export { - repo, -}; \ No newline at end of file diff --git a/src/backend/controllers/auth.js b/src/backend/controllers/auth.js index 6b220d52dd2737ccd9c069450bba6a1d7a35d19c..003b6ea3e38ae196e253f1c2bf7d9305b21b9d02 100644 --- a/src/backend/controllers/auth.js +++ b/src/backend/controllers/auth.js @@ -1,6 +1,6 @@ import express from 'express'; -import axios from 'axios'; -import { githubClientId, githubClientSecret } from '/environment'; +import { githubClientId } from '/environment'; +import { GitHubApi } from '/apis'; const router = express.Router(); @@ -11,14 +11,7 @@ const request = (req, res, next) => { const response = (req, res, next) => { const { code } = req.query; - axios.post('https://github.com/login/oauth/access_token', { - client_id: githubClientId, - client_secret: githubClientSecret, - code, - }, { - headers: { Accept: 'application/json' } - }).then(response => { - const { access_token } = response.data; + GitHubApi.getAccessToken(code).then(({ access_token }) => { res.cookie('access_token', access_token); res.redirect('/'); }).catch(next); diff --git a/src/backend/controllers/categories.js b/src/backend/controllers/categories.js index a40cd0eb986c408307ce13cb575ab6c0b48dae8a..3b7b1155484bac2e718179ae58867aa03d706388 100644 --- a/src/backend/controllers/categories.js +++ b/src/backend/controllers/categories.js @@ -3,7 +3,7 @@ import fs from 'fs'; import path from 'path'; import { NotFoundError } from '/common/error'; import { exec } from 'child_process'; -import { repo } from '/common/github'; +import { GitHubApi } from '/apis'; const router = express.Router(); @@ -49,16 +49,16 @@ const cacheCategories = () => { const categories = list(getPath()).map(cacheCategory); const per_page = 100; - const cacheCommitAuthors = (page = 1, commitAuthors = {}) => repo.listCommits({ + const cacheCommitAuthors = (page = 1, commitAuthors = {}) => GitHubApi.listCommits('algorithm-visualizer', 'algorithms', { per_page, page, - }).then(({ data }) => { - data.forEach(({ sha, commit, author }) => { + }).then(commits => { + commits.forEach(({ sha, commit, author }) => { if (!author) return; const { login, avatar_url } = author; commitAuthors[sha] = { login, avatar_url }; }); - if (data.length < per_page) { + if (commits.length < per_page) { return commitAuthors; } else { return cacheCommitAuthors(page + 1, commitAuthors); diff --git a/src/backend/index.js b/src/backend/index.js index 8d9ea6687395445c929a2686d01f23e4f7b5390c..cf4f9278924268df56a9a0019c2a03ac0ea45aa0 100644 --- a/src/backend/index.js +++ b/src/backend/index.js @@ -4,7 +4,10 @@ import cookieParser from 'cookie-parser'; import bodyParser from 'body-parser'; import * as controllers from '/controllers'; import { AuthorizationError, NotFoundError, PermissionError } from '/common/error'; +import { GitHubApi } from '/apis'; +import { githubClientId, githubClientSecret } from '/environment'; +GitHubApi.auth(githubClientId, githubClientSecret); const app = express(); app.use(morgan('tiny')); app.use(cookieParser()); diff --git a/src/backend/public/libs/.gitignore b/src/backend/public/libs/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c96a04f008ee21e260b28f7701595ed59e2839e3 --- /dev/null +++ b/src/backend/public/libs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file