{"version":3,"file":"index.cjs","names":["DEFAULT_MIME_TYPES","DEFAULT_MIME_TYPES"],"sources":["../src/error.ts","../src/file.ts","../src/file-selector.ts"],"sourcesContent":["export class UnexpectedObjectError extends Error {\n    item: DataTransferItem;\n    constructor(item: DataTransferItem) {\n        super('DataTransferItem is not a file');\n        this.item = item;\n        this.name = 'UnexpectedObjectError';\n    }\n}\n","import {DEFAULT_MIME_TYPES} from './mime-default';\n\nexport function toFileWithPath(file: File, path?: string, h?: FileSystemHandle): FileWithPath {\n    const f = file as FileWithPath;\n    const {webkitRelativePath} = file;\n    const p =\n        typeof path === 'string'\n            ? path\n            : // If <input webkitdirectory> is set,\n              // the File will have a {webkitRelativePath} property\n              // https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory\n              typeof webkitRelativePath === 'string' && webkitRelativePath.length > 0\n              ? webkitRelativePath\n              : `./${file.name}`;\n    if (typeof f.path !== 'string') {\n        // on electron, path is already set to the absolute path\n        setObjProp(f, 'path', p);\n    }\n    if (h !== undefined) {\n        Object.defineProperty(f, 'handle', {\n            value: h,\n            writable: false,\n            configurable: false,\n            enumerable: true\n        });\n    }\n    // Always populate a relative path so that even electron apps have access to a relativePath value\n    setObjProp(f, 'relativePath', p);\n    return f;\n}\n\nexport interface FileWithPath extends File {\n    readonly path: string;\n    readonly relativePath: string;\n    readonly handle?: FileSystemFileHandle;\n}\n\n/**\n * Sets a File's `type` from its extension using the provided `mimeTypes` lookup,\n * but only when the browser didn't already set a type. Returns the same File.\n */\nexport function withMimeType(file: File, mimeTypes: Map<string, string> = DEFAULT_MIME_TYPES): FileWithPath {\n    const {name} = file;\n    const hasExtension = name && name.lastIndexOf('.') !== -1;\n\n    if (hasExtension && !file.type) {\n        const ext = name.split('.').pop()!.toLowerCase();\n        const type = mimeTypes.get(ext);\n        if (type) {\n            Object.defineProperty(file, 'type', {\n                value: type,\n                writable: false,\n                configurable: false,\n                enumerable: true\n            });\n        }\n    }\n\n    return file as FileWithPath;\n}\n\nfunction setObjProp(f: FileWithPath, key: string, value: string) {\n    Object.defineProperty(f, key, {\n        value,\n        writable: false,\n        configurable: false,\n        enumerable: true\n    });\n}\n","import {UnexpectedObjectError} from './error';\nimport {type FileWithPath, toFileWithPath, withMimeType} from './file';\nimport {DEFAULT_MIME_TYPES} from './mime-default';\n\nconst FILES_TO_IGNORE = [\n    // Thumbnail cache files for macOS and Windows\n    '.DS_Store', // macOs\n    'Thumbs.db' // Windows\n];\n\nexport interface FromEventOptions {\n    /**\n     * Extension-to-MIME lookup used to set `type` on files the browser left typeless.\n     * Defaults to a small built-in set of common types ({@link DEFAULT_MIME_TYPES}).\n     *\n     * The full extension-to-MIME table (~1,200 entries) is not bundled into the main entry;\n     * import it from the `file-selector/mime` subpath when broader coverage is needed:\n     *\n     * ```ts\n     * import {fromEvent} from 'file-selector';\n     * import {COMMON_MIME_TYPES} from 'file-selector/mime';\n     * await fromEvent(evt, {mimeTypes: COMMON_MIME_TYPES});\n     * ```\n     *\n     * See https://github.com/react-dropzone/file-selector/issues/127\n     */\n    mimeTypes?: Map<string, string>;\n}\n\n/**\n * Convert a DragEvent's DataTrasfer object to a list of File objects\n * NOTE: If some of the items are folders,\n * everything will be flattened and placed in the same list but the paths will be kept as a {path} property.\n *\n * EXPERIMENTAL: A list of https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle objects can also be passed as an arg\n * and a list of File objects will be returned.\n *\n * @param evt\n * @param options\n */\nexport async function fromEvent(\n    evt: Event | any,\n    {mimeTypes = DEFAULT_MIME_TYPES}: FromEventOptions = {}\n): Promise<(FileWithPath | DataTransferItem)[]> {\n    const items = await getFilesOrItems(evt);\n    // Guess a MIME type from the file extension once, over the final flat list, for any file the\n    // browser left typeless. DataTransferItems (returned for non-'drop' drag events) pass through as-is.\n    return items.map(item => (item instanceof File ? withMimeType(item, mimeTypes) : item));\n}\n\nasync function getFilesOrItems(evt: Event | any): Promise<(FileWithPath | DataTransferItem)[]> {\n    if (isObject<DragEvent>(evt) && isDataTransfer(evt.dataTransfer)) {\n        return getDataTransferFiles(evt.dataTransfer, evt.type);\n    } else if (isChangeEvt(evt)) {\n        return getInputFiles(evt);\n    } else if (Array.isArray(evt) && evt.every(item => 'getFile' in item && typeof item.getFile === 'function')) {\n        return getFsHandleFiles(evt);\n    }\n    return [];\n}\n\nfunction isDataTransfer(value: any): value is DataTransfer {\n    return isObject(value);\n}\n\nfunction isChangeEvt(value: any): value is Event {\n    return isObject<Event>(value) && isObject(value.target);\n}\n\nfunction isObject<T>(v: any): v is T {\n    return typeof v === 'object' && v !== null;\n}\n\nfunction getInputFiles(evt: Event) {\n    return fromList<FileWithPath>((evt.target as HTMLInputElement).files).map(file => toFileWithPath(file));\n}\n\n// Ee expect each handle to be https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileHandle\nasync function getFsHandleFiles(handles: any[]) {\n    const files = await Promise.all(handles.map(h => h.getFile()));\n    return files.map(file => toFileWithPath(file));\n}\n\nasync function getDataTransferFiles(dt: DataTransfer, type: string) {\n    const items = fromList<DataTransferItem>(dt.items).filter(item => item.kind === 'file');\n    // According to https://html.spec.whatwg.org/multipage/dnd.html#dndevents,\n    // only 'dragstart' and 'drop' has access to the data (source node)\n    if (type !== 'drop') {\n        return items;\n    }\n    const files = await Promise.all(items.map(toFilePromises));\n    return noIgnoredFiles(flatten<FileWithPath>(files));\n}\n\nfunction noIgnoredFiles(files: FileWithPath[]) {\n    return files.filter(file => FILES_TO_IGNORE.indexOf(file.name) === -1);\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/FileList\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItemList\nfunction fromList<T>(items: DataTransferItemList | FileList | null): T[] {\n    // {items} can be null, e.g. an <input type=\"file\"> with no selection\n    if (items === null) {\n        return [];\n    }\n    return Array.from(items as unknown as ArrayLike<T>);\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem\nasync function toFilePromises(item: DataTransferItem) {\n    if (typeof item.webkitGetAsEntry !== 'function') {\n        return fromDataTransferItem(item);\n    }\n\n    const entry = item.webkitGetAsEntry();\n\n    // Safari supports dropping an image node from a different window and can be retrieved using\n    // the DataTransferItem.getAsFile() API\n    // NOTE: FileSystemEntry.file() throws if trying to get the file\n    if (entry?.isDirectory) {\n        // Prefer the File System Access API for directory traversal where it's available.\n        // The legacy Entry API (FileSystemDirectoryReader.readEntries) throws on some platforms,\n        // e.g. dragging a folder from Windows Explorer into a Chromium browser, which would\n        // otherwise reject the entire drop and lose every file.\n        // See https://github.com/react-dropzone/file-selector/issues/130\n        const handle = await getFsHandle(item);\n        if (handle?.kind === 'directory') {\n            return fromDirHandle(handle, `/${handle.name}`);\n        }\n        return fromDirEntry(entry) as any;\n    }\n\n    return fromDataTransferItem(item, entry);\n}\n\nfunction flatten<T>(items: any[]): T[] {\n    const result: T[] = [];\n    for (const item of items) {\n        if (Array.isArray(item)) {\n            result.push(...flatten<T>(item));\n        } else {\n            result.push(item);\n        }\n    }\n    return result;\n}\n\nasync function fromDataTransferItem(item: DataTransferItem, entry?: FileSystemEntry | null) {\n    const h = await getFsHandle(item);\n    if (h === null) {\n        throw new UnexpectedObjectError(item);\n    }\n    // It seems that the handle can be `undefined` (see https://github.com/react-dropzone/file-selector/issues/120),\n    // so we check if it isn't; if it is, the code path continues to the next API (`getAsFile`).\n    // The handle is also `undefined` when the File System Access API isn't available or we're not\n    // in a secure context, in which case we likewise fall back to `getAsFile`.\n    if (h !== undefined) {\n        const file = await h.getFile();\n        file.handle = h;\n        return toFileWithPath(file);\n    }\n    const file = item.getAsFile();\n    if (!file) {\n        throw new UnexpectedObjectError(item);\n    }\n    const fwp = toFileWithPath(file, entry?.fullPath ?? undefined);\n    return fwp;\n}\n\n// Resolve the https://developer.mozilla.org/en-US/docs/Web/API/FileSystemHandle for a dropped item.\n// Returns `undefined` when the File System Access API isn't available or we're not in a secure context.\n//\n// We check for a secure context because, due to a bug in Chrome (as far as we know),\n// the browser crashes when calling this API (yet to be confirmed as a consistent behaviour).\n// See:\n// - https://issues.chromium.org/issues/40186242\n// - https://github.com/react-dropzone/react-dropzone/issues/1397\nasync function getFsHandle(item: DataTransferItem) {\n    if (globalThis.isSecureContext && typeof (item as any).getAsFileSystemHandle === 'function') {\n        return (item as any).getAsFileSystemHandle();\n    }\n    return undefined;\n}\n\n// Traverse a directory recursively using the File System Access API, returning a flat list of files.\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryHandle\nasync function fromDirHandle(handle: any, path: string): Promise<FileWithPath[]> {\n    const files: FileWithPath[] = [];\n    for await (const child of handle.values()) {\n        const childPath = `${path}/${child.name}`;\n        if (child.kind === 'directory') {\n            files.push(...(await fromDirHandle(child, childPath)));\n        } else {\n            const file = await child.getFile();\n            files.push(toFileWithPath(file, childPath, child));\n        }\n    }\n    return files;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemEntry\nasync function fromEntry(entry: any) {\n    return entry.isDirectory ? fromDirEntry(entry) : fromFileEntry(entry);\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry\nfunction fromDirEntry(entry: any) {\n    const reader = entry.createReader();\n\n    return new Promise<FileArray[]>((resolve, reject) => {\n        const entries: Promise<FileValue[]>[] = [];\n\n        function readEntries() {\n            // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryEntry/createReader\n            // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemDirectoryReader/readEntries\n            reader.readEntries(\n                async (batch: any[]) => {\n                    if (!batch.length) {\n                        // Done reading directory\n                        try {\n                            const files = await Promise.all(entries);\n                            resolve(files);\n                        } catch (err) {\n                            reject(err);\n                        }\n                    } else {\n                        const items = Promise.all(batch.map(fromEntry));\n                        entries.push(items);\n\n                        // Continue reading\n                        readEntries();\n                    }\n                },\n                (err: any) => {\n                    reject(err);\n                }\n            );\n        }\n\n        readEntries();\n    });\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/FileSystemFileEntry\nasync function fromFileEntry(entry: any) {\n    return new Promise<FileWithPath>((resolve, reject) => {\n        entry.file(\n            (file: FileWithPath) => {\n                const fwp = toFileWithPath(file, entry.fullPath);\n                resolve(fwp);\n            },\n            (err: any) => {\n                reject(err);\n            }\n        );\n    });\n}\n\n// Infinite type recursion\n// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540\ninterface FileArray extends Array<FileValue> {}\ntype FileValue = FileWithPath | FileArray[];\n"],"mappings":"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"}