joplin/ReactNativeClient/lib/fs-driver-node.js

181 lines
4.2 KiB
JavaScript
Raw Normal View History

2018-03-09 17:49:35 +00:00
const fs = require("fs-extra");
const { time } = require("lib/time-utils.js");
const FsDriverBase = require("lib/fs-driver-base");
2017-07-05 21:52:31 +00:00
class FsDriverNode extends FsDriverBase {
2018-01-28 17:36:36 +00:00
fsErrorToJsError_(error, path = null) {
let msg = error.toString();
2018-03-09 17:49:35 +00:00
if (path !== null) msg += ". Path: " + path;
2018-01-28 17:36:36 +00:00
let output = new Error(msg);
if (error.code) output.code = error.code;
return output;
}
2017-07-05 21:52:31 +00:00
appendFileSync(path, string) {
return fs.appendFileSync(path, string);
}
2018-03-09 17:49:35 +00:00
async appendFile(path, string, encoding = "base64") {
2018-01-28 17:36:36 +00:00
try {
return await fs.appendFile(path, string, { encoding: encoding });
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
2018-01-28 17:36:36 +00:00
async writeBinaryFile(path, content) {
try {
let buffer = new Buffer(content);
return await fs.writeFile(path, buffer);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
2017-07-05 21:52:31 +00:00
}
2018-03-09 17:49:35 +00:00
async writeFile(path, string, encoding = "base64") {
2018-01-28 17:36:36 +00:00
try {
return await fs.writeFile(path, string, { encoding: encoding });
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
// same as rm -rf
async remove(path) {
2018-01-28 17:36:36 +00:00
try {
return await fs.remove(path);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
async move(source, dest) {
let lastError = null;
for (let i = 0; i < 5; i++) {
try {
const output = await fs.move(source, dest, { overwrite: true });
return output;
} catch (error) {
lastError = error;
// Normally cannot happen with the `overwrite` flag but sometime it still does.
// In this case, retry.
2018-03-09 17:49:35 +00:00
if (error.code == "EEXIST") {
await time.sleep(1);
continue;
}
2018-01-28 17:36:36 +00:00
throw this.fsErrorToJsError_(error);
}
}
throw lastError;
}
exists(path) {
return fs.pathExists(path);
}
async mkdir(path) {
return fs.mkdirp(path);
}
async stat(path) {
try {
const stat = await fs.stat(path);
return {
birthtime: stat.birthtime,
mtime: stat.mtime,
isDirectory: () => stat.isDirectory(),
path: path,
size: stat.size,
};
} catch (error) {
2018-03-09 17:49:35 +00:00
if (error.code == "ENOENT") return null;
throw error;
}
}
async setTimestamp(path, timestampDate) {
return fs.utimes(path, timestampDate, timestampDate);
}
async readDirStats(path, options = null) {
if (!options) options = {};
2018-03-09 17:49:35 +00:00
if (!("recursive" in options)) options.recursive = false;
2018-02-26 18:43:50 +00:00
let items = [];
try {
items = await fs.readdir(path);
} catch (error) {
throw this.fsErrorToJsError_(error);
}
let output = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
2018-03-09 17:49:35 +00:00
let stat = await this.stat(path + "/" + item);
if (!stat) continue; // Has been deleted between the readdir() call and now
stat.path = stat.path.substr(path.length + 1);
output.push(stat);
output = await this.readDirStatsHandleRecursion_(path, stat, output, options);
}
return output;
}
2018-01-28 17:36:36 +00:00
async open(path, mode) {
try {
return await fs.open(path, mode);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
2018-01-28 17:36:36 +00:00
async close(handle) {
try {
return await fs.close(handle);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
2018-03-09 17:49:35 +00:00
async readFile(path, encoding = "utf8") {
try {
2018-03-09 17:49:35 +00:00
if (encoding === "Buffer") return await fs.readFile(path); // Returns the raw buffer
return await fs.readFile(path, encoding);
} catch (error) {
throw this.fsErrorToJsError_(error, path);
}
}
// Always overwrite destination
async copy(source, dest) {
try {
return await fs.copy(source, dest, { overwrite: true });
} catch (error) {
throw this.fsErrorToJsError_(error, source);
}
2017-07-05 21:52:31 +00:00
}
async unlink(path) {
try {
await fs.unlink(path);
} catch (error) {
2018-03-09 17:49:35 +00:00
if (error.code === "ENOENT") return; // Don't throw if the file does not exist
throw error;
}
}
2018-03-09 17:49:35 +00:00
async readFileChunk(handle, length, encoding = "base64") {
let buffer = new Buffer(length);
2017-12-23 20:21:11 +00:00
const result = await fs.read(handle, buffer, 0, length, null);
if (!result.bytesRead) return null;
2017-12-23 20:21:11 +00:00
buffer = buffer.slice(0, result.bytesRead);
2018-03-09 17:49:35 +00:00
if (encoding === "base64") return buffer.toString("base64");
if (encoding === "ascii") return buffer.toString("ascii");
throw new Error("Unsupported encoding: " + encoding);
}
2017-07-05 21:52:31 +00:00
}
2018-03-09 17:49:35 +00:00
module.exports.FsDriverNode = FsDriverNode;