@uppy/utils
Advanced tools
Comparing version
@@ -0,1 +1,3 @@ | ||
import getFileType from './getFileType.js'; | ||
function encodeCharacter(character) { | ||
@@ -47,2 +49,18 @@ return character.charCodeAt(0).toString(32); | ||
return id; | ||
} // If the provider has a stable, unique ID, then we can use that to identify the file. | ||
// Then we don't have to generate our own ID, and we can add the same file many times if needed (different path) | ||
function hasFileStableId(file) { | ||
if (!file.isRemote || !file.remote) return false; // These are the providers that it seems like have stable IDs for their files. The other's I haven't checked yet. | ||
const stableIdProviders = new Set(['box', 'dropbox', 'drive', 'facebook', 'unsplash']); | ||
return stableIdProviders.has(file.remote.provider); | ||
} | ||
export function getSafeFileId(file) { | ||
if (hasFileStableId(file)) return file.id; | ||
const fileType = getFileType(file); | ||
return generateFileID({ ...file, | ||
type: fileType | ||
}); | ||
} |
import getFilesAndDirectoriesFromDirectory from './getFilesAndDirectoriesFromDirectory.js'; | ||
/** | ||
* Interop between deprecated webkitGetAsEntry and standard getAsFileSystemHandle. | ||
* Polyfill for the new (experimental) getAsFileSystemHandle API (using the popular webkitGetAsEntry behind the scenes) | ||
* so that we can switch to the getAsFileSystemHandle API once it (hopefully) becomes standard | ||
*/ | ||
@@ -40,3 +41,3 @@ | ||
if (file !== null) { | ||
if (file != null) { | ||
file.relativePath = relativePath ? `${relativePath}/${entry.name}` : null; | ||
@@ -47,2 +48,3 @@ yield file; | ||
for await (const handle of entry.values()) { | ||
// Recurse on the directory, appending the dir name to the relative path | ||
yield* createPromiseToAddFileOrParseDirectory(handle, `${relativePath}/${entry.name}`); | ||
@@ -52,18 +54,34 @@ } | ||
} | ||
/** | ||
* Load all files from data transfer, and recursively read any directories. | ||
* Note that IE is not supported for drag-drop, because IE doesn't support Data Transfers | ||
* | ||
* @param {DataTransfer} dataTransfer | ||
* @param {*} logDropError on error | ||
*/ | ||
export default async function* getFilesFromDataTransfer(dataTransfer, logDropError) { | ||
const entries = await Promise.all(Array.from(dataTransfer.items, async item => { | ||
var _entry; | ||
// Retrieving the dropped items must happen synchronously | ||
// otherwise only the first item gets treated and the other ones are garbage collected. | ||
// https://github.com/transloadit/uppy/pull/3998 | ||
const fileSystemHandles = await Promise.all(Array.from(dataTransfer.items, async item => { | ||
var _fileSystemHandle; | ||
const lastResortFile = item.getAsFile(); // Chromium bug, see https://github.com/transloadit/uppy/issues/3505. | ||
let fileSystemHandle; // TODO enable getAsFileSystemHandle API once we can get it working with subdirectories | ||
// IMPORTANT: Need to check isSecureContext *before* calling getAsFileSystemHandle | ||
// or else Chrome will crash when running in HTTP: https://github.com/transloadit/uppy/issues/4133 | ||
// if (window.isSecureContext && item.getAsFileSystemHandle != null) entry = await item.getAsFileSystemHandle() | ||
// `webkitGetAsEntry` exists in all popular browsers (including non-WebKit browsers), | ||
// however it may be renamed to getAsEntry() in the future, so you should code defensively, looking for both. | ||
// from https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry | ||
let entry; // IMPORTANT: Need to check isSecureContext *first* or else Chrome will crash when running in HTTP: | ||
// https://github.com/transloadit/uppy/issues/4133 | ||
const getAsEntry = () => typeof item.getAsEntry === 'function' ? item.getAsEntry() : item.webkitGetAsEntry(); // eslint-disable-next-line prefer-const | ||
if (window.isSecureContext && item.getAsFileSystemHandle != null) entry = await item.getAsFileSystemHandle(); // fallback | ||
(_entry = entry) != null ? _entry : entry = getAsFileSystemHandleFromEntry(item.webkitGetAsEntry(), logDropError); | ||
(_fileSystemHandle = fileSystemHandle) != null ? _fileSystemHandle : fileSystemHandle = getAsFileSystemHandleFromEntry(getAsEntry(), logDropError); | ||
return { | ||
lastResortFile, | ||
entry | ||
fileSystemHandle, | ||
lastResortFile: item.getAsFile() // can be used as a fallback in case other methods fail | ||
}; | ||
@@ -74,9 +92,12 @@ })); | ||
lastResortFile, | ||
entry | ||
} of entries) { | ||
// :entry can be null when we drop the url e.g. | ||
if (entry != null) { | ||
fileSystemHandle | ||
} of fileSystemHandles) { | ||
// fileSystemHandle and lastResortFile can be null when we drop an url. | ||
if (fileSystemHandle != null) { | ||
try { | ||
yield* createPromiseToAddFileOrParseDirectory(entry, '', lastResortFile); | ||
yield* createPromiseToAddFileOrParseDirectory(fileSystemHandle, '', lastResortFile); | ||
} catch (err) { | ||
// Example: If dropping a symbolic link, Chromium will throw: | ||
// "DOMException: A requested file or directory could not be found at the time an operation was processed.", | ||
// So we will use lastResortFile instead. See https://github.com/transloadit/uppy/issues/3505. | ||
if (lastResortFile != null) { | ||
@@ -83,0 +104,0 @@ yield lastResortFile; |
{ | ||
"name": "@uppy/utils", | ||
"description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.", | ||
"version": "5.1.3", | ||
"version": "5.2.0", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "types": "types/index.d.ts", |
@@ -0,1 +1,3 @@ | ||
import getFileType from './getFileType.js' | ||
function encodeCharacter (character) { | ||
@@ -46,1 +48,21 @@ return character.charCodeAt(0).toString(32) | ||
} | ||
// If the provider has a stable, unique ID, then we can use that to identify the file. | ||
// Then we don't have to generate our own ID, and we can add the same file many times if needed (different path) | ||
function hasFileStableId (file) { | ||
if (!file.isRemote || !file.remote) return false | ||
// These are the providers that it seems like have stable IDs for their files. The other's I haven't checked yet. | ||
const stableIdProviders = new Set(['box', 'dropbox', 'drive', 'facebook', 'unsplash']) | ||
return stableIdProviders.has(file.remote.provider) | ||
} | ||
export function getSafeFileId (file) { | ||
if (hasFileStableId(file)) return file.id | ||
const fileType = getFileType(file) | ||
return generateFileID({ | ||
...file, | ||
type: fileType, | ||
}) | ||
} |
import getFilesAndDirectoriesFromDirectory from './getFilesAndDirectoriesFromDirectory.js' | ||
/** | ||
* Interop between deprecated webkitGetAsEntry and standard getAsFileSystemHandle. | ||
* Polyfill for the new (experimental) getAsFileSystemHandle API (using the popular webkitGetAsEntry behind the scenes) | ||
* so that we can switch to the getAsFileSystemHandle API once it (hopefully) becomes standard | ||
*/ | ||
@@ -32,3 +33,3 @@ function getAsFileSystemHandleFromEntry (entry, logDropError) { | ||
const file = await entry.getFile() | ||
if (file !== null) { | ||
if (file != null) { | ||
file.relativePath = relativePath ? `${relativePath}/${entry.name}` : null | ||
@@ -39,2 +40,3 @@ yield file | ||
for await (const handle of entry.values()) { | ||
// Recurse on the directory, appending the dir name to the relative path | ||
yield* createPromiseToAddFileOrParseDirectory(handle, `${relativePath}/${entry.name}`) | ||
@@ -45,21 +47,43 @@ } | ||
/** | ||
* Load all files from data transfer, and recursively read any directories. | ||
* Note that IE is not supported for drag-drop, because IE doesn't support Data Transfers | ||
* | ||
* @param {DataTransfer} dataTransfer | ||
* @param {*} logDropError on error | ||
*/ | ||
export default async function* getFilesFromDataTransfer (dataTransfer, logDropError) { | ||
const entries = await Promise.all(Array.from(dataTransfer.items, async item => { | ||
const lastResortFile = item.getAsFile() // Chromium bug, see https://github.com/transloadit/uppy/issues/3505. | ||
let entry | ||
// IMPORTANT: Need to check isSecureContext *first* or else Chrome will crash when running in HTTP: | ||
// https://github.com/transloadit/uppy/issues/4133 | ||
if (window.isSecureContext && item.getAsFileSystemHandle != null) entry = await item.getAsFileSystemHandle() | ||
// fallback | ||
entry ??= getAsFileSystemHandleFromEntry(item.webkitGetAsEntry(), logDropError) | ||
// Retrieving the dropped items must happen synchronously | ||
// otherwise only the first item gets treated and the other ones are garbage collected. | ||
// https://github.com/transloadit/uppy/pull/3998 | ||
const fileSystemHandles = await Promise.all(Array.from(dataTransfer.items, async item => { | ||
let fileSystemHandle | ||
return { lastResortFile, entry } | ||
// TODO enable getAsFileSystemHandle API once we can get it working with subdirectories | ||
// IMPORTANT: Need to check isSecureContext *before* calling getAsFileSystemHandle | ||
// or else Chrome will crash when running in HTTP: https://github.com/transloadit/uppy/issues/4133 | ||
// if (window.isSecureContext && item.getAsFileSystemHandle != null) entry = await item.getAsFileSystemHandle() | ||
// `webkitGetAsEntry` exists in all popular browsers (including non-WebKit browsers), | ||
// however it may be renamed to getAsEntry() in the future, so you should code defensively, looking for both. | ||
// from https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry | ||
const getAsEntry = () => (typeof item.getAsEntry === 'function' ? item.getAsEntry() : item.webkitGetAsEntry()) | ||
// eslint-disable-next-line prefer-const | ||
fileSystemHandle ??= getAsFileSystemHandleFromEntry(getAsEntry(), logDropError) | ||
return { | ||
fileSystemHandle, | ||
lastResortFile: item.getAsFile(), // can be used as a fallback in case other methods fail | ||
} | ||
})) | ||
for (const { lastResortFile, entry } of entries) { | ||
// :entry can be null when we drop the url e.g. | ||
if (entry != null) { | ||
for (const { lastResortFile, fileSystemHandle } of fileSystemHandles) { | ||
// fileSystemHandle and lastResortFile can be null when we drop an url. | ||
if (fileSystemHandle != null) { | ||
try { | ||
yield* createPromiseToAddFileOrParseDirectory(entry, '', lastResortFile) | ||
yield* createPromiseToAddFileOrParseDirectory(fileSystemHandle, '', lastResortFile) | ||
} catch (err) { | ||
// Example: If dropping a symbolic link, Chromium will throw: | ||
// "DOMException: A requested file or directory could not be found at the time an operation was processed.", | ||
// So we will use lastResortFile instead. See https://github.com/transloadit/uppy/issues/3505. | ||
if (lastResortFile != null) { | ||
@@ -66,0 +90,0 @@ yield lastResortFile |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
252371
3.27%3357
2.19%