diff --git a/.gitignore b/.gitignore index 6704566..6d0ba52 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,9 @@ dist # TernJS port file .tern-port + +# Misc. +.DS_Store + +# Docs output +docs diff --git a/app.js b/app.js index 8932ff0..3499e55 100644 --- a/app.js +++ b/app.js @@ -1,9 +1,21 @@ const express = require("express"); + +const util = require("./util"); const app = express(); const port = 3000; app.get("/", (req, res) => res.send("Hello World!")); +app.get("/:user/:repo/compile", (req, res) => { + const user = req.params.user; + const repo = req.params.repo; + + util.getReadme(user, repo).then(() => { + util.serveDocs(app, user, repo); + res.send(`Successfully Compiled Docs! View them at /${user}/${repo}`); + }); +}); + app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`) ); diff --git a/docsify.js b/docsify.js new file mode 100644 index 0000000..aaafdb9 --- /dev/null +++ b/docsify.js @@ -0,0 +1,5 @@ +function generateHTML(user, repo) { + return `${repo}
`; +} + +module.exports = { generateHTML }; diff --git a/package-lock.json b/package-lock.json index aaf3198..66a99de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -331,6 +331,14 @@ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -709,6 +717,24 @@ "semver-regex": "^2.0.0" } }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -799,6 +825,22 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "hasha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz", + "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==", + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", @@ -909,6 +951,11 @@ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", diff --git a/package.json b/package.json index 264fb41..1d85e0b 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ } }, "dependencies": { - "express": "^4.17.1" + "axios": "^0.19.2", + "express": "^4.17.1", + "hasha": "^5.2.0" } } diff --git a/template.html b/template.html new file mode 100644 index 0000000..1f9c2a0 --- /dev/null +++ b/template.html @@ -0,0 +1,29 @@ + + + + + Document + + + + + + + +
+ + + + + diff --git a/util.js b/util.js new file mode 100644 index 0000000..1af1e16 --- /dev/null +++ b/util.js @@ -0,0 +1,70 @@ +const express = require("express"); +const axios = require("axios"); +const fs = require("fs"); +const hasha = require("hasha"); + +const docsify = require("./docsify"); + +// Compares local and remote readme for changes +function isDiffReadme(user, repo, readmeData) { + if (fs.existsSync(`./docs/${user}-${repo}/README.md`)) { + const localReadmeHash = hasha.fromFileSync( + `./docs/${user}-${repo}/README.md`, + { algorithm: "md5" } + ); + const remoteReadmeHash = hasha(readmeData, { algorithm: "md5" }); + + if (localReadmeHash == remoteReadmeHash) { + return false; + } + } + return true; +} + +// Writes all the required files +function writeDocs(user, repo, readmeData) { + const htmlData = docsify.generateHTML(user, repo); + + fs.writeFileSync(`./docs/${user}-${repo}/README.md`, readmeData, function ( + err + ) { + if (err) throw err; + console.log("Generated ReadMe!"); + }); + + fs.writeFileSync(`./docs/${user}-${repo}/index.html`, htmlData, function ( + err + ) { + if (err) throw err; + console.log("Generated HTML!"); + }); +} + +// Gets readme contents and generates /docs/ with docsify enabled to render +async function getReadme(user, repo) { + const readme = await axios.get( + `https://api.github.com/repos/${user}/${repo}/readme` + ); + const readmeUrl = readme.data.download_url; + const readmeData = await axios.get(readmeUrl); + + if (!fs.existsSync("./docs/")) { + fs.mkdirSync("./docs/"); + } + + if (!fs.existsSync(`./docs/${user}-${repo}/`)) { + fs.mkdirSync(`./docs/${user}-${repo}/`); + } + + // Write file only if github readme is different from local copy + if (isDiffReadme(user, repo, readmeData.data)) { + writeDocs(user, repo, readmeData.data); + } +} + +// Serves the compiled docs +function serveDocs(app, user, repo) { + app.use(`/${user}/${repo}`, express.static(`./docs/${user}-${repo}`)); +} + +module.exports = { getReadme, serveDocs };