2024-02-02 21:00:24 +00:00
|
|
|
#include bytefmt.js
|
|
|
|
#include xhr.js
|
|
|
|
|
|
|
|
const EEPROM = function(appId, endPoint, auth) {
|
|
|
|
if(typeof appId !== 'string')
|
|
|
|
appId = (appId || '').toString();
|
|
|
|
if(typeof endPoint !== 'string')
|
|
|
|
throw 'endPoint must be a string';
|
|
|
|
|
|
|
|
const applyAuth = options => {
|
|
|
|
if(typeof auth === 'function')
|
|
|
|
options.headers.Authorization = auth();
|
|
|
|
else if(typeof auth === 'string')
|
|
|
|
options.headers.Authorization = auth;
|
|
|
|
else
|
|
|
|
options.authed = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
const createUpload = fileInput => {
|
|
|
|
if(!(fileInput instanceof File))
|
|
|
|
throw 'fileInput must be an instance of window.File';
|
|
|
|
|
|
|
|
let userAborted = false;
|
|
|
|
let abortHandler, progressHandler;
|
|
|
|
|
|
|
|
const reportProgress = ev => {
|
|
|
|
if(progressHandler !== undefined)
|
|
|
|
progressHandler({
|
|
|
|
loaded: ev.loaded,
|
|
|
|
total: ev.total,
|
|
|
|
progress: ev.total <= 0 ? 0 : ev.loaded / ev.total,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const uploadAbortedError = () => {
|
|
|
|
return {
|
|
|
|
error: 'eeprom:aborted_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'File upload was aborted manually.',
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const uploadGenericError = () => {
|
|
|
|
return {
|
|
|
|
error: 'eeprom:generic_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'File upload failed for unknown reasons.',
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
abort: () => {
|
|
|
|
userAborted = true;
|
|
|
|
if(abortHandler !== undefined)
|
|
|
|
abortHandler();
|
|
|
|
},
|
|
|
|
onProgress: handler => {
|
|
|
|
if(typeof handler !== 'function')
|
|
|
|
throw 'handler must be a function';
|
|
|
|
progressHandler = handler;
|
|
|
|
},
|
|
|
|
start: async () => {
|
|
|
|
if(userAborted)
|
|
|
|
throw uploadAbortedError();
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
type: 'json',
|
|
|
|
headers: {},
|
|
|
|
upload: reportProgress,
|
|
|
|
abort: handler => abortHandler = handler,
|
|
|
|
};
|
|
|
|
|
|
|
|
applyAuth(options);
|
|
|
|
|
|
|
|
const formData = new FormData;
|
|
|
|
formData.append('src', appId);
|
|
|
|
formData.append('file', fileInput);
|
|
|
|
|
|
|
|
try {
|
|
|
|
const result = await EEPXHR.post(`${endPoint}/uploads`, options, formData);
|
|
|
|
|
|
|
|
if(result.status !== 201) {
|
|
|
|
if(result.status === 400)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:request_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'There was an error with the upload request.',
|
|
|
|
};
|
|
|
|
if(result.status === 401)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:auth_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'Could not authenticate upload request. If this persists, try refreshing the page.',
|
|
|
|
};
|
|
|
|
if(result.status === 403)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:access_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'You are not allowed to upload files.',
|
|
|
|
};
|
|
|
|
if(result.status === 404)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:app_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'EEPROM app is not configured properly.',
|
|
|
|
};
|
|
|
|
if(result.status === 413) {
|
2024-02-02 21:34:17 +00:00
|
|
|
const maxSize = parseInt(result.headers().get('x-eeprom-max-size'));
|
2024-02-02 21:00:24 +00:00
|
|
|
const maxSizeFormatted = EEPFMT.format(maxSize);
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:size_error',
|
|
|
|
maxSize: maxSize,
|
|
|
|
maxSizeFormatted: maxSizeFormatted,
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => maxSize < 1 ? 'Uploaded file was too large.' : `Uploads may not be larger than ${maxSizeFormatted}.`,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if(result.status === 451)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:dmca_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'This file is blocked from being uploaded, possibly for copyright reasons.',
|
|
|
|
};
|
|
|
|
if(result.status === 500)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:server_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'An error occurred within the EEPROM server. If this persists, report it to a developer.',
|
|
|
|
};
|
|
|
|
if(result.status === 503)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:maintenance_error',
|
|
|
|
aborted: userAborted,
|
|
|
|
toString: () => 'EEPROM server is temporarily unavailable for maintenance.',
|
|
|
|
};
|
|
|
|
|
|
|
|
throw uploadGenericError();
|
|
|
|
}
|
|
|
|
|
|
|
|
const fileInfo = result.body();
|
|
|
|
|
|
|
|
if(typeof fileInfo.type === 'string') {
|
|
|
|
fileInfo.isImage = () => fileInfo.type.indexOf('image/') === 0;
|
|
|
|
fileInfo.isVideo = () => fileInfo.type.indexOf('video/') === 0;
|
|
|
|
fileInfo.isAudio = () => fileInfo.type === 'application/x-font-gdos' || fileInfo.type.indexOf('audio/') === 0;
|
|
|
|
} else
|
|
|
|
fileInfo.isImage = fileInfo.isVideo = fileInfo.isAudio = () => false;
|
|
|
|
|
|
|
|
fileInfo.isMedia = () => fileInfo.isImage() || fileInfo.isAudio() || fileInfo.isVideo();
|
|
|
|
|
|
|
|
return Object.freeze(fileInfo);
|
|
|
|
} catch(ex) {
|
|
|
|
if(!ex.abort) {
|
|
|
|
console.error(ex);
|
2024-02-02 21:30:59 +00:00
|
|
|
throw ex;
|
2024-02-02 21:00:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
throw uploadAbortedError();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const deleteUpload = async fileInfo => {
|
|
|
|
if(typeof fileInfo !== 'object')
|
|
|
|
throw 'fileInfo must be an object';
|
|
|
|
if(typeof fileInfo.urlf !== 'string')
|
|
|
|
throw 'fileInfo.urlf must be a string';
|
|
|
|
|
|
|
|
const options = { headers: {} };
|
|
|
|
applyAuth(options);
|
|
|
|
|
|
|
|
const result = await EEPXHR.delete(fileInfo.urlf, options);
|
|
|
|
|
|
|
|
if(result.status !== 204) {
|
|
|
|
if(result.status === 401)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:auth_error',
|
|
|
|
toString: () => 'Could not authenticate delete request. If this persists, try refreshing the page.',
|
|
|
|
};
|
|
|
|
if(result.status === 403)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:access_error',
|
|
|
|
toString: () => 'You are not allowed to delete this file.',
|
|
|
|
};
|
|
|
|
if(result.status === 404)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:file_error',
|
|
|
|
toString: () => 'File not found.',
|
|
|
|
};
|
|
|
|
if(result.status === 500)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:server_error',
|
|
|
|
toString: () => 'An error occurred within the EEPROM server. If this persists, report it to a developer.',
|
|
|
|
};
|
|
|
|
if(result.status === 503)
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:maintenance_error',
|
|
|
|
toString: () => 'EEPROM server is temporarily unavailable for maintenance.',
|
|
|
|
};
|
|
|
|
|
|
|
|
throw {
|
|
|
|
error: 'eeprom:generic_error',
|
|
|
|
toString: () => 'File delete failed for unknown reasons.',
|
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
create: createUpload,
|
|
|
|
delete: deleteUpload,
|
|
|
|
};
|
|
|
|
};
|