import path from "node:path"; import fs from "node:fs"; import process from "node:process"; import type { FileService, NamedWritableStream, TxtEnDecoder } from "@adviser/cement"; export class NodeFileService implements FileService { readonly baseDir: string; readonly defTxtEnde: TxtEnDecoder; constructor(defTxtEncode: TxtEnDecoder, baseDir: string = process.cwd()) { this.baseDir = this.abs(baseDir); this.defTxtEnde = defTxtEncode; } // nodeImport(fname: string): string { // // console.log('nodeImport:'+ fname); // if (path.isAbsolute(fname)) { // return fname; // } else { // return "./" + path.normalize(fname); // } // } readFileString(fname: string): Promise { return fs.promises.readFile(fname, { encoding: "utf-8" }); } dirname(fname: string): string { return path.dirname(fname); } basename(fname: string): string { return path.basename(fname); } join(...paths: string[]): string { return path.join(...paths); } relative(from: string, to?: string): string { if (to === undefined) { to = from; from = process.cwd(); } const ret = path.relative(from, to); // console.log('relative:'+ from + " -> " + to + "= " + ret); return ret; } abs(fname: string): string { if (path.isAbsolute(fname)) { return fname; } else { const cwd = process.cwd(); return path.resolve(cwd, fname); } } isAbsolute(fname: string): boolean { return path.isAbsolute(fname); } async writeFileString(fname: string, content: string, ende: TxtEnDecoder = this.defTxtEnde): Promise { const o = await this.create(fname); const wr = o.stream.getWriter(); await wr.write(ende.encode(content)); await wr.close(); } async create(fname: string): Promise { let oName = fname; if (!path.isAbsolute(fname)) { oName = this.abs(fname); } const base = path.dirname(oName); await fs.promises.mkdir(base, { recursive: true }); const out = fs.createWriteStream(oName); return { name: oName, stream: new WritableStream({ write(chunk): void { out.write(chunk); }, close(): void { out.close(); }, abort(): void { throw new Error("not implemented"); }, }), }; } }