@beenotung/tslib
Version:
utils library in Typescript
195 lines (194 loc) • 6.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.exist = exist;
exports.hasFile = hasFile;
exports.hasDirectory = hasDirectory;
exports.scanRecursively = scanRecursively;
exports.scanRecursivelySync = scanRecursivelySync;
exports.readJsonFile = readJsonFile;
exports.readJsonFileSync = readJsonFileSync;
exports.writeJsonFile = writeJsonFile;
exports.writeJsonFileSync = writeJsonFileSync;
exports.iterateFileByLine = iterateFileByLine;
exports.verboseWriteFileSync = verboseWriteFileSync;
exports.getDirFilenamesSync = getDirFilenamesSync;
exports.getDirFilenames = getDirFilenames;
exports.isMetadataFilename = isMetadataFilename;
const tslib_1 = require("tslib");
const fs = tslib_1.__importStar(require("fs"));
const path = tslib_1.__importStar(require("path"));
const promises_1 = require("fs/promises");
function isNoFileError(e) {
if (e.code === 'ENOENT') {
return true;
}
return Promise.reject(e);
}
function not(e) {
return e === true ? false : e;
}
function exist(filename) {
return (0, promises_1.stat)(filename)
.then(() => true)
.catch(e => not(isNoFileError(e)));
}
function hasFile(filename) {
return (0, promises_1.stat)(filename)
.then(stat => stat.isFile())
.catch(e => not(isNoFileError(e)));
}
function hasDirectory(filename) {
return (0, promises_1.stat)(filename)
.then(stat => stat.isDirectory())
.catch(e => not(isNoFileError(e)));
}
async function scanRecursively(args) {
const { entryPath, onFile, onDir, onComplete, dereferenceSymbolicLinks, skipDir, } = args;
const checkStat = dereferenceSymbolicLinks ? promises_1.stat : promises_1.lstat;
const check = async (pathname, basename) => {
const stat = await checkStat(pathname);
if (stat.isDirectory()) {
if (onDir) {
await onDir(pathname, basename);
}
if (skipDir && skipDir(pathname, basename)) {
return;
}
const names = await (0, promises_1.readdir)(pathname);
for (const basename of names) {
const childPathname = path.join(pathname, basename);
await check(childPathname, basename);
}
return;
}
if (onFile && stat.isFile()) {
await onFile(pathname, basename);
return;
}
};
await check(entryPath, path.basename(entryPath));
if (onComplete) {
await onComplete();
}
}
function scanRecursivelySync(args) {
const { entryPath, onFile, onDir, onComplete, dereferenceSymbolicLinks, skipDir, } = args;
const checkStat = dereferenceSymbolicLinks ? fs.statSync : fs.lstatSync;
const check = (pathname, basename) => {
const stat = checkStat(pathname);
if (stat.isDirectory()) {
if (onDir) {
onDir(pathname, basename);
}
if (skipDir && skipDir(pathname, basename)) {
return;
}
const names = fs.readdirSync(pathname);
for (const basename of names) {
const childPathname = path.join(pathname, basename);
check(childPathname, basename);
}
return;
}
if (onFile && stat.isFile()) {
onFile(pathname, basename);
return;
}
};
check(entryPath, path.basename(entryPath));
if (onComplete) {
onComplete();
}
}
function readJsonFile(file) {
return (0, promises_1.readFile)(file).then(buffer => JSON.parse(buffer.toString()));
}
function readJsonFileSync(file) {
return JSON.parse(fs.readFileSync(file).toString());
}
function writeJsonFile(file, value, options) {
const text = options?.format
? JSON.stringify(value, null, 2)
: JSON.stringify(value);
return (0, promises_1.writeFile)(file, text);
}
function writeJsonFileSync(file, value, options) {
const text = options?.format
? JSON.stringify(value, null, 2)
: JSON.stringify(value);
return fs.writeFileSync(file, text);
}
/**
* linefeed "\n" is omitted from the yielded value
* but "\r" if exists is preserved as is
* */
function* iterateFileByLine(file, options) {
const batchSize = options?.batchSize || 8 * 1024 * 1024;
const encoding = options?.encoding;
const buffer = Buffer.alloc(batchSize);
const fd = fs.openSync(file, 'r');
if (options) {
options.close = () => fs.closeSync(fd);
}
let acc = Buffer.alloc(0);
for (;;) {
const read = fs.readSync(fd, buffer, 0, batchSize, null);
if (read === 0) {
break;
}
acc = Buffer.concat([acc, buffer], acc.length + read);
for (;;) {
const idx = acc.indexOf(10);
if (idx === -1) {
break;
}
const line = acc.slice(0, idx);
yield line.toString(encoding);
acc = acc.slice(idx + 1);
}
}
if (acc.length > 0) {
yield acc.toString(encoding);
}
fs.closeSync(fd);
}
function verboseWriteFileSync(file, content) {
fs.writeFileSync(file, content);
// eslint-disable-next-line no-console
console.log('saved to', file);
}
/**
* @description skip metadata files, e.g. .DS_Store
*/
function getDirFilenamesSync(dir) {
const filenames = fs.readdirSync(dir);
return filenames.filter(filename => !isMetadataFilename(filename));
}
/**
* @description skip metadata files, e.g. .DS_Store
*/
async function getDirFilenames(dir) {
const filenames = await (0, promises_1.readdir)(dir);
return filenames.filter(filename => !isMetadataFilename(filename));
}
/**
* @description check for metadata files, e.g. .DS_Store, *.swp, *.swo, .~lock.*#, *.ext~
*/
function isMetadataFilename(filename) {
switch (filename) {
case '.DS_Store':
return true;
}
const ext = path.extname(filename);
switch (ext) {
case '.swp':
case '.swo':
case '.orig':
return true;
}
// libreoffice lock file
if (filename.startsWith('.~lock.') && filename.endsWith('#')) {
return true;
}
return false;
}