Skip to content

Instantly share code, notes, and snippets.

@ndesmic
Last active January 10, 2023 15:17
Show Gist options
  • Save ndesmic/d9016270efc371111c34fa1d05b2e856 to your computer and use it in GitHub Desktop.
Save ndesmic/d9016270efc371111c34fa1d05b2e856 to your computer and use it in GitHub Desktop.
node tools
async function directoryToObject(dir, walkOpts){
const obj = {};
for await(const file of walk(dir, walkOpts)){
const path = relative(dir, file.path);
const split = path.split("/");
let currObj = obj;
for(let i = 0; i < split.length; i++){
const part = split[i];
if(i === split.length - 1){
currObj[part] = await Deno.readTextFile(file.path);
} else if(currObj[part] === undefined){
currObj[part] = {};
}
currObj = currObj[part];
}
}
return obj;
}
async function asyncIterToArray(asyncIter){
const value = [];
for await(const val of asyncIter){
value.push(val);
}
return value;
}
import { promises as fs } from "fs";
import { dirname, resolve } from "path";
export function getNodeModuleDir(packageName: string){
return dirname(require.resolve(resolve(packageName, "package.json")));
}
export const exists = path =>
fs.access(path).then(() => true).catch(() => false);
export async function ensure(path){
const pathSplit = path.split("/");
let currentPath = pathSplit[0];
for await(let part of pathSplit.slice(1, pathSplit.length - 1)){
currentPath = currentPath + "/" + part;
if(!await exists(currentPath)){
await fs.mkdir(currentPath);
}
}
}
export async function rmrf(path){
if(await exists(path)) {
const files = await fs.readdir(path);
for (let file of files){
const currentPath = path + "/" + file;
if(await fs.lstat(currentPath).isDirectory()) {
rmrf(currentPath);
} else { // delete file
await fs.unlink(currentPath);
}
}
await fs.rmdir(path);
}
}
export const readJson = async path => {
const text = await fs.readFile(path, "utf-8");
return JSON.parse(text);
}
export const writeJson = async (path, data) => {
const json = JSON.stringify(data, null, 4);
await fs.writeFile(path, json, "utf-8");
}
export const ensureWrite = async (path, content) =>
ensure(path)
.then(() => fs.writeFile(path, content));
export async function listDirectoryRecursive(dir) {
if(!(await fs.lstat(dir)).isDirectory()){
return [dir];
}
const files = await fs.readdir(dir);
const results = [];
for(let file of files){
results.push(...(await listDirectoryRecursive(resolve(dir, file))));
}
return results.flat(Infinity);
}
export async function mapDirectoryRecursive(dir){
if(!(await lstat(dir)).isDirectory()){
return dir;
}
const files = await readdir(dir);
const results = {};
for (let file of files){
results[file] = await mapDirectoryRecursive(resolve(dir, file));
}
return results;
}
export async function findFile(dir, regex = /.*/, maxDepth = Infinity) {
if(!(await fs.lstat(dir)).isDirectory() && regex.test(dir)){
return [dir];
}
if(maxDepth === 0){
return [];
}
const files = await fs.readdir(dir);
const results = [];
for(let file of files){
results.push(...(await findFile(resolve(dir, file), regex, maxDepth - 1)));
}
return results.flat(maxDepth);
}
export function mapTree(tree, mapFunc){
return Object.fromEntries(Object.entries(tree).map(([key, value]) =>
typeof(value) === "object"
? mapTree(value, mapFunc)
: mapFunc(value)));
}
//plain objects only!
export async function asyncTreeAll(tree){
const promisesToResolve = [];
const promiseToIndex = new WeakMap();
const entries = Object.entries(tree);
for (const [key, value] of entries){
if(value instanceof Promise){
promiseToIndex.set(value, promisesToResolve.length);
promisesToResolve.push(value);
} else if (typeof(value) === "object"){
promiseToIndex.set(value, promisesToResolve.length);
promisesToResolve.push(asyncTreeAll(value));
}
}
const results = await Promise.all(promisesToResolve);
const resolvedEntries = [];
for (const [key, value] of entries){
if(value instanceof Promise || typeof(value) === "object"){
const index = promiseToIndex.get(value);
resolvedEntries.push([key, results[index]]);
} else {
resolvedEntries.push([key, value]);
}
}
return Object.fromEntries(resolvedEntries);
}
export function filterTree(tree, filterFunc){
return Object.fromEntries(Object.entries(tree).flatMap(([key, value]) => {
if(typeof(value) === "object"){
const newValue = filterTree(value, filterFunc);
if(Object.keys(newValue).length > 0){
return [key, newValue];
} else {
return [];
}
} else {
if(filterFunc(value)){
return [key, value];
} else {
return [];
}
}
}));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment