import fs from "fs"; import path from "path"; import * as util from "util"; export async function sleep(ms: number): Promise { return await new Promise(resolve => { setTimeout(() => resolve(), ms); }); } export abstract class WrappingError extends Error { public readonly cause?: Error; protected constructor(message: string, cause?: Error) { super(message); this.cause = cause; if (cause !== undefined) { this.stack = (this.stack || '') + `\n> Caused by: ${cause.stack}`; } } public get name(): string { return this.constructor.name; } } export type Type = { new(...args: never[]): T }; export function bufferToUuid(buffer: Buffer): string { const chars = buffer.toString('hex'); let out = ''; let i = 0; for (const l of [8, 4, 4, 4, 12]) { if (i > 0) out += '-'; out += chars.substr(i, l); i += l; } return out; } export function getMethods(obj: T): string[] { const properties = new Set(); let currentObj: T | unknown = obj; do { Object.getOwnPropertyNames(currentObj).map(item => properties.add(item)); currentObj = Object.getPrototypeOf(currentObj); } while (currentObj); return [...properties.keys()].filter(item => typeof obj[item] === 'function'); } export const afs = { readFile: util.promisify(fs.readFile), writeFile: util.promisify(fs.writeFile), mkdir: util.promisify(fs.mkdir), readdir: util.promisify(fs.readdir), exists: async (file: string): Promise => await new Promise((resolve, reject) => fs.stat(file, (err) => { if (err == null) { resolve(true); } else if (err.code === 'ENOENT') { resolve(false); } else { reject(err); } })), }; export async function readdirRecursively(dir: string, consumer: (file: string) => Promise): Promise { const files = await afs.readdir(dir); await Promise.all(files.map(file => new Promise((resolve, reject) => { file = path.join(dir, file); fs.stat(file, (err, stat) => { if (err) return reject(err); if (stat.isDirectory()) { resolve(readdirRecursively(file, consumer)); } else { resolve(consumer(file)); } }); }))); }