import { UploadFileProps } from "./types" import { createMD5, createSHA1, createSHA256 } from "hash-wasm" export const traverseFileTree = async (entry: FileSystemEntry) => { let res: File[] = [] const internalProcess = async (entry: FileSystemEntry, path: string) => { const promise = new Promise<{}>((resolve, reject) => { const errorCallback: ErrorCallback = (e) => { console.error(e) reject(e) } if (entry.isFile) { ;(entry as FileSystemFileEntry).file((file) => { const newFile = new File([file], path + file.name, { type: file.type, }) res.push(newFile) console.log(newFile) resolve({}) }, errorCallback) } else if (entry.isDirectory) { const dirReader = (entry as FileSystemDirectoryEntry).createReader() const readEntries = () => { dirReader.readEntries(async (entries) => { for (let i = 0; i < entries.length; i++) { await internalProcess(entries[i], path + entry.name + "/") } resolve({}) /** why? https://stackoverflow.com/questions/3590058/does-html5-allow-drag-drop-upload-of-folders-or-a-folder-tree/53058574#53058574 Unfortunately none of the existing answers are completely correct because readEntries will not necessarily return ALL the (file or directory) entries for a given directory. This is part of the API specification (see Documentation section below). To actually get all the files, we'll need to call readEntries repeatedly (for each directory we encounter) until it returns an empty array. If we don't, we will miss some files/sub-directories in a directory e.g. in Chrome, readEntries will only return at most 100 entries at a time. */ if (entries.length > 0) { readEntries() } }, errorCallback) } readEntries() } }) await promise } await internalProcess(entry, "") return res } export const File2Upload = (file: File): UploadFileProps => { return { name: file.name, path: file.webkitRelativePath ? file.webkitRelativePath : file.name, size: file.size, progress: 0, speed: 0, status: "pending", } } export const calculateHash = async (file: File) => { const md5Digest = await createMD5() const sha1Digest = await createSHA1() const sha256Digest = await createSHA256() const reader = file.stream().getReader() const read = async () => { const { done, value } = await reader.read() if (done) { return } md5Digest.update(value) sha1Digest.update(value) sha256Digest.update(value) await read() } await read() const md5 = md5Digest.digest("hex") const sha1 = sha1Digest.digest("hex") const sha256 = sha256Digest.digest("hex") return { md5, sha1, sha256 } }