1
0

Initial commit

This commit is contained in:
Eric Lewin
2020-08-23 21:48:06 -05:00
commit 162ce47bc6
57 changed files with 12096 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
const axios = require("axios");
/**
* Gets coordinates from an external API
*
*/
function getCoords(req, res) {
axios
.get("https://freegeoip.app/json/")
.then((result) => {
return res.status(result.status).json(result.data).end();
})
.catch((err) => {
return res.status(500).json(err).end();
});
}
module.exports = {
getCoords,
};
+52
View File
@@ -0,0 +1,52 @@
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const open = require("open");
const ver = require("../package.json").version;
const appName = require("../package.json").name;
const settingsCtrl = require("./settingsCtrl");
const geolocationCtrl = require("./geolocationCtrl");
const {
getSettings,
setSetting,
deleteSetting,
createSettingsFile,
replaceSettings,
} = settingsCtrl;
const { getCoords } = geolocationCtrl;
const DIST_DIR = "/../client/dist";
const PORT = 8080;
const app = express();
// ***** dev only:
// const livereload = require("livereload");
// const connectLivereload = require("connect-livereload");
// const liveReloadServer = livereload.createServer();
// liveReloadServer.watch(path.join(`${__dirname}/${DIST_DIR}`));
// liveReloadServer.server.once("connection", () => {
// setTimeout(() => {
// liveReloadServer.refresh("/");
// }, 100);
// });
// app.use(connectLivereload());
// *****
app.use(cors());
app.use(bodyParser.json());
app.use(express.static(path.join(`${__dirname}/${DIST_DIR}`)));
app.listen(PORT, "localhost", async () => {
await open(`http://localhost:${PORT}`);
console.log(`${appName} v${ver} has started on port ${PORT}`);
});
app.get("/settings", getSettings);
app.post("/settings", createSettingsFile);
app.put("/settings", replaceSettings);
app.patch("/setting", setSetting);
app.delete("/setting", deleteSetting);
app.get("/geolocation", getCoords);
+209
View File
@@ -0,0 +1,209 @@
const fs = require("fs");
const path = require("path");
const SETTINGS_FILE = "../settings.json";
const FILE_PATH = path.join(`${__dirname}/${SETTINGS_FILE}`);
const ENCODING = "utf8";
/**
* Read the settings.json file
*
* @param {Object} callbacks
* @param {Function} callbacks.successCb
* @param {Function} callbacks.errorCb
*/
function readSettingsFile({ successCb, errorCb }) {
fs.readFile(FILE_PATH, (err, data) => {
if (err) {
errorCb(err);
} else {
successCb(JSON.parse(data));
}
});
}
/**
* Creates a `settings.json` file
*
* @param {Object} req
* @param {Object} [req.body]
* @param {Object} res
*/
function createSettingsFile(req, res) {
const contents = req.body || {};
if (fs.existsSync(FILE_PATH)) {
return res.status(409).json("settings file already exists").end();
} else {
fs.writeFile(FILE_PATH, JSON.stringify(contents), ENCODING, (err) => {
if (err) {
return res.status(500).json(err).end();
} else {
return res.status(201).json(contents).end();
}
});
}
}
/**
* Return the settings.json file
*/
function getSettings(req, res) {
if (!fs.existsSync(FILE_PATH)) {
return res.status(404).json("settings.json not found!").end();
}
readSettingsFile({
successCb: (data) => {
return res.status(200).json(data).end();
},
errorCb: (err) => {
return res.status(500).end();
},
});
}
/**
* Sets a single setting. Creates a new `settings.json` file if none exists.
*
* @param {Object} req
* @param {Object} res
*/
function setSetting(req, res) {
const { key, val } = req.body;
if (!key || !val) {
return res.status(400).json("You must supply a key and val").end();
}
/**
* Writes file contents
*
* @param {Object} newSettings
* @param {Boolean} [newFile] If file is new
*/
const writeContents = (newSettings, newFile) => {
fs.writeFile(FILE_PATH, JSON.stringify(newSettings), ENCODING, (err) => {
if (err) {
return res.status(500).json(err).end();
} else {
return res
.status(newFile ? 201 : 200)
.json(newSettings)
.end();
}
});
};
/**
* Read success callback
*
* @param {Object} currentSettings
*/
const readSuccess = (currentSettings) => {
const newSettings = {
...currentSettings,
[key]: val,
};
writeContents(newSettings);
};
/**
* Read error callback
*
* @param {Object} [err]
*/
const readError = (err) => {
return res.status(500).json(err).end();
};
if (!fs.existsSync(FILE_PATH)) {
writeContents({ [key]: val }, true);
} else {
readSettingsFile({
successCb: readSuccess,
errorCb: readError,
});
}
}
function replaceSettings(req, res) {
const { body } = req;
if (!body) {
return res.status(400).json("You must provide settings contents").end();
}
const fileExists = fs.existsSync(FILE_PATH);
fs.writeFile(FILE_PATH, JSON.stringify(body), ENCODING, (err) => {
if (err) {
return res.status(500).json(err).end();
} else {
return res
.status(fileExists ? 200 : 201)
.json(body)
.end();
}
});
}
/**
* Deletes a specific setting
*
* @param {Object} req
* @param {Object} req.query
* @param {Object} req.query.key The key to be deleted
* @param {Object} res
*/
function deleteSetting(req, res) {
const { key } = req.query;
if (!key) {
return res.status(400).json("You must supply a key to delete").end();
}
/**
* Read success callback
*
* @param {Object} currentSettings
*/
const readSuccess = (currentSettings) => {
if (!Object.prototype.hasOwnProperty.call(currentSettings, key)) {
return res.status(404).end();
}
delete currentSettings[key];
fs.writeFile(
FILE_PATH,
JSON.stringify(currentSettings),
ENCODING,
(err) => {
if (err) {
return res.status(500).json(err).end();
} else {
return res.status(200).json(currentSettings).end();
}
}
);
};
/**
* Error callback
*
* @param {Object} err
*/
const readError = (err) => {
return res.status(500).json(err).end();
};
readSettingsFile({
successCb: readSuccess,
errorCb: readError,
});
}
module.exports = {
getSettings,
setSetting,
deleteSetting,
createSettingsFile,
replaceSettings,
};