206 lines
6.3 KiB
JavaScript
206 lines
6.3 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const fs_1 = __importDefault(require("fs"));
|
|
const mkdirp_1 = __importDefault(require("mkdirp"));
|
|
const destroy_1 = __importDefault(require("destroy"));
|
|
const tmp_1 = __importDefault(require("tmp"));
|
|
const path_1 = __importDefault(require("path"));
|
|
const cp_1 = __importDefault(require("cp"));
|
|
const cpr_1 = __importDefault(require("cpr"));
|
|
const promise_1 = __importDefault(require("./promise"));
|
|
const http_1 = __importDefault(require("http"));
|
|
const https_1 = __importDefault(require("https"));
|
|
// Write a stream to a file
|
|
function writeStream(filename, st) {
|
|
const d = promise_1.default.defer();
|
|
const wstream = fs_1.default.createWriteStream(filename);
|
|
const cleanup = function () {
|
|
(0, destroy_1.default)(wstream);
|
|
wstream.removeAllListeners();
|
|
};
|
|
wstream.on("finish", () => {
|
|
cleanup();
|
|
d.resolve();
|
|
});
|
|
wstream.on("error", (err) => {
|
|
cleanup();
|
|
d.reject(err);
|
|
});
|
|
st.on("error", (err) => {
|
|
cleanup();
|
|
d.reject(err);
|
|
});
|
|
st.pipe(wstream);
|
|
return d.promise;
|
|
}
|
|
// Return a promise resolved with a boolean
|
|
function fileExists(filename) {
|
|
const d = promise_1.default.defer();
|
|
fs_1.default.stat(filename, (error) => {
|
|
if (error) {
|
|
d.resolve(false);
|
|
}
|
|
else {
|
|
d.resolve(true);
|
|
}
|
|
});
|
|
return d.promise;
|
|
}
|
|
// Generate temporary file
|
|
function genTmpFile(opts) {
|
|
return promise_1.default.nfcall(tmp_1.default.file, opts).get(0);
|
|
}
|
|
/**
|
|
* Generate temporary dir
|
|
* @deprecated use tmpdir.ts
|
|
* @param opts
|
|
*/
|
|
function genTmpDir(opts) {
|
|
return promise_1.default.nfcall(tmp_1.default.dir, opts).get(0);
|
|
}
|
|
// https://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js-without-using-third-party-libraries
|
|
const downloadStream = (url, dest, cb) => {
|
|
const file = fs_1.default.createWriteStream(dest);
|
|
const protocol = url.startsWith("https") ? https_1.default : http_1.default;
|
|
const request = protocol.get(url, (response) => {
|
|
// check if response is success
|
|
if (response.statusCode < 200 && response.statusCode > 300) {
|
|
return cb(new Error("Response status was " + response.statusCode));
|
|
}
|
|
response.pipe(file);
|
|
});
|
|
// close() is async, call cb after close completes
|
|
file.on("finish", () => file.close(() => cb(null)));
|
|
// check for request error too
|
|
request.on("error", (err) => {
|
|
fs_1.default.unlink(dest, () => cb(err)); // delete the (partial) file and then return the error
|
|
});
|
|
file.on("error", (err) => {
|
|
// Handle errors
|
|
fs_1.default.unlink(dest, () => cb(err)); // delete the (partial) file and then return the error
|
|
});
|
|
};
|
|
// Download an image
|
|
async function download(uri, destFilePath) {
|
|
// create dest dir if not exists
|
|
const destDir = path_1.default.dirname(destFilePath);
|
|
await fs_1.default.promises.mkdir(destDir, { recursive: true });
|
|
const d = promise_1.default.defer();
|
|
downloadStream(uri, destFilePath, (err) => {
|
|
if (err) {
|
|
d.reject(err);
|
|
}
|
|
else {
|
|
d.resolve();
|
|
}
|
|
});
|
|
return d.promise;
|
|
}
|
|
// Find a filename available in a folder
|
|
function uniqueFilename(base, filename) {
|
|
const ext = path_1.default.extname(filename);
|
|
filename = path_1.default.resolve(base, filename);
|
|
filename = path_1.default.join(path_1.default.dirname(filename), path_1.default.basename(filename, ext));
|
|
let _filename = filename + ext;
|
|
let i = 0;
|
|
while (fs_1.default.existsSync(filename)) {
|
|
_filename = `${filename}_${i}${ext}`;
|
|
i = i + 1;
|
|
}
|
|
return (0, promise_1.default)(path_1.default.relative(base, _filename));
|
|
}
|
|
// Create all required folder to create a file
|
|
function ensureFile(filename) {
|
|
const base = path_1.default.dirname(filename);
|
|
return (0, promise_1.default)((0, mkdirp_1.default)(base));
|
|
}
|
|
// Remove a folder
|
|
function rmDir(base) {
|
|
return promise_1.default.nfcall(fs_1.default.rm, base, {
|
|
recursive: true
|
|
});
|
|
}
|
|
/**
|
|
Assert a file, if it doesn't exist, call "generator"
|
|
|
|
@param {string} filePath
|
|
@param {Function} generator
|
|
@return {Promise}
|
|
*/
|
|
function assertFile(filePath, generator) {
|
|
return fileExists(filePath).then((exists) => {
|
|
if (exists)
|
|
return;
|
|
return generator();
|
|
});
|
|
}
|
|
/**
|
|
Pick a file, returns the absolute path if exists, undefined otherwise
|
|
|
|
@param {string} rootFolder
|
|
@param {string} fileName
|
|
@return {string}
|
|
*/
|
|
function pickFile(rootFolder, fileName) {
|
|
const result = path_1.default.join(rootFolder, fileName);
|
|
if (fs_1.default.existsSync(result)) {
|
|
return result;
|
|
}
|
|
return undefined;
|
|
}
|
|
/**
|
|
Ensure that a directory exists and is empty
|
|
|
|
@param {string} folder
|
|
@return {Promise}
|
|
*/
|
|
function ensureFolder(rootFolder) {
|
|
return rmDir(rootFolder)
|
|
.fail(() => {
|
|
return (0, promise_1.default)();
|
|
})
|
|
.then(() => {
|
|
return (0, promise_1.default)((0, mkdirp_1.default)(rootFolder));
|
|
});
|
|
}
|
|
exports.default = {
|
|
exists: fileExists,
|
|
existsSync: fs_1.default.existsSync,
|
|
mkdirp: mkdirp_1.default,
|
|
readFile: promise_1.default.nfbind(fs_1.default.readFile),
|
|
writeFile: (filePath, content) => {
|
|
const d = promise_1.default.defer();
|
|
fs_1.default.writeFile(filePath, content, (error) => {
|
|
if (error) {
|
|
d.reject(error);
|
|
}
|
|
else {
|
|
d.resolve();
|
|
}
|
|
});
|
|
return d.promise;
|
|
},
|
|
assertFile: assertFile,
|
|
pickFile: pickFile,
|
|
stat: promise_1.default.nfbind(fs_1.default.lstat),
|
|
statSync: fs_1.default.lstatSync,
|
|
readdir: promise_1.default.nfbind(fs_1.default.readdir),
|
|
writeStream: writeStream,
|
|
readStream: fs_1.default.createReadStream,
|
|
copy: promise_1.default.nfbind(cp_1.default),
|
|
copyDir: promise_1.default.nfbind(cpr_1.default),
|
|
tmpFile: genTmpFile,
|
|
/**
|
|
* @deprecated use tmpdir.ts
|
|
*/
|
|
tmpDir: genTmpDir,
|
|
download: download,
|
|
uniqueFilename: uniqueFilename,
|
|
ensureFile: ensureFile,
|
|
ensureFolder: ensureFolder,
|
|
rmDir: rmDir
|
|
};
|