UNPKG

@push.rocks/smartfile

Version:

Provides comprehensive tools for efficient file management in Node.js using TypeScript, including handling streams, virtual directories, and various file operations.

294 lines 19.8 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import * as plugins from './plugins.js'; import * as fs from './fs.js'; import * as memory from './memory.js'; /** * an vinyl file compatible in memory file class */ export class SmartFile extends plugins.smartjson.Smartjson { // ====== // STATIC // ====== /** * creates a Smartfile from a filePath * @param filePath */ static async fromFilePath(filePath, baseArg = process.cwd()) { filePath = plugins.path.resolve(filePath); const fileBuffer = fs.toBufferSync(filePath); const smartfile = new SmartFile({ contentBuffer: fileBuffer, base: baseArg, path: plugins.path.relative(baseArg, filePath), }); return smartfile; } static async fromBuffer(filePath, contentBufferArg, baseArg = process.cwd()) { const smartfile = new SmartFile({ contentBuffer: contentBufferArg, base: baseArg, path: plugins.path.relative(baseArg, filePath), }); return smartfile; } static async fromString(filePath, contentStringArg, encodingArg, baseArg = process.cwd()) { const smartfile = new SmartFile({ contentBuffer: Buffer.from(contentStringArg, encodingArg), base: baseArg, path: plugins.path.relative(baseArg, filePath), }); return smartfile; } static async fromFoldedJson(foldedJsonArg) { return new SmartFile(plugins.smartjson.parse(foldedJsonArg)); } /** * creates a Smartfile from a ReadableStream * @param stream a readable stream that provides file content * @param filePath the file path to associate with the content * @param baseArg the base path to use for the file */ static async fromStream(stream, filePath, baseArg = process.cwd()) { return new Promise((resolve, reject) => { const chunks = []; stream.on('data', (chunk) => chunks.push(Buffer.from(chunk))); stream.on('error', (error) => reject(error)); stream.on('end', () => { const contentBuffer = Buffer.concat(chunks); const smartfile = new SmartFile({ contentBuffer: contentBuffer, base: baseArg, path: plugins.path.relative(baseArg, filePath), }); resolve(smartfile); }); }); } static async fromUrl(urlArg) { const response = await plugins.smartrequest.getBinary(urlArg); const smartfile = await SmartFile.fromBuffer(urlArg, response.body); return smartfile; } /** * a parsed path */ get parsedPath() { return plugins.path.parse(this.path); } get absolutePath() { return plugins.path.join(this.base, this.path); } get absoluteParsedPath() { return plugins.path.parse(this.absolutePath); } /** * the constructor of Smartfile * @param optionsArg */ constructor(optionsArg) { super(); if (optionsArg.contentBuffer) { this.contentBuffer = optionsArg.contentBuffer; } else { console.log('created empty Smartfile?'); } this.path = optionsArg.path; this.base = optionsArg.base; } /** * set contents from string * @param contentString */ setContentsFromString(contentString, encodingArg = 'utf8') { this.contents = Buffer.from(contentString, encodingArg); } /** * write file to disk at its original location * Behaviours: * - no argument write to exactly where the file was picked up */ async write() { let writePath = plugins.smartpath.transform.makeAbsolute(this.path, this.base); console.log(`writing to ${writePath}`); await memory.toFs(this.contentBuffer, writePath); } /** * writes the file to path given as argument * note: if the path is not absolute, takes process.cwd() as base * @param filePathArg */ async writeToDiskAtPath(filePathArg) { if (!plugins.path.isAbsolute(filePathArg)) { filePathArg = plugins.path.join(process.cwd(), filePathArg); } await memory.toFs(this.contentBuffer, filePathArg); } /** * writes the file to a directory combined with the relative path portion * @param dirPathArg * @returns */ async writeToDir(dirPathArg) { dirPathArg = plugins.smartpath.transform.toAbsolute(dirPathArg); const filePath = plugins.path.join(dirPathArg, this.path); await memory.toFs(this.contentBuffer, filePath); return filePath; } /** * read file from disk */ async read() { this.contentBuffer = await fs.toBuffer(plugins.path.join(this.base, this.path)); } /** * deletes the file from disk at its original location */ async delete() { await fs.remove(plugins.path.join(this.base, this.path)); } /** * Renames the file to the specified new name. * - Updates the `path` property with the new name. * - Writes the file to the new location if it exists on disk. * @param newName The new name of the file (including extension if applicable). * @param writeToDisk (optional) If true, also renames the file on the disk. * @returns The updated file path after renaming. */ async rename(newName, writeToDisk = false) { // Validate the new name if (!newName || typeof newName !== 'string') { throw new Error('Invalid new name provided.'); } // Extract the directory path const oldFilePath = this.path; const dirPath = plugins.path.dirname(this.path); // Create the new file path const newFilePath = plugins.path.join(dirPath, newName); // Update the `path` property this.path = newFilePath; // Optionally write the renamed file to disk if (writeToDisk) { const oldAbsolutePath = plugins.smartpath.transform.makeAbsolute(oldFilePath, this.base); const newAbsolutePath = plugins.smartpath.transform.makeAbsolute(newFilePath, this.base); // Rename the file on disk await plugins.fsExtra.rename(oldAbsolutePath, newAbsolutePath); } // Return the new path return this.path; } // ----------------------------------------------- // vinyl compatibility // ----------------------------------------------- /** * vinyl-compatibility: alias of this.contentBuffer */ get contents() { return this.contentBuffer; } set contents(contentsArg) { this.contentBuffer = contentsArg; } /** * vinyl-compatibility */ get cwd() { return process.cwd(); } /** * return relative path of file */ get relative() { return this.path; } /** * return truw when the file has content */ isNull() { if (!this.contentBuffer) { return true; } return false; } /** * return true if contents are Buffer */ isBuffer() { if (this.contents instanceof Buffer) { return true; } return false; } isDirectory() { return false; } isStream() { return false; } isSymbolic() { return false; } async getHash(typeArg = 'all') { const pathHash = await plugins.smarthash.sha256FromString(this.path); const contentHash = await plugins.smarthash.sha256FromBuffer(this.contentBuffer); const combinedHash = await plugins.smarthash.sha256FromString(pathHash + contentHash); switch (typeArg) { case 'path': return pathHash; case 'content': return contentHash; case 'all': default: return combinedHash; } } // update things updateFileName(fileNameArg) { const oldFileName = this.parsedPath.base; this.path = this.path.replace(new RegExp(oldFileName + '$'), fileNameArg); } async editContentAsString(editFuncArg) { const newFileString = await editFuncArg(this.contentBuffer.toString()); this.contentBuffer = Buffer.from(newFileString); } /** * Returns a ReadableStream from the file's content buffer */ getStream() { const stream = new plugins.stream.Readable(); stream.push(this.contentBuffer); // Push the content buffer to the stream stream.push(null); // Push null to signify the end of the stream (EOF) return stream; } /** * Returns the size of the file in bytes */ async getSize() { return this.contentBuffer.length; } } __decorate([ plugins.smartjson.foldDec(), __metadata("design:type", String) ], SmartFile.prototype, "path", void 0); __decorate([ plugins.smartjson.foldDec(), __metadata("design:type", Buffer) ], SmartFile.prototype, "contentBuffer", void 0); __decorate([ plugins.smartjson.foldDec(), __metadata("design:type", String) ], SmartFile.prototype, "base", void 0); __decorate([ plugins.smartjson.foldDec(), __metadata("design:type", Boolean) ], SmartFile.prototype, "sync", void 0); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zbWFydGZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNtYXJ0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQVF0Qzs7R0FFRztBQUNILE1BQU0sT0FBTyxTQUFVLFNBQVEsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTO0lBQ3hELFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztJQUVUOzs7T0FHRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFFBQWdCLEVBQUUsVUFBa0IsT0FBTyxDQUFDLEdBQUcsRUFBRTtRQUNoRixRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsQ0FBQztZQUM5QixhQUFhLEVBQUUsVUFBVTtZQUN6QixJQUFJLEVBQUUsT0FBTztZQUNiLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDO1NBQy9DLENBQUMsQ0FBQztRQUNILE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FDNUIsUUFBZ0IsRUFDaEIsZ0JBQXdCLEVBQ3hCLFVBQWtCLE9BQU8sQ0FBQyxHQUFHLEVBQUU7UUFFL0IsTUFBTSxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQUM7WUFDOUIsYUFBYSxFQUFFLGdCQUFnQjtZQUMvQixJQUFJLEVBQUUsT0FBTztZQUNiLElBQUks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