Skip to content

Commit

Permalink
refactor: clean up retrieval from data transfer item
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Koops <[email protected]>
  • Loading branch information
jonkoops committed Nov 22, 2024
1 parent 1a997bd commit 6a613b6
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 13 deletions.
18 changes: 16 additions & 2 deletions src/file-selector.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,19 @@ it("should use getAsFileSystemHandle when available", async () => {
expect(file.path).toBe(`./${name}`);
});

it("should throw if getAsFileSystemHandle does not return a file", (done) => {
const name = "test.json";
const data = { ping: true };
const options = { type: "application/json" };
const file = createFile(name, data, options);
const handle = { kind: "unknown" } as unknown as FileSystemFileHandle;
const evt = dragEvtFromItems([dataTransferItemWithFsHandle(file, handle)]);

fromEvent(evt)
.then(() => done.fail("Getting the files should have failed"))
.catch(() => done());
});

function dragEvtFromItems(
items: DataTransferItem | DataTransferItem[],
type: string = "drop",
Expand Down Expand Up @@ -519,11 +532,11 @@ function createFileSystemFileHandle<T>(
data: T,
options?: FilePropertyBag,
): [File, FileSystemFileHandle] {
const json = JSON.stringify(data);
const file = new File([json], name, options);
const file = createFile(name, data, options);
return [
file,
{
kind: "file",
getFile() {
return Promise.resolve(file);
},
Expand All @@ -536,6 +549,7 @@ function sortFiles<T extends File>(files: T[]) {
}

interface FileSystemFileHandle {
kind: "file";
getFile(): Promise<File>;
}

Expand Down
40 changes: 29 additions & 11 deletions src/file-selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,29 @@ function flatten<T>(items: any[]): T[] {
);
}

function fromDataTransferItem(
async function fromDataTransferItem(
item: DataTransferItem,
entry?: FileSystemEntry | null,
) {
if (typeof (item as any).getAsFileSystemHandle === "function") {
return (item as any).getAsFileSystemHandle().then(async (h: any) => {
const file = await h.getFile();
file.handle = h;
return toFileWithPath(file);
});
): Promise<FileWithPath> {
if (typeof item.getAsFileSystemHandle === "function") {
const handle = await item.getAsFileSystemHandle();

if (!handle || !isFileHandle(handle)) {
throw new Error(`${item} is not a File`);
}

const file = await handle.getFile();
(file as any).handle = handle;
return toFileWithPath(file);
}

const file = item.getAsFile();

if (!file) {
return Promise.reject(`${item} is not a File`);
throw new Error(`${item} is not a File`);
}
const fwp = toFileWithPath(file, entry?.fullPath ?? undefined);
return Promise.resolve(fwp);

return toFileWithPath(file, entry?.fullPath ?? undefined);
}

async function fromEntry(
Expand Down Expand Up @@ -165,6 +171,10 @@ async function fromFileEntry(
return fileWithPath;
}

const isFileHandle = (
handle: FileSystemHandle,
): handle is FileSystemFileHandle => handle.kind === "file";

const isDirectoryEntry = (
entry: FileSystemEntry,
): entry is FileSystemDirectoryEntry => entry.isDirectory;
Expand All @@ -180,6 +190,14 @@ const readEntries = (
): Promise<FileSystemEntry[]> =>
new Promise((resolve, reject) => reader.readEntries(resolve, reject));

declare global {
interface DataTransferItem {
// This method is not yet widely supported in all browsers, and is thus marked as optional.
// See: https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/getAsFileSystemHandle
getAsFileSystemHandle?(): Promise<FileSystemHandle | null>;
}
}

// Infinite type recursion
// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
interface FileArray extends Array<FileValue> {}
Expand Down

0 comments on commit 6a613b6

Please sign in to comment.