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

Adds support for base64 Files #95

Open
wants to merge 25 commits into
base: master
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
155 changes: 118 additions & 37 deletions dist/mobx-spine.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ function forNestedRelations(model, nestedRelations, fn) {
});
}

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};

var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
Expand Down Expand Up @@ -865,6 +871,17 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
}
return this[this.constructor.primaryKey];
}
}, {
key: 'getEncodedFile',
value: function getEncodedFile(file) {
// get the resource name from path
var id = this[this.constructor.primaryKey];

if (this.fileFields().includes(file) && id) {
return '' + lodash.result(this, 'urlRoot') + (id ? id + '/' : '') + file + '/?encode=true';
}
return '';
}
}, {
key: 'casts',
value: function casts() {
Expand Down Expand Up @@ -1385,6 +1402,13 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
}
return value;
}
}, {
key: 'uuidv4',
value: function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
});
}
}, {
key: 'saveFile',
value: function saveFile(name) {
Expand All @@ -1395,8 +1419,18 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
if (this.__fileChanges[name]) {
var file = this.__fileChanges[name];

// debugger;

var data = new FormData();
data.append(name, file, file.name);

if (this.isBase64(file)) {
var newfile = this.dataURItoBlob(file);
// file = `${URL.createObjectURL(blob)}`;
var fname = this.uuidv4() + '.png';
data.append(name, newfile, fname);
} else {
data.append(name, file, file.name);
}

return this.api.post('' + this.url + snakeName + '/', data, { headers: { 'Content-Type': 'multipart/form-data' } }).then(mobx.action(function (res) {
_this10.__fileExists[name] = true;
Expand All @@ -1423,43 +1457,38 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
return Promise.all(this.fileFields().filter(this.fieldFilter).map(this.saveFile));
}
}, {
key: 'save',
value: function save() {
var _this11 = this;

var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

this.clearValidationErrors();
return this.wrapPendingRequestCount(this.__getApi().saveModel({
url: options.url || this.url,
data: this.toBackend({
data: options.data,
mapData: options.mapData,
fields: options.fields,
onlyChanges: options.onlyChanges
}),
isNew: this.isNew,
requestOptions: lodash.omit(options, 'url', 'data', 'mapData')
}).then(mobx.action(function (res) {
_this11.saveFromBackend(_extends({}, res, {
data: lodash.omit(res.data, _this11.fileFields().map(camelToSnake))
}));
_this11.clearUserFieldChanges();
return _this11.saveFiles().then(function () {
_this11.clearUserFileChanges();
return Promise.resolve(res);
});
})).catch(mobx.action(function (err) {
if (err.valErrors) {
_this11.parseValidationErrors(err.valErrors);
}
throw err;
})));
key: 'isBase64',
value: function isBase64(str) {
if ((typeof str === 'undefined' ? 'undefined' : _typeof(str)) === 'object' || str === undefined || str === null) {
return false;
}
if (str === '' || str.trim() === '') {
return false;
}
str = str.replace(/^[^,]+,/, '');
try {
return btoa(atob(str)) === atob(btoa(str));
} catch (err) {
return false;
}
}
}, {
key: 'dataURItoBlob',
value: function dataURItoBlob(dataURI) {
var mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
var binary = atob(dataURI.split(',')[1]);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: mime });
}
}, {
key: 'setInput',
value: function setInput(name, value) {
invariant(this.__attributes.includes(name) || this.__activeCurrentRelations.includes(name), 'Field `' + name + '` does not exist on the model.');
this.isBase64File = false;

if (this.fileFields().includes(name)) {
if (this.__fileExists[name] === undefined) {
this.__fileExists[name] = this[name] !== null;
Expand All @@ -1468,7 +1497,14 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
this.__fileChanges[name] = value;
delete this.__fileDeletions[name];

value = URL.createObjectURL(value) + '?content_type=' + value.type;
this.isBase64File = this.isBase64(value);

if (!this.isBase64File) {
value = URL.createObjectURL(value) + '?content_type=' + value.type;
} else {
var blob = this.dataURItoBlob(value);
value = '' + URL.createObjectURL(blob);
}
} else {
if (!this.__fileChanges[name] || this.__fileChanges[name].existed) {
this.__fileDeletions[name] = true;
Expand Down Expand Up @@ -1533,8 +1569,53 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
return Promise.all(promises);
}
}, {
key: 'saveAll',
value: function saveAll() {
key: 'save',
value: function save() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

if (options.relations && options.relations.length > 0) {
return this._saveAll(options);
} else {
return this._save(options);
}
}
}, {
key: '_save',
value: function _save() {
var _this11 = this;

var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

this.clearValidationErrors();
return this.wrapPendingRequestCount(this.__getApi().saveModel({
url: options.url || this.url,
data: this.toBackend({
data: options.data,
mapData: options.mapData,
fields: options.fields,
onlyChanges: options.onlyChanges
}),
isNew: this.isNew,
requestOptions: lodash.omit(options, 'url', 'data', 'mapData')
}).then(mobx.action(function (res) {
_this11.saveFromBackend(_extends({}, res, {
data: lodash.omit(res.data, _this11.fileFields().map(camelToSnake))
}));
_this11.clearUserFieldChanges();
return _this11.saveFiles().then(function () {
_this11.clearUserFileChanges();
return Promise.resolve(res);
});
})).catch(mobx.action(function (err) {
if (err.valErrors) {
_this11.parseValidationErrors(err.valErrors);
}
throw err;
})));
}
}, {
key: '_saveAll',
value: function _saveAll() {
var _this12 = this;

var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Expand Down Expand Up @@ -1797,7 +1878,7 @@ var Model = (_class$1 = (_temp$1 = _class2$1 = function () {
initializer: function initializer() {
return {};
}
}), _applyDecoratedDescriptor$1(_class$1.prototype, 'url', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'url'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'isNew', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'isNew'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'isLoading', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'isLoading'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, '__parseRelations', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, '__parseRelations'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'hasUserChanges', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'hasUserChanges'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fieldFilter', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fieldFilter'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fromBackend', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fromBackend'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'parse', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'parse'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'save', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'save'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'setInput', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'setInput'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'saveAll', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'saveAll'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'parseValidationErrors', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'parseValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'clearValidationErrors', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'clearValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'backendValidationErrors', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'backendValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'delete', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'delete'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fetch', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fetch'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'clear', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'clear'), _class$1.prototype)), _class$1);
}), _applyDecoratedDescriptor$1(_class$1.prototype, 'url', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'url'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'isNew', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'isNew'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'isLoading', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'isLoading'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, '__parseRelations', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, '__parseRelations'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'hasUserChanges', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'hasUserChanges'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fieldFilter', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fieldFilter'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fromBackend', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fromBackend'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'parse', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'parse'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'setInput', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'setInput'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, '_save', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, '_save'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, '_saveAll', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, '_saveAll'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'parseValidationErrors', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'parseValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'clearValidationErrors', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'clearValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'backendValidationErrors', [mobx.computed], Object.getOwnPropertyDescriptor(_class$1.prototype, 'backendValidationErrors'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'delete', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'delete'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'fetch', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'fetch'), _class$1.prototype), _applyDecoratedDescriptor$1(_class$1.prototype, 'clear', [mobx.action], Object.getOwnPropertyDescriptor(_class$1.prototype, 'clear'), _class$1.prototype)), _class$1);

// Function ripped from Django docs.
// See: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
Expand Down
Loading