@enspirit/emb
Version:
A replacement for our Makefile-for-monorepos
87 lines (86 loc) • 2.67 kB
JavaScript
import { constants, createReadStream, createWriteStream } from 'node:fs';
import { access, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
import { dirname, join, normalize } from 'node:path';
/**
* A first implementation of a "store" where
* everyone can create things (logs, sentinel files, ...)
*
* For now it's a hidden folder on the root of the monorepo
*/
export class EMBStore {
monorepo;
path;
constructor(monorepo, dirname) {
this.monorepo = monorepo;
// By default, we use the flavor name to build that root of the store
// so that logs and sentinel files for different flavors are keps separate
this.path = this.monorepo.join(dirname || '.emb');
}
async createReadStream(path) {
await this.mkdirp(dirname(path));
return createReadStream(this.join(path));
}
async createWriteStream(path, flags = 'w') {
await this.mkdirp(dirname(path));
return createWriteStream(this.join(path), {
flags: flags ?? 'w',
});
}
async init() {
let exists;
try {
await access(this.path, constants.F_OK);
exists = true;
}
catch {
exists = false;
}
if (exists) {
return;
}
try {
await mkdir(this.path, { recursive: true });
}
catch (error) {
const msg = error instanceof Error ? error.message : error;
throw new Error(`Unable to create the emb store: ${msg}`);
}
}
join(path) {
return join(this.path, this.monorepo.currentFlavor, path);
}
async mkdirp(path) {
// Avoid getting out of the store by ensuring nothing goes past ../
const normalized = normalize(join('/', path));
await mkdir(this.join(normalized), { recursive: true });
}
async stat(path, mustExist = true) {
try {
return await stat(this.join(path));
}
catch (error) {
if (error.code === 'ENOENT' && !mustExist) {
return;
}
throw error;
}
}
async readFile(path, mustExist = true) {
try {
return (await readFile(this.join(path))).toString();
}
catch (error) {
if (error.code === 'ENOENT' && !mustExist) {
return;
}
throw error;
}
}
async trash() {
return rm(this.path, { force: true, recursive: true });
}
async writeFile(path, data) {
await this.mkdirp(dirname(path));
return writeFile(this.join(path), data);
}
}