tus / tus-js-client

A pure JavaScript client for the tus resumable upload protocol
https://tus.io/
MIT License
2.11k stars 316 forks source link

typescript: Replace file types with interfaces #289

Open Acconut opened 3 years ago

Acconut commented 3 years ago

Currently, the definitions reference browser-specific types, which do not exist in other environments, e.g. in Node.js: https://github.com/tus/tus-js-client/blob/239343a75da5aaedeefbc3bf2438062554b5db8d/lib/index.d.ts#L8

It would be better to replace them with interfaces, so we are independent of the environment (pseudo-code):

interface IBlob {
  slice(start, end): IBlob;
}

interface IReader {
  read(): Promise<IBlob>;
}

This could prevent issues like https://github.com/tus/tus-js-client/issues/252

DennySlick commented 7 months ago

Is here any consistent solution or example for Node.js environment? When I try to use fileData as Blob or Buffer from Node.js receive an error: source object may only be an instance of Buffer or Readable in this environment

Acconut commented 7 months ago

tus-js-client does not accept Blobs when used in Node.js. But Buffers should work as long as they pass Buffer.isBuffer:

https://github.com/tus/tus-js-client/blob/97015bf61ebc97be7ab1e108f37377f8cca91cfc/lib/node/fileReader.js#L10-L12

Does that apply to your fileData?

DennySlick commented 7 months ago

@Acconut, thank you for your answer!

I was able to use NodeJS Buffer. But it was incompatible with TypeScript out of the box.

The solution I ended up with is:

  1. Defined type augmentation file in my project: tus-js-client.d.ts
  2. Copied index.d.ts from tus-js-client initial file and extended typing to Buffer:
    
    /* eslint-disable @typescript-eslint/no-explicit-any */
    // file: 'types/tus-js-client.d.ts'
    // Type definitions for tus-js-client

declare module 'tus-js-client' { export const isSupported: boolean; export const canStoreURLs: boolean; export const defaultOptions: UploadOptions;

// TODO: Consider using { read: () => Promise<{ done: boolean; value?: any; }>; } as type export class Upload { // Override: Added Buffer type constructor(file: File | Buffer | Blob | Pick<ReadableStreamDefaultReader, 'read'>, options: UploadOptions);

// Override: Added Buffer type
file: File | Buffer | Blob | Pick<ReadableStreamDefaultReader, 'read'>;
options: UploadOptions;
url: string | null;

static terminate(url: string, options?: UploadOptions): Promise<void>;
start(): void;
abort(shouldTerminate?: boolean): Promise<void>;
findPreviousUploads(): Promise<PreviousUpload[]>;

resumeFromPreviousUpload(previousUpload: PreviousUpload): void;

}

// Copy the rest tus-js-client index.d.ts file...

Acconut commented 7 months ago

I see, thanks for the update. Our current type definitions are focused on the use in browser, which is not ideal, I agree. We should have type definitions that work in browsers and in Node.js.