mirror of
https://github.com/Instadapp/Swap-Aggregator-Subgraph.git
synced 2024-07-29 21:57:12 +00:00
194 lines
4.9 KiB
JavaScript
194 lines
4.9 KiB
JavaScript
"use strict";
|
|
|
|
const crypto = require("crypto");
|
|
const pathUtil = require("path");
|
|
const fs = require("./utils/fs");
|
|
const validate = require("./utils/validate");
|
|
|
|
const supportedChecksumAlgorithms = ["md5", "sha1", "sha256", "sha512"];
|
|
|
|
const symlinkOptions = ["report", "follow"];
|
|
|
|
const validateInput = (methodName, path, options) => {
|
|
const methodSignature = `${methodName}(path, [options])`;
|
|
validate.argument(methodSignature, "path", path, ["string"]);
|
|
validate.options(methodSignature, "options", options, {
|
|
checksum: ["string"],
|
|
mode: ["boolean"],
|
|
times: ["boolean"],
|
|
absolutePath: ["boolean"],
|
|
symlinks: ["string"]
|
|
});
|
|
|
|
if (
|
|
options &&
|
|
options.checksum !== undefined &&
|
|
supportedChecksumAlgorithms.indexOf(options.checksum) === -1
|
|
) {
|
|
throw new Error(
|
|
`Argument "options.checksum" passed to ${methodSignature} must have one of values: ${supportedChecksumAlgorithms.join(
|
|
", "
|
|
)}`
|
|
);
|
|
}
|
|
|
|
if (
|
|
options &&
|
|
options.symlinks !== undefined &&
|
|
symlinkOptions.indexOf(options.symlinks) === -1
|
|
) {
|
|
throw new Error(
|
|
`Argument "options.symlinks" passed to ${methodSignature} must have one of values: ${symlinkOptions.join(
|
|
", "
|
|
)}`
|
|
);
|
|
}
|
|
};
|
|
|
|
const createInspectObj = (path, options, stat) => {
|
|
const obj = {};
|
|
|
|
obj.name = pathUtil.basename(path);
|
|
|
|
if (stat.isFile()) {
|
|
obj.type = "file";
|
|
obj.size = stat.size;
|
|
} else if (stat.isDirectory()) {
|
|
obj.type = "dir";
|
|
} else if (stat.isSymbolicLink()) {
|
|
obj.type = "symlink";
|
|
} else {
|
|
obj.type = "other";
|
|
}
|
|
|
|
if (options.mode) {
|
|
obj.mode = stat.mode;
|
|
}
|
|
|
|
if (options.times) {
|
|
obj.accessTime = stat.atime;
|
|
obj.modifyTime = stat.mtime;
|
|
obj.changeTime = stat.ctime;
|
|
}
|
|
|
|
if (options.absolutePath) {
|
|
obj.absolutePath = path;
|
|
}
|
|
|
|
return obj;
|
|
};
|
|
|
|
// ---------------------------------------------------------
|
|
// Sync
|
|
// ---------------------------------------------------------
|
|
|
|
const fileChecksum = (path, algo) => {
|
|
const hash = crypto.createHash(algo);
|
|
const data = fs.readFileSync(path);
|
|
hash.update(data);
|
|
return hash.digest("hex");
|
|
};
|
|
|
|
const addExtraFieldsSync = (path, inspectObj, options) => {
|
|
if (inspectObj.type === "file" && options.checksum) {
|
|
inspectObj[options.checksum] = fileChecksum(path, options.checksum);
|
|
} else if (inspectObj.type === "symlink") {
|
|
inspectObj.pointsAt = fs.readlinkSync(path);
|
|
}
|
|
};
|
|
|
|
const inspectSync = (path, options) => {
|
|
let statOperation = fs.lstatSync;
|
|
let stat;
|
|
const opts = options || {};
|
|
|
|
if (opts.symlinks === "follow") {
|
|
statOperation = fs.statSync;
|
|
}
|
|
|
|
try {
|
|
stat = statOperation(path);
|
|
} catch (err) {
|
|
// Detection if path exists
|
|
if (err.code === "ENOENT") {
|
|
// Doesn't exist. Return undefined instead of throwing.
|
|
return undefined;
|
|
}
|
|
throw err;
|
|
}
|
|
|
|
const inspectObj = createInspectObj(path, opts, stat);
|
|
addExtraFieldsSync(path, inspectObj, opts);
|
|
|
|
return inspectObj;
|
|
};
|
|
|
|
// ---------------------------------------------------------
|
|
// Async
|
|
// ---------------------------------------------------------
|
|
|
|
const fileChecksumAsync = (path, algo) => {
|
|
return new Promise((resolve, reject) => {
|
|
const hash = crypto.createHash(algo);
|
|
const s = fs.createReadStream(path);
|
|
s.on("data", data => {
|
|
hash.update(data);
|
|
});
|
|
s.on("end", () => {
|
|
resolve(hash.digest("hex"));
|
|
});
|
|
s.on("error", reject);
|
|
});
|
|
};
|
|
|
|
const addExtraFieldsAsync = (path, inspectObj, options) => {
|
|
if (inspectObj.type === "file" && options.checksum) {
|
|
return fileChecksumAsync(path, options.checksum).then(checksum => {
|
|
inspectObj[options.checksum] = checksum;
|
|
return inspectObj;
|
|
});
|
|
} else if (inspectObj.type === "symlink") {
|
|
return fs.readlink(path).then(linkPath => {
|
|
inspectObj.pointsAt = linkPath;
|
|
return inspectObj;
|
|
});
|
|
}
|
|
return Promise.resolve(inspectObj);
|
|
};
|
|
|
|
const inspectAsync = (path, options) => {
|
|
return new Promise((resolve, reject) => {
|
|
let statOperation = fs.lstat;
|
|
const opts = options || {};
|
|
|
|
if (opts.symlinks === "follow") {
|
|
statOperation = fs.stat;
|
|
}
|
|
|
|
statOperation(path)
|
|
.then(stat => {
|
|
const inspectObj = createInspectObj(path, opts, stat);
|
|
addExtraFieldsAsync(path, inspectObj, opts).then(resolve, reject);
|
|
})
|
|
.catch(err => {
|
|
// Detection if path exists
|
|
if (err.code === "ENOENT") {
|
|
// Doesn't exist. Return undefined instead of throwing.
|
|
resolve(undefined);
|
|
} else {
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
// ---------------------------------------------------------
|
|
// API
|
|
// ---------------------------------------------------------
|
|
|
|
exports.supportedChecksumAlgorithms = supportedChecksumAlgorithms;
|
|
exports.symlinkOptions = symlinkOptions;
|
|
exports.validateInput = validateInput;
|
|
exports.sync = inspectSync;
|
|
exports.async = inspectAsync;
|