diff --git a/lib/browser/urlStorage.ts b/lib/browser/urlStorage.ts index cbd0f1e8..b93b1e72 100644 --- a/lib/browser/urlStorage.ts +++ b/lib/browser/urlStorage.ts @@ -12,7 +12,7 @@ try { const key = 'tusSupport' const originalValue = localStorage.getItem(key) localStorage.setItem(key, String(originalValue)) - if (originalValue === null) localStorage.removeItem(key) + if (originalValue == null) localStorage.removeItem(key) } catch (e: unknown) { // If we try to access localStorage inside a sandboxed iframe, a SecurityError // is thrown. When in private mode on iOS Safari, a QuotaExceededError is diff --git a/lib/node/httpStack.ts b/lib/node/httpStack.ts index 499ec3a1..31867fe3 100644 --- a/lib/node/httpStack.ts +++ b/lib/node/httpStack.ts @@ -119,7 +119,7 @@ class Request implements HttpRequest { } abort() { - if (this._request !== null) this._request.abort() + if (this._request != null) this._request.abort() return Promise.resolve() } diff --git a/lib/node/sources/StreamFileSource.ts b/lib/node/sources/StreamFileSource.ts index e10ef1c0..ec5f9bd6 100644 --- a/lib/node/sources/StreamFileSource.ts +++ b/lib/node/sources/StreamFileSource.ts @@ -21,7 +21,7 @@ async function readChunk(stream: Readable, size: number) { // TODO: Node requires size to be less than 1GB. Add a validation for that const chunk = stream.read(size) - if (chunk !== null) { + if (chunk != null) { stream.off('error', onError) stream.off('readable', onReadable) diff --git a/lib/options.ts b/lib/options.ts index f7c73e2a..8771e2a6 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -32,36 +32,31 @@ export type UploadInput = | ReactNativeFile export interface UploadOptions { - // TODO: Embrace undefined over null - endpoint: string | null + endpoint?: string - uploadUrl: string | null + uploadUrl?: string metadata: { [key: string]: string } metadataForPartialUploads: UploadOptions['metadata'] fingerprint: (file: UploadInput, options: UploadOptions) => Promise - uploadSize: number | null - - onProgress: ((bytesSent: number, bytesTotal: number | null) => void) | null - onChunkComplete: - | ((chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void) - | null - onSuccess: ((payload: OnSuccessPayload) => void) | null - onError: ((error: Error | DetailedError) => void) | null - onShouldRetry: - | ((error: DetailedError, retryAttempt: number, options: UploadOptions) => boolean) - | null - onUploadUrlAvailable: (() => void) | null + uploadSize?: number + + onProgress?: (bytesSent: number, bytesTotal: number | null) => void + onChunkComplete?: (chunkSize: number, bytesAccepted: number, bytesTotal: number | null) => void + onSuccess?: (payload: OnSuccessPayload) => void + onError?: (error: Error | DetailedError) => void + onShouldRetry?: (error: DetailedError, retryAttempt: number, options: UploadOptions) => boolean + onUploadUrlAvailable?: () => void overridePatchMethod: boolean headers: { [key: string]: string } addRequestId: boolean - onBeforeRequest: ((req: HttpRequest) => void | Promise) | null - onAfterResponse: ((req: HttpRequest, res: HttpResponse) => void | Promise) | null + onBeforeRequest?: (req: HttpRequest) => void | Promise + onAfterResponse?: (req: HttpRequest, res: HttpResponse) => void | Promise chunkSize: number retryDelays: number[] parallelUploads: number - parallelUploadBoundaries: { start: number; end: number }[] | null + parallelUploadBoundaries?: { start: number; end: number }[] storeFingerprintForResuming: boolean removeFingerprintOnSuccess: boolean uploadLengthDeferred: boolean diff --git a/lib/upload.ts b/lib/upload.ts index 7e2027d3..bb64a1fe 100644 --- a/lib/upload.ts +++ b/lib/upload.ts @@ -17,39 +17,39 @@ import { import { uuid } from './uuid.js' export const defaultOptions = { - endpoint: null, + endpoint: undefined, - uploadUrl: null, + uploadUrl: undefined, metadata: {}, metadataForPartialUploads: {}, - fingerprint: null, - uploadSize: null, + fingerprint: undefined, + uploadSize: undefined, - onProgress: null, - onChunkComplete: null, - onSuccess: null, - onError: null, - onUploadUrlAvailable: null, + onProgress: undefined, + onChunkComplete: undefined, + onSuccess: undefined, + onError: undefined, + onUploadUrlAvailable: undefined, overridePatchMethod: false, headers: {}, addRequestId: false, - onBeforeRequest: null, - onAfterResponse: null, + onBeforeRequest: undefined, + onAfterResponse: undefined, onShouldRetry: defaultOnShouldRetry, chunkSize: Number.POSITIVE_INFINITY, retryDelays: [0, 1000, 3000, 5000], parallelUploads: 1, - parallelUploadBoundaries: null, + parallelUploadBoundaries: undefined, storeFingerprintForResuming: true, removeFingerprintOnSuccess: false, uploadLengthDeferred: false, uploadDataDuringCreation: false, - urlStorage: null, - fileReader: null, - httpStack: null, + urlStorage: undefined, + fileReader: undefined, + httpStack: undefined, protocol: PROTOCOL_TUS_V1 as UploadOptions['protocol'], } @@ -67,13 +67,13 @@ export class BaseUpload { url: string | null = null // The underlying request object for the current PATCH request - _req: HttpRequest | null = null + _req?: HttpRequest // The fingerpinrt for the current file (set after start()) _fingerprint: string | null = null // The key that the URL storage returned when saving an URL with a fingerprint, - _urlStorageKey: string | null = null + _urlStorageKey?: string // The offset used in the current PATCH request _offset = 0 @@ -87,13 +87,13 @@ export class BaseUpload { // The Source object which will wrap around the given file and provides us // with a unified interface for getting its size and slice chunks from its // content allowing us to easily handle Files, Blobs, Buffers and Streams. - _source: FileSource | null = null + _source?: FileSource // The current count of attempts which have been made. Zero indicates none. _retryAttempt = 0 // The timeout's ID which is used to delay the next retry - _retryTimeout: ReturnType | null = null + _retryTimeout?: ReturnType // The offset of the remote upload before the latest attempt was started. _offsetBeforeRetry = 0 @@ -275,7 +275,7 @@ export class BaseUpload { ? this._parallelUploadUrls.length : this.options.parallelUploads - if (this._size === null) { + if (this._size == null) { this._emitError(new Error('tus: Expected _size to be set')) return } @@ -330,7 +330,7 @@ export class BaseUpload { onProgress: (newPartProgress: number) => { totalProgress = totalProgress - lastPartProgress + newPartProgress lastPartProgress = newPartProgress - if (totalSize === null) { + if (totalSize == null) { this._emitError(new Error('tus: Expected totalSize to be set')) return } @@ -365,7 +365,7 @@ export class BaseUpload { // creating the final upload. Promise.all(uploads) .then(() => { - if (this.options.endpoint === null) { + if (this.options.endpoint == null) { this._emitError(new Error('tus: Expected options.endpoint to be set')) return } @@ -397,7 +397,7 @@ export class BaseUpload { return } - if (this.options.endpoint === null) { + if (this.options.endpoint == null) { this._emitError(new Error('tus: Expeced endpoint to be defined.')) return } @@ -463,7 +463,7 @@ export class BaseUpload { } // Stop any current running request. - if (this._req !== null) { + if (this._req != null) { this._req.abort() // Note: We do not close the file source here, so the user can resume in the future. } @@ -472,7 +472,7 @@ export class BaseUpload { // Stop any timeout used for initiating a retry. if (this._retryTimeout != null) { clearTimeout(this._retryTimeout) - this._retryTimeout = null + this._retryTimeout = undefined } if (!shouldTerminate || this.url == null) { @@ -588,7 +588,7 @@ export class BaseUpload { if (this.options.uploadLengthDeferred) { req.setHeader('Upload-Defer-Length', '1') } else { - if (this._size === null) { + if (this._size == null) { this._emitError(new Error('tus: expected _size to be set')) } req.setHeader('Upload-Length', `${this._size}`) @@ -632,7 +632,7 @@ export class BaseUpload { return } - if (this.options.endpoint === null) { + if (this.options.endpoint == null) { this._emitError(new Error('tus: Expected options.endpoint to be set')) return } @@ -673,7 +673,7 @@ export class BaseUpload { * @api private */ _resumeUpload() { - if (this.url === null) { + if (this.url == null) { this._emitError(new Error('tus: Expected url to be set')) return } @@ -777,7 +777,7 @@ export class BaseUpload { let req: HttpRequest - if (this.url === null) { + if (this.url == null) { this._emitError(new Error('tus: Expected url to be set')) return } @@ -875,7 +875,7 @@ export class BaseUpload { ) } - if (value === null) { + if (value == null) { return this._sendRequest(req) } @@ -940,7 +940,7 @@ export class BaseUpload { this._urlStorage.removeUpload(this._urlStorageKey).catch((err) => { this._emitError(err) }) - this._urlStorageKey = null + this._urlStorageKey = undefined } /** @@ -956,7 +956,7 @@ export class BaseUpload { if ( !this.options.storeFingerprintForResuming || !this._fingerprint || - this._urlStorageKey !== null + this._urlStorageKey != null ) { return Promise.resolve() } @@ -977,8 +977,8 @@ export class BaseUpload { } return this._urlStorage.addUpload(this._fingerprint, storedUpload).then((urlStorageKey) => { - // TODO: Handle cases when urlStorageKey is undefined - this._urlStorageKey = urlStorageKey || null + // TODO: Emit a waring if urlStorageKey is undefined. Should we even allow this? + this._urlStorageKey = urlStorageKey }) }