Skip to content

Commit

Permalink
Better detect input types for fingerprinting
Browse files Browse the repository at this point in the history
  • Loading branch information
Acconut committed May 29, 2024
1 parent 695a763 commit 2e79a9c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 20 deletions.
8 changes: 2 additions & 6 deletions lib/browser/fileReader.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import isReactNative from './isReactNative.js'
import { isReactNativeFile, isReactNativePlatform } from './isReactNative.js'
import uriToBlob from './uriToBlob.js'

import type { FileReader, FileSource, ReactNativeFile, UploadInput } from '../options.js'
import BlobFileSource from './sources/FileSource.js'
import StreamSource from './sources/StreamSource.js'

function isReactNativeFile(input: UploadInput): input is ReactNativeFile {
return 'uri' in input && typeof input.uri === 'string'
}

function isWebStream(input: UploadInput): input is Pick<ReadableStreamDefaultReader, 'read'> {
return 'read' in input && typeof input.read === 'function'
}
Expand All @@ -21,7 +17,7 @@ export default class BrowserFileReader implements FileReader {
// a local path to the file. We use XMLHttpRequest to fetch
// the file blob, before uploading with tus.
if (isReactNativeFile(input)) {
if (!isReactNative()) {
if (!isReactNativePlatform()) {
// TODO
throw new Error('')
}
Expand Down
19 changes: 10 additions & 9 deletions lib/browser/fileSignature.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import type { ReactNativeFile, UploadInput, UploadOptions } from '../options.js'
import isReactNative from './isReactNative.js'

// TODO: Differenciate between input types
import { isReactNativeFile, isReactNativePlatform } from './isReactNative.js'

/**
* Generate a fingerprint for a file which will be used the store the endpoint
*/
export default function fingerprint(file: UploadInput, options: UploadOptions) {
if (isReactNative()) {
//@ts-expect-error TODO: We have to check the input type here
if (isReactNativePlatform() && isReactNativeFile(file)) {
return Promise.resolve(reactNativeFingerprint(file, options))
}

return Promise.resolve(
//@ts-expect-error TODO: We have to check the input type here
['tus-br', file.name, file.type, file.size, file.lastModified, options.endpoint].join('-'),
)
if (file instanceof Blob) {
return Promise.resolve(
//@ts-expect-error TODO: We have to check the input type here
['tus-br', file.name, file.type, file.size, file.lastModified, options.endpoint].join('-'),
)
}

return Promise.resolve(null)
}

function reactNativeFingerprint(file: ReactNativeFile, options: UploadOptions): string {
Expand Down
19 changes: 14 additions & 5 deletions lib/browser/isReactNative.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const isReactNative = () =>
typeof navigator !== 'undefined' &&
typeof navigator.product === 'string' &&
navigator.product.toLowerCase() === 'reactnative'
import type { ReactNativeFile } from '../options'

export default isReactNative
export function isReactNativePlatform() {
return (
typeof navigator !== 'undefined' &&
typeof navigator.product === 'string' &&
navigator.product.toLowerCase() === 'reactnative'
)
}

export function isReactNativeFile(input: unknown): input is ReactNativeFile {
return (
input != null && typeof input === 'object' && 'uri' in input && typeof input.uri === 'string'
)
}
3 changes: 3 additions & 0 deletions lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ export interface ReactNativeFile {
}

export type UploadInput =
// Blob, File, ReadableStreamDefaultReader are available in browsers and Node.js
| Blob
| File
// TODO: Should we keep the Pick<> here?
| Pick<ReadableStreamDefaultReader, 'read'>
// Buffer, stream.Readable, fs.ReadStream are available in Node.js
| Buffer
| Readable
| ReadStream
// ReactNativeFile is intended for React Native apps
| ReactNativeFile

export interface UploadOptions {
Expand Down

0 comments on commit 2e79a9c

Please sign in to comment.