extractify.zip/composables/files-manager.ts

112 lines
4.7 KiB
TypeScript
Raw Permalink Normal View History

// class to load 7zip wasm module
// and extract files from archive
import * as Comlink from "comlink";
// @ts-expect-error typescript can't find it when query it with ?worker
import SevenZipWorker from "./worker/7zip-manager?worker";
import { SevenZipManager, iFile } from "./worker/7zip-manager";
import mime from 'mime';
export const videoExtensions = ['mp4', 'avi', 'mov', 'mkv'];
export const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
export const audioExtensions = ['mp3', 'wav', 'ogg', 'flac'];
2024-11-04 09:12:02 +03:00
export const textExtensions = ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'md', 'js', 'ts', 'php', 'c', 'cpp', 'py', 'html', 'css', 'scss', 'sass', 'less', 'json', 'xml', 'sql', 'java', 'go', 'rb', 'sh', 'bat', 'ps1', 'cmd', 'yml', 'yaml', 'ini', 'toml', 'csv', 'tsv', 'gitignore', 'lock', 'htaccess', 'htpasswd', 'env', 'dockerfile', 'gitattributes', 'gitmodules', 'editorconfig', 'babelrc', 'eslintrc', 'eslintignore', 'prettierrc', 'prettierignore', 'stylelintrc', 'stylelintignore', 'postcssrc', 'postcss.config', 'jsx', 'tsx', 'license'];
export const binaryExtensions = ['exe', 'dll', 'so', 'dylib', 'bin', 'dat', 'db', 'sqlite', 'o', 'class', 'pyc'];
2024-11-04 09:44:01 +03:00
export const supportedExtensions = [
'7z', 'xz', 'bz2', 'gz', 'tar', 'zip', 'wim',
'apfs', 'ar', 'arj', 'cab', 'chm', 'cpio', 'dmg', 'ext', 'fat', 'gpt', 'hfs',
'ihex', 'iso', 'lzh', 'lzma', 'mbr', 'msi', 'nsis', 'ntfs', 'qcow2', 'rar',
2024-11-20 13:10:24 +03:00
'rpm', 'squashfs', 'udf', 'uefi', 'vdi', 'vhd', 'vhdx', 'vmdk', 'xar', 'z', 'jar'
2024-11-04 09:44:01 +03:00
];
export class FilesManager {
consoleOutputBuffer: string[] = [];
path: Ref<string> = useSelectedPath();
remoteSevenZipManager?: Comlink.Remote<SevenZipManager>;
constructor(private filesList: Ref<iFile[]>) {
this.init();
}
async init() {
this.remoteSevenZipManager = await new (Comlink.wrap(new SevenZipWorker()) as any);
}
async loadArchive(file: File) {
if (!this.remoteSevenZipManager) return;
2024-11-04 09:44:01 +03:00
const extension = file.name.split('.').pop()?.toLowerCase();
if (!extension || !supportedExtensions.includes(extension)) {
throw new Error('Unsupported file format. Please use a supported archive format.');
}
this.filesList.value = await this.remoteSevenZipManager.loadArchive(file) || [];
}
getFile(path: string, innerList: iFile[] | undefined = undefined): any {
if (path == "/") {
return {
content: this.filesList.value.sort((a: iFile, b: iFile) => {
// sort by folder and from a to z
if (a.isFolder && !b.isFolder) return -1;
if (!a.isFolder && b.isFolder) return 1;
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}),
2023-06-06 03:59:48 +03:00
isFolder: this.filesList.value.length ? true : false,
};
}
for (const file of (innerList || this.filesList.value)) {
if (file.path == path) {
file.content = file.content?.sort((a: iFile, b: iFile) => {
// sort by folder and from a to z
if (a.isFolder && !b.isFolder) return -1;
if (!a.isFolder && b.isFolder) return 1;
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
return file;
}
if (file.isFolder && path.includes(file.path)) {
2023-06-03 06:59:17 +03:00
const recursiveFile = this.getFile(path, file.content);
if (recursiveFile) {
return recursiveFile;
}
}
}
return undefined;
}
async getFileBlobUrl(path: string) {
if (!this.remoteSevenZipManager) return;
return await this.remoteSevenZipManager.generateBlobUrl(JSON.stringify(this.getFile(path)) as any);
}
async getFileContent(path: string, encoding: "utf8" | "binary" = "utf8") {
if (!this.remoteSevenZipManager) return;
return await this.remoteSevenZipManager.getFileContent(JSON.stringify(this.getFile(path)) as any, encoding);
}
async downloadFile(path: string) {
if (!this.remoteSevenZipManager) return;
const file = this.getFile(path);
const fileContent = await this.getFileContent(path, "binary");
if (!file) return;
const blob = new Blob([fileContent as any], { type: mime.getType(file.extension!) || "application/octet-stream" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = file.name;
a.click();
}
}