smartarchive/ts/classes.tartools.ts

128 lines
4.4 KiB
TypeScript
Raw Permalink Normal View History

2023-11-06 17:14:21 +00:00
import type { SmartArchive } from './classes.smartarchive.js';
import * as plugins from './plugins.js';
export class TarTools {
2024-06-08 08:30:03 +00:00
// INSTANCE
2024-06-08 10:44:40 +00:00
constructor() {}
2024-06-08 08:30:03 +00:00
2023-11-06 17:14:21 +00:00
// packing
2024-06-08 08:30:03 +00:00
public async addFileToPack(
pack: plugins.tarStream.Pack,
optionsArg: {
fileName?: string;
content?:
| string
| Buffer
| plugins.smartstream.stream.Readable
| plugins.smartfile.SmartFile
| plugins.smartfile.StreamFile;
byteLength?: number;
filePath?: string;
}
): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
2024-06-08 12:00:55 +00:00
let fileName: string | null = null;
if (optionsArg.fileName) {
fileName = optionsArg.fileName;
} else if (optionsArg.content instanceof plugins.smartfile.SmartFile) {
fileName = (optionsArg.content as plugins.smartfile.SmartFile).relative;
} else if (optionsArg.content instanceof plugins.smartfile.StreamFile) {
fileName = (optionsArg.content as plugins.smartfile.StreamFile).relativeFilePath;
} else if (optionsArg.filePath) {
fileName = optionsArg.filePath;
}
2024-06-08 08:30:03 +00:00
/**
* contentByteLength is used to set the size of the entry in the tar file
*/
let contentByteLength: number;
if (optionsArg.byteLength) {
contentByteLength = optionsArg.byteLength;
} else if (typeof optionsArg.content === 'string') {
contentByteLength = Buffer.byteLength(optionsArg.content, 'utf8');
} else if (Buffer.isBuffer(optionsArg.content)) {
contentByteLength = optionsArg.content.length;
} else if (optionsArg.content instanceof plugins.smartfile.SmartFile) {
contentByteLength = await optionsArg.content.getSize(); // assuming SmartFile has getSize method
} else if (optionsArg.content instanceof plugins.smartfile.StreamFile) {
contentByteLength = await optionsArg.content.getSize(); // assuming StreamFile has getSize method
} else if (optionsArg.content instanceof plugins.smartstream.stream.Readable) {
console.warn(
'@push.rocks/smartarchive: When streaming, it is recommended to provide byteLength, if known.'
);
} else if (optionsArg.filePath) {
const fileStat = await plugins.smartfile.fs.stat(optionsArg.filePath);
contentByteLength = fileStat.size;
}
2024-06-08 09:01:56 +00:00
/**
* here we try to harmonize all kind of entries towards a readable stream
*/
let content: plugins.smartstream.stream.Readable;
if (Buffer.isBuffer(optionsArg.content)) {
content = plugins.smartstream.stream.Readable.from(optionsArg.content);
} else if (typeof optionsArg.content === 'string') {
content = plugins.smartstream.stream.Readable.from(Buffer.from(optionsArg.content));
} else if (optionsArg.content instanceof plugins.smartfile.SmartFile) {
content = plugins.smartstream.stream.Readable.from(optionsArg.content.contents);
} else if (optionsArg.content instanceof plugins.smartfile.StreamFile) {
content = await optionsArg.content.createReadStream();
} else if (optionsArg.content instanceof plugins.smartstream.stream.Readable) {
content = optionsArg.content;
}
2024-06-08 08:30:03 +00:00
const entry = pack.entry(
{
name: fileName,
...(contentByteLength
? {
size: contentByteLength,
}
: null),
},
(err: Error) => {
if (err) {
reject(err);
} else {
resolve();
}
2023-11-06 17:14:21 +00:00
}
2024-06-08 08:30:03 +00:00
);
content.pipe(entry);
2024-06-08 12:48:24 +00:00
resolve();
2023-11-06 17:14:21 +00:00
});
}
2024-06-08 08:30:03 +00:00
/**
* packs a directory from disk into a tar stream
* @param directoryPath
*/
public async packDirectory(directoryPath: string) {
const fileTree = await plugins.smartfile.fs.listFileTree(directoryPath, '**/*');
const pack = await this.getPackStream();
for (const filePath of fileTree) {
const absolutePath = plugins.path.join(directoryPath, filePath);
const fileStat = await plugins.smartfile.fs.stat(absolutePath);
await this.addFileToPack(pack, {
byteLength: fileStat.size,
2024-06-08 11:47:38 +00:00
filePath: absolutePath,
2024-06-08 08:30:03 +00:00
fileName: filePath,
content: plugins.smartfile.fsStream.createReadStream(absolutePath),
});
}
2024-06-08 09:03:37 +00:00
return pack;
2024-06-08 08:30:03 +00:00
}
2023-11-06 17:14:21 +00:00
public async getPackStream() {
const pack = plugins.tarStream.pack();
return pack;
}
// extracting
getDecompressionStream() {
return plugins.tarStream.extract();
}
}