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, };