196 lines
7.2 KiB
JavaScript
196 lines
7.2 KiB
JavaScript
|
window.EEPROM = (() => {
|
||
|
const errGeneric = 'generic';
|
||
|
const errInvalid = 'invalid';
|
||
|
const errAuth = 'auth';
|
||
|
const errAccess = 'access';
|
||
|
const errDMCA = 'dmca';
|
||
|
const errGone = 'gone';
|
||
|
const errSize = 'size';
|
||
|
const errServer = 'server';
|
||
|
|
||
|
const createClient = function(srcId, endPoint, authorization) {
|
||
|
if(typeof srcId !== 'number')
|
||
|
srcId = parseInt(srcId);
|
||
|
if(typeof endPoint !== 'string')
|
||
|
throw 'endPoint must be a string';
|
||
|
if(typeof authorization !== 'string' && typeof authorization !== 'function')
|
||
|
throw 'authorization must be a string or a function returning a string';
|
||
|
|
||
|
const createUpload = file => {
|
||
|
const uploadTask = { onComplete: undefined, onFailure: undefined, onProgress: undefined };
|
||
|
let userAborted = false;
|
||
|
|
||
|
const xhr = new XMLHttpRequest;
|
||
|
const fd = new FormData;
|
||
|
|
||
|
fd.append('src', srcId);
|
||
|
fd.append('file', file);
|
||
|
|
||
|
const reportUploadProgress = ev => {
|
||
|
if(typeof uploadTask.onProgress === 'function')
|
||
|
uploadTask.onProgress({
|
||
|
loaded: ev.loaded,
|
||
|
total: ev.total,
|
||
|
progress: Math.ceil((ev.loaded / ev.total) * 100),
|
||
|
});
|
||
|
};
|
||
|
|
||
|
xhr.upload.addEventListener('loadstart', reportUploadProgress);
|
||
|
xhr.upload.addEventListener('progress', reportUploadProgress);
|
||
|
xhr.upload.addEventListener('load', reportUploadProgress);
|
||
|
|
||
|
xhr.addEventListener('readystatechange', () => {
|
||
|
if(xhr.readyState !== 4)
|
||
|
return;
|
||
|
|
||
|
if(xhr.status !== 201) {
|
||
|
const failureResponse = {
|
||
|
userAborted: userAborted,
|
||
|
error: errGeneric,
|
||
|
};
|
||
|
|
||
|
switch(xhr.status) {
|
||
|
case 400:
|
||
|
case 405:
|
||
|
failureResponse.error = errInvalid;
|
||
|
break;
|
||
|
case 401:
|
||
|
failureResponse.error = errAuth;
|
||
|
break;
|
||
|
case 403:
|
||
|
failureResponse.error = errAccess;
|
||
|
break;
|
||
|
case 404:
|
||
|
case 410:
|
||
|
failureResponse.error = errGone;
|
||
|
break;
|
||
|
case 451:
|
||
|
failureResponse.error = errDMCA;
|
||
|
break;
|
||
|
case 413:
|
||
|
failureResponse.error = errSize;
|
||
|
failureResponse.maxSize = parseInt(xhr.getResponseHeader('X-EEPROM-Max-Size'));
|
||
|
break;
|
||
|
case 500:
|
||
|
case 503:
|
||
|
failureResponse.error = errServer;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(typeof uploadTask.onFailure === 'function')
|
||
|
uploadTask.onFailure(failureResponse);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(typeof uploadTask.onComplete === 'function') {
|
||
|
const fileInfo = JSON.parse(xhr.responseText);
|
||
|
if(typeof fileInfo !== 'object') {
|
||
|
if(typeof uploadTask.onFailure === 'function')
|
||
|
uploadTask.onFailure({
|
||
|
userAborted: userAborted,
|
||
|
error: errServer,
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
fileInfo.isImage = () => typeof fileInfo.type === 'string' && fileInfo.type.indexOf('image/') === 0;
|
||
|
fileInfo.isVideo = () => typeof fileInfo.type === 'string' && fileInfo.type.indexOf('video/') === 0;
|
||
|
fileInfo.isAudio = () => typeof fileInfo.type === 'string' && (fileInfo.type === 'application/x-font-gdos' || fileInfo.type.indexOf('audio/') === 0);
|
||
|
fileInfo.isMedia = () => typeof fileInfo.type === 'string' && (fileInfo.isImage() || fileInfo.isAudio() || fileInfo.isVideo());
|
||
|
|
||
|
uploadTask.onComplete(fileInfo);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
uploadTask.abort = () => {
|
||
|
userAborted = true;
|
||
|
xhr.abort();
|
||
|
};
|
||
|
|
||
|
uploadTask.start = () => {
|
||
|
xhr.open('POST', endPoint);
|
||
|
|
||
|
const authIsFunc = typeof authorization === 'function';
|
||
|
if(authIsFunc || typeof authorization === 'string')
|
||
|
xhr.setRequestHeader('Authorization', authIsFunc ? authorization() : authorization);
|
||
|
else
|
||
|
xhr.withCredentials = true;
|
||
|
|
||
|
xhr.send(fd);
|
||
|
};
|
||
|
|
||
|
return uploadTask;
|
||
|
};
|
||
|
|
||
|
const deleteUpload = fileInfo => {
|
||
|
const deleteTask = { onSuccess: undefined, onFailure: undefined };
|
||
|
|
||
|
const xhr = new XMLHttpRequest;
|
||
|
xhr.addEventListener('readystatechange', () => {
|
||
|
if(xhr.readyState !== 4)
|
||
|
return;
|
||
|
|
||
|
if(xhr.status !== 204) {
|
||
|
let errorCode = errGeneric;
|
||
|
|
||
|
switch(xhr.status) {
|
||
|
case 401:
|
||
|
errorCode = errAuth;
|
||
|
break;
|
||
|
case 403:
|
||
|
errorCode = errAccess;
|
||
|
break;
|
||
|
case 404:
|
||
|
case 410:
|
||
|
errorCode = errGone;
|
||
|
break;
|
||
|
case 500:
|
||
|
case 503:
|
||
|
errorCode = errServer;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(typeof deleteTask.onFailure === 'function')
|
||
|
deleteTask.onFailure(errorCode);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(typeof deleteTask.onSuccess === 'function')
|
||
|
deleteTask.onSuccess();
|
||
|
});
|
||
|
|
||
|
deleteTask.start = () => {
|
||
|
xhr.open('DELETE', fileInfo.urlf);
|
||
|
|
||
|
const authIsFunc = typeof authorization === 'function';
|
||
|
if(authIsFunc || typeof authorization === 'string')
|
||
|
xhr.setRequestHeader('Authorization', authIsFunc ? authorization() : authorization);
|
||
|
else
|
||
|
xhr.withCredentials = true;
|
||
|
|
||
|
xhr.send();
|
||
|
};
|
||
|
|
||
|
return deleteTask;
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
createUpload: createUpload,
|
||
|
deleteUpload: deleteUpload,
|
||
|
};
|
||
|
};
|
||
|
|
||
|
Object.defineProperties(createClient, {
|
||
|
ERR_GENERIC: { value: errGeneric },
|
||
|
ERR_INVALID: { value: errInvalid },
|
||
|
ERR_AUTH: { value: errAuth },
|
||
|
ERR_ACCESS: { value: errAccess },
|
||
|
ERR_DMCA: { value: errDMCA },
|
||
|
ERR_GONE: { value: errGone },
|
||
|
ERR_SERVER: { value: errServer },
|
||
|
ERR_SIZE: { value: errSize },
|
||
|
});
|
||
|
|
||
|
return createClient;
|
||
|
})();
|