walk.js/create.js

77 lines
1.8 KiB
JavaScript
Raw Normal View History

2020-12-09 11:10:56 +00:00
// a port of Go's filepath.Walk
import { promises as fs } from "fs";
2020-12-09 11:48:55 +00:00
import Walk from "./walk.js";
2020-12-09 11:10:56 +00:00
import path from "path";
var _withFileTypes = { withFileTypes: true };
var _noopts = {};
function pass(err) {
return err;
}
2020-12-09 11:48:55 +00:00
Walk.create = function (opts) {
if (!opts) {
opts = _noopts;
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
// a port of Go's filepath.Walk
const _walk = async (pathname, walkFunc, _dirent) => {
let err;
2020-12-09 11:10:56 +00:00
2020-12-09 11:48:55 +00:00
// special case of the very first run
if (!_dirent) {
_dirent = pathname;
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
// the first run, or if false === withFileTypes
if ("string" === typeof _dirent) {
let _name = path.basename(path.resolve(pathname));
_dirent = await fs.lstat(pathname).catch(pass);
if (_dirent instanceof Error) {
err = _dirent;
} else {
_dirent.name = _name;
}
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
// run the user-supplied function and either skip, bail, or continue
err = await walkFunc(err, pathname, _dirent).catch(pass);
if (false === err || Walk.skipDir === err) {
2020-12-09 11:10:56 +00:00
return;
}
2020-12-09 11:48:55 +00:00
if (err instanceof Error) {
throw err;
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
// "walk does not follow symbolic links"
if (!_dirent || !_dirent.isDirectory()) {
return;
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
// lightweight dirents or full lstat
let _readdirOpts;
if (!opts.withFileStats) {
_readdirOpts = _withFileTypes;
}
2020-12-09 11:10:56 +00:00
2020-12-09 11:48:55 +00:00
// TODO check if the error is "not a directory"
// (and thus allow false === opts.withFileTypes)
let result = await fs.readdir(pathname, _readdirOpts).catch(pass);
if (result instanceof Error) {
return walkFunc(result, pathname, _dirent);
2020-12-09 11:10:56 +00:00
}
2020-12-09 11:48:55 +00:00
if (opts.sort) {
result = opts.sort(result);
}
for (let entity of result) {
await _walk(path.join(pathname, entity.name || entity), walkFunc, entity);
}
};
2020-12-09 11:10:56 +00:00
return _walk;
};
export default Walk;