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

Add support for creating headers using Promise #553

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
19 changes: 13 additions & 6 deletions resumable.d.ts
Original file line number Diff line number Diff line change
@@ -78,9 +78,9 @@ declare namespace Resumable {
**/
parameterNamespace?: string;
/**
* Extra headers to include in the multipart POST with data. This can be an object or a function that allows you to construct and return a value, based on supplied file (Default: {})
* Extra headers to include in the multipart POST with data. This can be an object or a function that allows you to construct and return a value or a Promise, based on supplied file (Default: {})
**/
headers?: Object | ((file: ResumableFile) => Object);
headers?: Object | ((file: ResumableFile) => Object) | ((file) => Promise<Object>);
/**
* Method to use when POSTing chunks to the server (multipart or octet) (Default: multipart)
**/
@@ -141,6 +141,10 @@ declare namespace Resumable {
* The number of milliseconds to wait before retrying a chunk on a non-permanent error. Valid values are any positive integer and undefined for immediate retry. (Default: undefined)
**/
chunkRetryInterval?: number;
/**
* List of error codes that will immediately terminate the file upload
*/
permanentErrors?: number[];
/**
* Standard CORS requests do not send or set any cookies by default. In order to include cookies as part of the request, you need to set the withCredentials property to true. (Default: false)
**/
@@ -205,7 +209,7 @@ declare namespace Resumable {
/**
* Add a HTML5 File object to the list of files.
**/
addFile(file: File, event: Event): void;
addFile(file: File, event?: Event): void;
/**
* Cancel upload of a specific ResumableFile object on the list from the list.
**/
@@ -250,11 +254,11 @@ declare namespace Resumable {
/**
* Something went wrong during upload of a specific file, uploading is being retried.
**/
on(event: 'fileRetry', callback: (file: ResumableFile) => void): void;
on(event: 'fileRetry', callback: (file: ResumableFile, message: string, chunk: ResumableChunk) => void): void;
/**
* An error occurred during upload of a specific file.
**/
on(event: 'fileError', callback: (file: ResumableFile, message: string) => void): void;
on(event: 'fileError', callback: (file: ResumableFile, message: string, chunk: ResumableChunk) => void): void;
/**
* Upload has been started on the Resumable object.
**/
@@ -366,7 +370,10 @@ declare namespace Resumable {
isComplete: () => boolean;
}

interface ResumableChunk { }
interface ResumableChunk {
offset: number;
retries: number;
}
}

declare module 'resumablejs' {
68 changes: 56 additions & 12 deletions resumable.js
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@
}
};
$.indexOf = function(array, obj) {
if (array.indexOf) { return array.indexOf(obj); }
if (array.indexOf) { return array.indexOf(obj); }
for (var i = 0; i < array.length; i++) {
if (array[i] === obj) { return i; }
}
@@ -215,6 +215,9 @@
if (joinedParams) target = target + separator + joinedParams;

return target;
},
isPromise: function(o){
return o && typeof o.then === 'function'
}
};

@@ -450,7 +453,7 @@
}
// directories have size == 0
var uniqueIdentifier = $h.generateUniqueIdentifier(file, event);
if(uniqueIdentifier && typeof uniqueIdentifier.then === 'function'){
if($h.isPromise(uniqueIdentifier)){
// Promise or Promise-like object provided as unique identifier
uniqueIdentifier
.then(
@@ -499,7 +502,7 @@
$.abort();
_error = true;
$.chunks = [];
$.resumableObj.fire('fileError', $, message);
$.resumableObj.fire('fileError', $, message, this);
break;
case 'success':
if(_error) return;
@@ -509,7 +512,7 @@
}
break;
case 'retry':
$.resumableObj.fire('fileRetry', $);
$.resumableObj.fire('fileRetry', $, message, this);
break;
}
};
@@ -670,6 +673,7 @@
$.lastProgressCallback = (new Date);
$.tested = false;
$.retries = 0;
$.headersErr = false;
$.pendingRetry = false;
$.preprocessState = 0; // 0 = unprocessed, 1 = processing, 2 = finished
$.markComplete = false;
@@ -747,10 +751,25 @@
if(typeof customHeaders === 'function') {
customHeaders = customHeaders($.fileObj, $);
}
$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(null);
if($h.isPromise(customHeaders)) {
$.headersErr = false;
customHeaders
.then(headers => {
$h.each(headers, function (k, v) {
$.xhr.setRequestHeader(k, v)
})
$.xhr.send(null)
})
.catch(() => {
$.headersErr = true;
testHandler()
})
} else {
$h.each(customHeaders, function (k, v) {
$.xhr.setRequestHeader(k, v);
});
$.xhr.send(null);
}
};

$.preprocessFinished = function(){
@@ -798,6 +817,7 @@
$.callback('retry', $.message());
$.abort();
$.retries++;
$.headersErr = false;
var retryInterval = $.getOpt('chunkRetryInterval');
if(retryInterval !== undefined) {
$.pendingRetry = true;
@@ -886,12 +906,29 @@
customHeaders = customHeaders($.fileObj, $);
}

$h.each(customHeaders, function(k,v) {
$.xhr.setRequestHeader(k, v);
});
if($h.isPromise(customHeaders)) {
$.headersErr = false;
customHeaders
.then(headers => {
$h.each(headers, function (k, v) {
$.xhr.setRequestHeader(k, v)
})
if ($.getOpt('chunkFormat') == 'blob') {
$.xhr.send(data)
}
})
.catch(() => {
$.headersErr = true;
doneHandler()
})
} else {
$h.each(customHeaders, function (k, v) {
$.xhr.setRequestHeader(k, v);
});

if ($.getOpt('chunkFormat') == 'blob') {
if ($.getOpt('chunkFormat') == 'blob') {
$.xhr.send(data);
}
}
};
$.abort = function(){
@@ -901,6 +938,13 @@
};
$.status = function(){
// Returns: 'pending', 'uploading', 'success', 'error'
if($.headersErr) {
if($.retries >= $.getOpt('maxChunkRetries')) {
return 'error';
}
$.abort();
return 'pending';
}
if($.pendingRetry) {
// if pending retry then that's effectively the same as actively uploading,
// there might just be a slight delay before the retry starts