UNPKG

easy-file-picker

Version:

Easy File Picker is a straightforward library with no dependencies to upload/pick/read files in the browser.

145 lines (144 loc) 4.78 kB
export async function getFile(options) { const fileInput = createFileInput(false, options); const file = new Promise((resolve, reject) => { fileInput.onchange = (event) => { const files = convertFileListToFileArray(event.target?.files); resolve(files[0]); }; fileInput.oncancel = () => { resolve(null); }; fileInput.onerror = (_event, _source, _line, _col, error) => { reject(error); }; fileInput.click(); }); return file.finally(() => fileInput.remove()); } export async function getFiles(options) { const fileInput = createFileInput(true, options); const files = new Promise((resolve, reject) => { fileInput.onchange = (event) => { const files = convertFileListToFileArray(event.target?.files); resolve(files); }; fileInput.oncancel = () => { resolve([]); }; fileInput.onerror = (_event, _source, _line, _col, error) => { reject(error); }; fileInput.click(); }); return files.finally(() => fileInput.remove()); } export async function getFileAsString(options) { const fileInput = createFileInput(false, options); const file = new Promise((resolve, reject) => { fileInput.onchange = (event) => { const files = convertFileListToFileArray(event.target?.files); convertFileArrayToFileStringArray(files) .then((str) => resolve(str[0])) .catch((err) => reject(err)); }; fileInput.oncancel = () => { resolve(null); }; fileInput.onerror = (_event, _source, _line, _col, error) => { reject(error); }; fileInput.click(); }); return file.finally(() => fileInput.remove()); } export async function getFilesAsString(options) { const fileInput = createFileInput(true, options); const files = new Promise((resolve, reject) => { fileInput.onchange = (event) => { const files = convertFileListToFileArray(event.target?.files); convertFileArrayToFileStringArray(files) .then((str) => resolve(str)) .catch((err) => reject(err)); }; fileInput.oncancel = () => { resolve([]); }; fileInput.onerror = (_event, _source, _line, _col, error) => { reject(error); }; fileInput.click(); }); return files.finally(() => fileInput.remove()); } export async function uploadFilesTo(url, files, methodOrInit = "POST") { const formData = filesToFormData(files); const init = typeof methodOrInit === "string" ? { body: formData, method: methodOrInit, } : { body: formData, ...methodOrInit, }; return fetch(url, init); } function filesToFormData(files) { const formData = new FormData(); if (files instanceof File) { formData.append("file0", files); } else if (Array.isArray(files)) { files.forEach((file, i) => { formData.append(`file${i}`, file); }); } else if (typeof files === "object" && files != null) { Object.entries(files).forEach(([key, file]) => { formData.append(key, file); }); } return formData; } function createFileInput(multipleFiles, options) { const fileInput = document.createElement("input"); fileInput.hidden = true; fileInput.type = "file"; fileInput.multiple = multipleFiles; fileInput.accept = options?.acceptedExtensions?.join(",") ?? ""; return fileInput; } function convertFileListToFileArray(files) { if (files == null) { return []; } const fileArray = []; for (let i = 0; i < files.length; i++) { fileArray.push(files[i]); } return fileArray; } async function convertFileArrayToFileStringArray(files) { const filePromises = []; for (const file of files) { const filePromise = new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (event) => { resolve({ name: file.name, size: file.size, type: file.type, lastModified: file.lastModified, webkitRelativePath: file.webkitRelativePath, content: event.target?.result, }); }; reader.onerror = () => { reject(reader.error); }; reader.readAsText(file, "utf-8"); }); filePromises.push(filePromise); } return Promise.all(filePromises); }