Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow string data on Upload constructor #493

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/browser/fileReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import StreamSource from './sources/StreamSource.js'

export default class FileReader {
openFile (input, chunkSize) {
if (typeof input === 'string') {
input = new Blob(input.split(''))
}

// In React Native, when user selects a file, instead of a File or Blob,
// you usually get a file object {} with a uri property that contains
// a local path to the file. We use XMLHttpRequest to fetch
Expand Down Expand Up @@ -35,6 +39,8 @@ export default class FileReader {
return Promise.resolve(new StreamSource(input, chunkSize))
}

return Promise.reject(new Error('source object may only be an instance of File, Blob, or Reader in this environment'))
return Promise.reject(new Error(
'source object may only be an instance of string, File, Blob, or Reader in this environment',
))
}
}
8 changes: 7 additions & 1 deletion lib/node/fileReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import StreamSource from './sources/StreamSource.js'

export default class FileReader {
openFile (input, chunkSize) {
if (typeof input === 'string') {
input = Buffer.from(input)
}

if (Buffer.isBuffer(input)) {
return Promise.resolve(new BufferSource(input))
}
Expand All @@ -23,6 +27,8 @@ export default class FileReader {
return Promise.resolve(new StreamSource(input))
}

return Promise.reject(new Error('source object may only be an instance of Buffer or Readable in this environment'))
return Promise.reject(new Error(
'source object may only be an instance of string, Buffer or Readable in this environment',
))
}
}
2 changes: 1 addition & 1 deletion lib/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class BaseUpload {
start () {
const { file } = this

if (!file) {
if (file == null) {
this._emitError(new Error('tus: no file or stream to upload provided'))
return
}
Expand Down
15 changes: 0 additions & 15 deletions test/spec/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,6 @@

'use strict'

const isBrowser = typeof window !== 'undefined'
const isNode = !isBrowser

/**
* Obtain a platform specific buffer object, which can be
* handled by tus-js-client.
*/
function getBlob (str) {
if (isNode) {
return Buffer.from(str)
}
return new Blob(str.split(''))
}

/**
* Create a promise and obtain the resolve/reject functions
* outside of the Promise callback.
Expand Down Expand Up @@ -174,5 +160,4 @@ module.exports = {
TestHttpStack,
waitableFunction,
wait,
getBlob,
}
58 changes: 29 additions & 29 deletions test/spec/test-common.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict'

const { TestHttpStack, waitableFunction, wait, getBlob } = require('./helpers/utils')
const { TestHttpStack, waitableFunction, wait } = require('./helpers/utils')
const tus = require('../..')

// Uncomment to enable debug log from tus-js-client
Expand All @@ -20,14 +20,14 @@ describe('tus', () => {
})

it('should throw if no endpoint and upload URL is provided', () => {
const file = getBlob('hello world')
const file = 'hello world'
const upload = new tus.Upload(file)
expect(upload.start.bind(upload)).toThrowError('tus: neither an endpoint or an upload URL is provided')
})

it('should upload a file', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'https://tus.io/uploads',
Expand Down Expand Up @@ -92,7 +92,7 @@ describe('tus', () => {

it('should create an upload if resuming fails', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -123,7 +123,7 @@ describe('tus', () => {

it('should create an upload using the creation-with-data extension', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('tus', () => {

it('should create an upload with partial data and continue', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -231,7 +231,7 @@ describe('tus', () => {

it("should add the request's body and ID to errors", async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('tus', () => {

it('should invoke the request and response callbacks', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
uploadUrl: 'http://tus.io/uploads/foo',
Expand Down Expand Up @@ -306,7 +306,7 @@ describe('tus', () => {

it('should throw an error if resuming fails and no endpoint is provided', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
uploadUrl: 'http://tus.io/uploads/resuming',
Expand All @@ -331,7 +331,7 @@ describe('tus', () => {

it('should resolve relative URLs', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io:1080/files/',
Expand Down Expand Up @@ -367,7 +367,7 @@ describe('tus', () => {

it('should upload a file in chunks', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -435,7 +435,7 @@ describe('tus', () => {

it('should add the original request to errors', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -468,7 +468,7 @@ describe('tus', () => {

it('should only create an upload for empty files', async () => {
const testStack = new TestHttpStack()
const file = getBlob('')
const file = ''
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -497,7 +497,7 @@ describe('tus', () => {

it('should not resume a finished upload', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -531,7 +531,7 @@ describe('tus', () => {

it('should resume an upload from a specified url', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -583,7 +583,7 @@ describe('tus', () => {

it('should resume a previously started upload', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -649,7 +649,7 @@ describe('tus', () => {

it('should override the PATCH method', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand Down Expand Up @@ -690,7 +690,7 @@ describe('tus', () => {

it('should emit an error if an upload is locked', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand All @@ -716,7 +716,7 @@ describe('tus', () => {

it('should emit an error if no Location header is presented', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/uploads',
Expand All @@ -742,7 +742,7 @@ describe('tus', () => {
})

it('should throw if retryDelays is not an array', () => {
const file = getBlob('hello world')
const file = 'hello world'
const upload = new tus.Upload(file, {
endpoint : 'http://endpoint/',
retryDelays: 44,
Expand All @@ -754,7 +754,7 @@ describe('tus', () => {
// response has the code 500 Internal Error, 423 Locked or 409 Conflict.
it('should retry the upload', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -843,7 +843,7 @@ describe('tus', () => {
// return value of onShouldRetry is true.
it('should retry the upload when onShouldRetry specified and returns true', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -942,7 +942,7 @@ describe('tus', () => {
// return value of onShouldRetry is false.
it('should not retry the upload when callback specified and returns false', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -973,7 +973,7 @@ describe('tus', () => {
})

it('should not retry if the error has not been caused by a request', async () => {
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : new TestHttpStack(),
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -1001,7 +1001,7 @@ describe('tus', () => {

it('should stop retrying after all delays have been used', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -1041,7 +1041,7 @@ describe('tus', () => {

it('should stop retrying when the abort function is called', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -1076,7 +1076,7 @@ describe('tus', () => {

it('should stop upload when the abort function is called during a callback', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -1124,7 +1124,7 @@ describe('tus', () => {

it('should stop upload when the abort function is called during the POST request', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack: testStack,
endpoint : 'http://tus.io/files/',
Expand Down Expand Up @@ -1160,7 +1160,7 @@ describe('tus', () => {

it('should reset the attempt counter if an upload proceeds', async () => {
const testStack = new TestHttpStack()
const file = getBlob('hello world')
const file = 'hello world'
const options = {
httpStack : testStack,
endpoint : 'http://tus.io/files/',
Expand Down
5 changes: 2 additions & 3 deletions test/spec/test-end-to-end.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const axios = require('axios')
const { getBlob } = require('./helpers/utils')
const tus = require('../..')

// Test timeout for end-to-end tests when uploading to real server.
Expand All @@ -11,7 +10,7 @@ describe('tus', () => {
describe('end-to-end', () => {
it('should upload to a real tus server', async () => {
return new Promise((resolve, reject) => {
const file = getBlob('hello world')
const file = 'hello world'
const options = {
endpoint: 'https://tusd.tusdemo.net/files/',
metadata: {
Expand Down Expand Up @@ -44,7 +43,7 @@ describe('tus', () => {

it('should upload to a real tus server with creation-with-upload', async () => {
return new Promise((resolve, reject) => {
const file = getBlob('hello world')
const file = 'hello world'
const options = {
endpoint: 'https://tusd.tusdemo.net/files/',
metadata: {
Expand Down
Loading