adaptorex
Version:
Connect all your live interactive storytelling devices and software
245 lines (228 loc) • 5.55 kB
JavaScript
/**
* read and write files
*
* @requires fs-extra
* @requires path
* @requires chokidar
* @requires js-yaml
*
* @module file
* @copyright Lasse Marburg 2021
* @license MIT
*/
const fs = require("fs-extra")
const chokidar = require("chokidar")
const path = require("path")
const yaml = require("js-yaml")
/**
* write data to file
*/
function toFile(data, file, create_dirs) {
return new Promise(function (resolve, reject) {
fs.writeFile(file, data, "utf8", function (err) {
if (err) {
log.error(0, "An error occured while writing to " + file + "\n" + err)
return reject()
}
log.debug(0, file + " saved")
return resolve(file + " saved")
})
})
}
/**
* create folder if it doesn't exist
*
* @returns {boolean} true if folder already existed, false if it was created
*/
function mkdir(path) {
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true })
return false
}
return true
}
/**
* report changes on directory. Uses [chokidar](@link https://github.com/paulmillr/chokidar).
*
* @param {string} path
* @param {function} callback
*/
function watchDir(path, callback) {
chokidar
.watch(path, { ignoreInitial: true, ignored: "**/.git/**", depth: 10 })
.on("all", callback)
}
/**
* remove folder and content
*
*/
function rm(path) {
if (fs.existsSync(path)) {
fs.removeSync(path)
return true
}
return false
}
function cp(orig, dest) {
return new Promise((resolve, reject) => {
fs.copy(orig, dest, (err) => {
if (err) return reject(err)
return resolve()
})
})
}
/**
* move or rename a file.
* @param {string} orig - file to be moved
* @param {string} dest - move file to destination
*/
function mv(orig, dest) {
return new Promise((resolve, reject) => {
if (dest[dest.length - 1] == "/") {
orig_file = orig.substring(orig.lastIndexOf("/") + 1)
dest = dest + orig_file
}
fs.rename(orig, dest, (err) => {
if (err) return reject(err)
log.info("file", "moved from " + orig + " to " + dest)
return resolve()
})
})
}
/**
* check if file or folder exists
*
* @returns {boolean} - true if folder/file exists
*/
function exists(path) {
return fs.existsSync(path)
}
/**
* get a list of all files in a folder (syncronous)
*
* @example
* // returns list of image files
* ls("/path/to/my/pictures", [".jpg",".jpeg",".png"])
* @example
* // returns only directories
* ls("/path", "directories")
*
* @param {string|array} filter - filter "directories" (only directories) or filenames
*
* @returns {array} list of directories and/or filenames
*/
function ls(dir, filter) {
if (filter == "directories") {
return fs.readdirSync(dir).filter((name) => {
let p = path.join(dir, name)
return isDir(p)
})
} else if (Array.isArray(filter)) {
let all = fs.readdirSync(dir)
let show = []
for (let a of all) {
filter.forEach((elem) => {
if (a.includes(elem)) {
show.push(a)
}
})
}
return show
} else if (typeof filter === "string") {
let all = fs.readdirSync(dir)
let show = []
for (let a of all) {
if (a.includes(filter)) {
show.push(a)
}
}
return show
}
return fs.readdirSync(dir)
}
/**
* Checks if the given path is a directory.
*
* @param {string} directory - The path to check.
* @returns {boolean} - Returns `true` if the path is a directory, otherwise `false`.
*/
function isDir(directory) {
return fs.lstatSync(directory).isDirectory()
}
/**
* load json data from file
*/
function loadJSON(filename) {
return new Promise(function (resolve, reject) {
fs.readFile(filename, "utf8", function (err, data) {
if (err) {
log.error(0, "An error occured while reading " + filename + "\n" + err)
//reject()
} else {
try {
json_data = JSON.parse(data)
resolve(json_data)
} catch (e) {
log.error(0, "An error occured while reading " + filename + "\n" + e)
//reject()
}
}
})
})
}
/**
* save json data to file
*/
function saveJSON(data, file) {
return new Promise(function (resolve, reject) {
save_data = JSON.stringify(data, null, 2)
toFile(save_data, file, true)
.then(function (result) {
return resolve(result)
})
.catch(function (error) {
log.error(this.name, error)
return reject(error)
})
})
}
/**
* load a file of type .yaml and make it accessible in js context
*
* @param {string} file - path to and filename of a .yaml file
* @returns {Object|string|number|null|undefined} yaml file content converted to js object, string, number, null or undefined (returns undefined also on error)
*/
function loadYAML(file) {
try {
const doc = yaml.load(fs.readFileSync(file, "utf8"))
log.debug("file", "load yaml file from " + file)
return doc
} catch (err) {
log.error("file", err)
return undefined
}
}
/**
* Store json data object as file of type yaml.
*
* @param {Object} data - json data to be stored as yaml file
* @param {string} file - fpath to and filename of a .yaml file
*/
function saveYAML(data, file) {
let yamlStr = yaml.dump(data)
fs.writeFileSync(file, yamlStr, "utf8")
}
module.exports = {
loadYAML: loadYAML,
saveYAML: saveYAML,
loadJSON: loadJSON,
saveJSON: saveJSON,
mkdir: mkdir,
watchDir: watchDir,
exists: exists,
isDir: isDir,
ls: ls,
rm: rm,
cp: cp,
mv: mv
}