Initial commit
This commit is contained in:
@@ -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,
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
};
|
||||
Reference in New Issue
Block a user