128 lines
4.4 KiB
TypeScript
128 lines
4.4 KiB
TypeScript
import type { SmartArchive } from './classes.smartarchive.js';
|
|
import * as plugins from './plugins.js';
|
|
|
|
export class TarTools {
|
|
// INSTANCE
|
|
constructor() {}
|
|
|
|
// packing
|
|
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) => {
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
const entry = pack.entry(
|
|
{
|
|
name: fileName,
|
|
...(contentByteLength
|
|
? {
|
|
size: contentByteLength,
|
|
}
|
|
: null),
|
|
},
|
|
(err: Error) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve();
|
|
}
|
|
}
|
|
);
|
|
|
|
content.pipe(entry);
|
|
resolve();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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,
|
|
filePath: absolutePath,
|
|
fileName: filePath,
|
|
content: plugins.smartfile.fsStream.createReadStream(absolutePath),
|
|
});
|
|
}
|
|
return pack;
|
|
}
|
|
|
|
public async getPackStream() {
|
|
const pack = plugins.tarStream.pack();
|
|
return pack;
|
|
}
|
|
|
|
// extracting
|
|
getDecompressionStream() {
|
|
return plugins.tarStream.extract();
|
|
}
|
|
}
|