UNPKG

ra-data-firebase

Version:

Firebase data provider for React Admin

429 lines (419 loc) 17.8 kB
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var firebase = _interopDefault(require('firebase')); var sortBy = _interopDefault(require('sort-by')); var reactAdmin = require('react-admin'); var deepAssign = _interopDefault(require('deep-assign')); var getImageSize = function (file) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = function () { resolve({ width: this.width, height: this.height }); }; img.src = file.src; }); }; var upload = function (fieldName, submitedData, id, resourceName, resourcePath) { return new Promise(function ($return, $error) { var file, result; file = submitedData[fieldName] && Array.isArray(submitedData[fieldName]) ? submitedData[fieldName][0] : submitedData[fieldName]; result = {}; if (file && file.rawFile && file.rawFile.name) { var rawFile, ref, snapshot; rawFile = file.rawFile; ref = firebase.storage().ref().child((resourcePath + "/" + id + "/" + fieldName)); return ref.put(rawFile).then((function ($await_4) { try { snapshot = $await_4; result[fieldName] = [{}]; result[fieldName][0].uploadedAt = Date.now(); result[fieldName][0].src = snapshot.downloadURL.split('?').shift() + '?alt=media'; result[fieldName][0].type = rawFile.type; if (rawFile.type.indexOf('image/') === 0) { var $Try_1_Post = (function () { try { return $If_3.call(this); } catch ($boundEx) { return $error($boundEx); } }).bind(this); var $Try_1_Catch = function (e) { try { console.error("Failed to get image dimensions"); return $Try_1_Post(); } catch ($boundEx) { return $error($boundEx); } }; try { var imageSize; return getImageSize(file).then(function ($await_5) { try { imageSize = $await_5; result[fieldName][0].width = imageSize.width; result[fieldName][0].height = imageSize.height; return $Try_1_Post(); } catch ($boundEx) { return $Try_1_Catch($boundEx); } }, $Try_1_Catch); } catch (e) { $Try_1_Catch(e); } } function $If_3() { return $return(result); } return $If_3.call(this); } catch ($boundEx) { return $error($boundEx); } }).bind(this), $error); } return $return(false); }); }; var save = function (id, data, previous, resourceName, resourcePath, firebaseSaveFilter, uploadResults, isNew, metaFieldNames) { return new Promise(function ($return, $error) { var obj, obj$1, obj$2; var currentUser; currentUser = firebase.auth().currentUser; if (uploadResults) { uploadResults.map(function (uploadResult) { return uploadResult ? Object.assign(data, uploadResult) : false; }); } if (isNew) { Object.assign(data, ( obj = {}, obj[metaFieldNames.createdAt] = Date.now(), obj )); } if (currentUser) { Object.assign(data, ( obj$1 = {}, obj$1[metaFieldNames.createdBy] = currentUser.uid, obj$1 )); } data = Object.assign(previous, ( obj$2 = {}, obj$2[metaFieldNames.updatedAt] = Date.now(), obj$2 ), data); if (!data.key) { data.key = id; } if (!data.id) { data.id = id; } return firebase.database().ref((resourcePath + "/" + (data.key))).update(firebaseSaveFilter(data)).then(function ($await_6) { try { return $return({ data: data }); } catch ($boundEx) { return $error($boundEx); } }, $error); }); }; var del = function (id, resourceName, resourcePath, uploadFields) { return new Promise(function ($return, $error) { if (uploadFields.length) { uploadFields.map(function (fieldName) { return firebase.storage().ref().child((resourcePath + "/" + id + "/" + fieldName)).delete(); }); } return firebase.database().ref((resourcePath + "/" + id)).remove().then(function ($await_7) { try { return $return({ data: id }); } catch ($boundEx) { return $error($boundEx); } }, $error); }); }; var getItemID = function (params, type, resourceName, resourcePath, resourceData) { var itemId = params.data.id || params.id || params.data.key || params.key; if (!itemId) { itemId = firebase.database().ref().child(resourcePath).push().key; } if (!itemId) { throw new Error('ID is required'); } if (resourceData && resourceData[itemId] && type === reactAdmin.CREATE) { throw new Error('ID already in use'); } return itemId; }; var getOne = function (params, resourceName, resourceData) { if (params.id && resourceData[params.id]) { return { data: resourceData[params.id] }; } else { throw new Error('Key not found'); } }; var getMany = function (params, resourceName, resourceData) { var ids = []; var data = []; var total = 0; if (params.ids && Array.isArray(params.ids)) { params.ids.forEach(function (key) { if (resourceData[key]) { ids.push(key); data.push(resourceData[key]); total++; } }); return { total: total, ids: ids, data: data }; } else if (params.pagination) { var values = []; var filter = Object.assign({}, params.filter); if (params.target && params.id) { filter[params.target] = params.id; } var filterKeys = Object.keys(filter); if (filterKeys.length) { Object.values(resourceData).map(function (value) { var filterIndex = 0; while (filterIndex < filterKeys.length) { var property = filterKeys[filterIndex]; if (property !== 'q' && value[property] !== filter[property]) { return filterIndex; } else if (property === 'q') { if (JSON.stringify(value).indexOf(filter['q']) === -1) { return filterIndex; } } filterIndex++; } values.push(value); return filterIndex; }); } else { values = Object.values(resourceData); } if (params.sort) { values.sort(sortBy(("" + (params.sort.order === 'ASC' ? '-' : '') + (params.sort.field)))); } var keys = values.map(function (i) { return i.id; }); var ref = params.pagination; var page = ref.page; var perPage = ref.perPage; var _start = (page - 1) * perPage; var _end = page * perPage; data = values.slice(_start, _end); ids = keys.slice(_start, _end); total = values.length; return { data: data, ids: ids, total: total }; } else { throw new Error('Error processing request'); } }; var methods = { upload: upload, save: save, del: del, getItemID: getItemID, getOne: getOne, getMany: getMany }; var baseConfig = { initialQuerytimeout: 10000, metaFieldNames: { createdAt: 'createdAt', updatedAt: 'updatedAt', createdBy: 'createdBy' }, admin: { path: 'users', config: {}, validate: function () { return true; } }, debug: false, trackedResources: [], firebaseSaveFilter: function (data) { return data; }, firebaseGetFilter: function (data) { return data; } }; function dataProvider (options) { if ( options === void 0 ) options = {}; options = deepAssign({}, baseConfig, methods, options); var metaFieldNames = options.metaFieldNames; var trackedResources = options.trackedResources; var initialQuerytimeout = options.initialQuerytimeout; var debug = options.debug; var admin = options.admin; var firebaseSaveFilter = options.firebaseSaveFilter; var firebaseGetFilter = options.firebaseGetFilter; var upload = options.upload; var save = options.save; var del = options.del; var getItemID = options.getItemID; var getOne = options.getOne; var getMany = options.getMany; var resourcesStatus = {}; var resourcesReferences = {}; var resourcesData = {}; var resourcesPaths = {}; var resourcesUploadFields = {}; trackedResources.forEach(function (resource, index) { if (typeof resource === 'string') { resource = { name: resource, path: resource, uploadFields: [] }; trackedResources[index] = resource; } var name = resource.name; var path = resource.path; var uploadFields = resource.uploadFields; if (!name) { throw new Error(("name is missing from resource " + resource)); } resourcesUploadFields[name] = uploadFields || []; resourcesPaths[name] = path || name; resourcesData[name] = {}; }); var initializeResource = function (ref$1, resolve) { var name = ref$1.name; var isPublic = ref$1.isPublic; var ref = resourcesReferences[name] = firebase.database().ref(resourcesPaths[name]); resourcesData[name] = []; if (isPublic) { subscribeResource(ref, name, resolve); } else { firebase.auth().onAuthStateChanged(function (auth) { if (auth) { subscribeResource(ref, name, resolve); } }); } setTimeout(resolve, initialQuerytimeout); return true; }; var subscribeResource = function (ref, name, resolve) { ref.once('value', function (snapshot) { if (snapshot.key === name) { var entries = snapshot.val() || {}; Object.keys(entries).forEach(function (key) { resourcesData[name][key] = firebaseGetFilter(entries[key], name); }); Object.keys(resourcesData[name]).forEach(function (itemKey) { resourcesData[name][itemKey].id = itemKey; resourcesData[name][itemKey].key = itemKey; }); resolve(); } }); ref.on('child_added', function (snapshot) { resourcesData[name][snapshot.key] = firebaseGetFilter(Object.assign({}, { id: snapshot.key, key: snapshot.key }, snapshot.val()), name); }); ref.on('child_removed', function (oldsnapshot) { if (resourcesData[name][oldsnapshot.key]) { delete resourcesData[name][oldsnapshot.key]; } }); ref.on('child_changed', function (snapshot) { resourcesData[name][snapshot.key] = snapshot.val(); }); }; trackedResources.forEach(function (resource) { resourcesStatus[resource.name] = new Promise(function (resolve) { initializeResource(resource, resolve); }); }); return function (type, resourceName, params) { return new Promise(function ($return, $error) { var uploadFields, uploads, currentData, uploadResults; var result, itemId; debug && console.log(type, resourceName, params); return resourcesStatus[resourceName].then((function ($await_4) { try { result = null; itemId = null; switch (type) { case reactAdmin.GET_LIST: case reactAdmin.GET_MANY: case reactAdmin.GET_MANY_REFERENCE: result = getMany(params, resourceName, resourcesData[resourceName]); return $return(result); case reactAdmin.GET_ONE: result = getOne(params, resourceName, resourcesData[resourceName]); return $return(result); case reactAdmin.DELETE: uploadFields = resourcesUploadFields[resourceName] ? resourcesUploadFields[resourceName] : []; return del(params.id, resourceName, resourcesPaths[resourceName], uploadFields).then(function ($await_5) { try { result = $await_5; return $return(result); } catch ($boundEx) { return $error($boundEx); } }, $error); case reactAdmin.UPDATE: case reactAdmin.CREATE: if (admin && admin.path === resourceName && type === reactAdmin.CREATE && params.data && params.data.email && params.data.password && admin.validate(params.data)) { var $Try_1_Post = (function () { try { return $If_3.call(this); } catch ($boundEx) { return $error($boundEx); } }).bind(this); var $Try_1_Catch = function (error) { try { return $return(Promise.reject(new Error(error))); } catch ($boundEx) { return $error($boundEx); } }; try { var app, user; app = firebase.initializeApp(admin.config, 'user-admin'); return app.auth().createUserWithEmailAndPassword(params.data.email, params.data.password).then(function ($await_6) { try { user = $await_6; itemId = user.uid; app.auth().signOut(); return $Try_1_Post(); } catch ($boundEx) { return $Try_1_Catch($boundEx); } }, $Try_1_Catch); } catch (error) { $Try_1_Catch(error); } } else { itemId = getItemID(params, type, resourceName, resourcesPaths[resourceName], resourcesData[resourceName]); return $If_3.call(this); } function $If_3() { uploads = resourcesUploadFields[resourceName] ? resourcesUploadFields[resourceName].map(function (field) { return upload(field, params.data, itemId, resourceName, resourcesPaths[resourceName]); }) : []; currentData = resourcesData[resourceName][itemId] || {}; return Promise.all(uploads).then(function ($await_7) { try { uploadResults = $await_7; return save(itemId, params.data, currentData, resourceName, resourcesPaths[resourceName], firebaseSaveFilter, uploadResults, type === reactAdmin.CREATE, metaFieldNames).then(function ($await_8) { try { result = $await_8; return $return(result); } catch ($boundEx) { return $error($boundEx); } }, $error); } catch ($boundEx) { return $error($boundEx); } }, $error); } default: debug && console.error('Undocumented method: ', type); return $return({ data: [] }); } return $return(); } catch ($boundEx) { return $error($boundEx); } }).bind(this), $error); }); }; } exports.FirebaseDataProvider = dataProvider; exports.methods = methods; //# sourceMappingURL=ra-data-firebase.js.map