gzipper
Version:
CLI for compressing files.
175 lines • 12.7 kB
JavaScript
import { createReadStream } from 'node:fs';
import { lstat, readdir, unlink, rmdir } from 'node:fs/promises';
import crypto from 'node:crypto';
import path from 'node:path';
import { isDeepStrictEqual as deepEqual } from 'node:util';
import { CACHE_FOLDER, CONFIG_FOLDER } from './constants.js';
import { mapToJSON, checkFileExists, createFolders } from './helpers.js';
export class Incremental {
_cacheFolder;
_filePaths = new Map();
config;
get cacheFolder() {
return this._cacheFolder;
}
get filePaths() {
return Object.fromEntries(this._filePaths);
}
set filePaths(value) {
this._filePaths = new Map(Object.entries(value));
}
/**
* Creates an instance of Incremental.
*/
constructor(config) {
if (config) {
this.config = config;
}
this._cacheFolder = path.resolve(process.cwd(), CONFIG_FOLDER, CACHE_FOLDER);
}
/**
* Read config (.gzipperconfig).
*/
async readConfig() {
const incrementalConfig = this.config.configContent.incremental;
if (incrementalConfig) {
this._filePaths = new Map(Object.entries(incrementalConfig.files));
}
}
/**
* update config (.gzipperconfig).
*/
async updateConfig() {
this.config.setProperty('incremental', {
files: mapToJSON(this._filePaths),
});
}
/**
* Create cache folder (.gzipper).
*/
async initCacheFolder() {
if (!(await checkFileExists(this._cacheFolder))) {
await createFolders(this._cacheFolder);
}
}
/**
* Returns file incremental info and save checksum and options to `filePath` (if file is changed or newly created).
*/
setFile(target, checksum, compressionType, compressOptions) {
const filePath = this._filePaths.get(target);
const selectedRevision = filePath?.revisions.find((revision) => compressionType === revision.compressionType &&
deepEqual(revision.options, compressOptions));
if (!filePath) {
const fileId = crypto.randomUUID();
this._filePaths.set(target, {
revisions: [
{
lastChecksum: checksum,
fileId,
date: new Date(),
compressionType,
options: compressOptions,
},
],
});
return {
isChanged: true,
fileId,
};
}
if (!selectedRevision) {
const fileId = crypto.randomUUID();
this._filePaths.set(target, {
revisions: filePath.revisions.concat({
lastChecksum: checksum,
fileId,
date: new Date(),
compressionType,
options: compressOptions,
}),
});
return {
isChanged: true,
fileId,
};
}
if (selectedRevision.lastChecksum !== checksum) {
this._filePaths.set(target, {
revisions: filePath.revisions.map((revision) => {
return revision.fileId === selectedRevision.fileId
? { ...revision, date: new Date(), lastChecksum: checksum }
: revision;
}),
});
return {
isChanged: true,
fileId: selectedRevision.fileId,
};
}
return {
isChanged: false,
fileId: selectedRevision.fileId,
};
}
/**
* Returns file checksum.
*/
async getFileChecksum(target) {
const hash = crypto.createHash('md5');
const stream = createReadStream(target);
return new Promise((resolve, reject) => {
stream.on('data', (data) => hash.update(data.toString(), 'utf8'));
stream.on('end', () => resolve(hash.digest('hex')));
stream.on('error', (error) => reject(error));
});
}
/**
* Purge cache folder.
*/
async cachePurge() {
if (!(await checkFileExists(this._cacheFolder))) {
throw new Error('No cache found.');
}
const recursiveRemove = async (folderPath = this._cacheFolder) => {
const files = await readdir(folderPath);
for (const file of files) {
const filePath = path.resolve(folderPath, file);
const isDirectory = (await lstat(filePath)).isDirectory();
if (isDirectory) {
await recursiveRemove(filePath);
}
else {
await unlink(filePath);
}
}
await rmdir(folderPath);
};
await recursiveRemove();
this.config.deleteProperty('incremental');
await this.config.writeConfig();
}
/**
* Returns cache size.
*/
async cacheSize(folderPath = this._cacheFolder, size = 0) {
if (!(await checkFileExists(this._cacheFolder))) {
throw new Error('No cache found.');
}
const files = await readdir(folderPath);
if (!files.length) {
return 0;
}
for (const file of files) {
const filePath = path.resolve(folderPath, file);
const fileStat = await lstat(filePath);
if (fileStat.isDirectory()) {
size += await this.cacheSize(filePath, size);
}
else if (fileStat.isFile()) {
size += fileStat.size;
}
}
return size;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5jcmVtZW50YWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvSW5jcmVtZW50YWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQzdCLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFM0QsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFJekUsTUFBTSxPQUFPLFdBQVc7SUFDTCxZQUFZLENBQVM7SUFDOUIsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFnQyxDQUFDO0lBQ3BELE1BQU0sQ0FBVTtJQUV6QixJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQUksU0FBUztRQUNYLE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELElBQUksU0FBUyxDQUFDLEtBQTJDO1FBQ3ZELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNILFlBQVksTUFBZTtRQUN6QixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDdkIsQ0FB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