Socket
Socket
Sign inDemoInstall

firestore-export-import

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

firestore-export-import - npm Package Compare versions

Comparing version 0.3.3 to 0.3.4

14

CHANGELOG.md

@@ -14,3 +14,3 @@ # Change log

## [0.3.3] - 2020-01-03
## [0.3.4] - 2020-03-17

@@ -20,2 +20,14 @@ #### - :nail_care: [Polish]

- Update new packages
- Fixed security package: minimist
#### - :rocket: [New Feature]
- Supported import array of references
- Supported multi sub collections
## [0.3.3] - 2020-03-10
#### - :nail_care: [Polish]
- Update new packages
- Check app before initializing

@@ -22,0 +34,0 @@

14

dist/import.js

@@ -14,11 +14,13 @@ "use strict";var __awaiter=(this&&this.__awaiter)||function(thisArg,_arguments,P,generator){function adopt(value){return value instanceof P?value:new P(function(resolve){resolve(value);});}

else
return acc[cur]||{};},documentObj);});};exports.restore=function(fileName,options){var db=admin.firestore();return new Promise(function(resolve,reject){if(typeof fileName==='object'){var dataArray=fileName;updateCollection(db,dataArray,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});}
return acc[cur]||{};},documentObj);});};exports.restore=function(fileName,options){var db=admin.firestore();return new Promise(function(resolve,reject){if(typeof fileName==='object'){var dataObj=fileName;updateCollection(db,dataObj,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});}
else{fs.readFile(fileName,'utf8',function(err,data){if(err){console.log(err);reject({status:false,message:err.message});}
var dataArray=JSON.parse(data);updateCollection(db,dataArray,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});});}}).catch(function(error){return console.error(error);});};var updateCollection=function(db,dataArray,options){if(options===void 0){options={};}
return __awaiter(void 0,void 0,void 0,function(){var _a,_b,_i,index,collectionName,_c,_d,_e,doc,docId,subCollections;return __generator(this,function(_f){switch(_f.label){case 0:_a=[];for(_b in dataArray)
_a.push(_b);_i=0;_f.label=1;case 1:if(!(_i<_a.length))return[3,9];index=_a[_i];collectionName=index;_c=[];for(_d in dataArray[index])
_c.push(_d);_e=0;_f.label=2;case 2:if(!(_e<_c.length))return[3,8];doc=_c[_e];if(!dataArray[index].hasOwnProperty(doc))return[3,7];docId=Array.isArray(dataArray[index])?uuid_1.v1():doc;if(!dataArray[index][doc]['subCollection'])return[3,5];subCollections=dataArray[index][docId]['subCollection'];delete dataArray[index][doc]['subCollection'];return[4,startUpdating(db,collectionName,docId,dataArray[index][doc],options)];case 3:_f.sent();return[4,updateCollection(db,subCollections)];case 4:_f.sent();return[3,7];case 5:return[4,startUpdating(db,collectionName,docId,dataArray[index][doc],options)];case 6:_f.sent();_f.label=7;case 7:_e++;return[3,2];case 8:_i++;return[3,1];case 9:return[2];}});});};var startUpdating=function(db,collectionName,docId,data,options){if(options.dates&&options.dates.length>0){updateTime(options.dates,data);}
if(options.refs&&options.refs.length>0){options.refs.forEach(function(ref){if(data.hasOwnProperty(ref)){data[ref]=db.doc(data[ref]);}});}
var dataObj=JSON.parse(data);updateCollection(db,dataObj,options).then(function(){resolve({status:true,message:'Collection successfully imported!'});}).catch(function(error){reject({status:false,message:error.message});});});}}).catch(function(error){return console.error(error);});};var updateCollection=function(db,dataObj,options){if(options===void 0){options={};}
return __awaiter(void 0,void 0,void 0,function(){var _a,_b,_i,index,collectionName,_c,_d,_e,doc,docId,subCollections,subCollections,_f,_g,_h,subIndex,revivedSubCollection,subCollectionPath;return __generator(this,function(_j){switch(_j.label){case 0:_a=[];for(_b in dataObj)
_a.push(_b);_i=0;_j.label=1;case 1:if(!(_i<_a.length))return[3,13];index=_a[_i];collectionName=index;_c=[];for(_d in dataObj[index])
_c.push(_d);_e=0;_j.label=2;case 2:if(!(_e<_c.length))return[3,12];doc=_c[_e];if(!dataObj[index].hasOwnProperty(doc))return[3,11];docId=Array.isArray(dataObj[index])?uuid_1.v1():doc;if(!!Array.isArray(dataObj[index]))return[3,6];subCollections=dataObj[index][docId]['subCollection'];delete dataObj[index][doc]['subCollection'];return[4,startUpdating(db,collectionName,docId,dataObj[index][doc],options)];case 3:_j.sent();if(!subCollections)return[3,5];return[4,updateCollection(db,subCollections,options)];case 4:_j.sent();_j.label=5;case 5:return[3,11];case 6:subCollections=dataObj[index][doc]['subCollection'];delete dataObj[index][doc]['subCollection'];return[4,startUpdating(db,collectionName,docId,dataObj[index][doc],options)];case 7:_j.sent();if(!subCollections)return[3,11];_f=[];for(_g in subCollections)
_f.push(_g);_h=0;_j.label=8;case 8:if(!(_h<_f.length))return[3,11];subIndex=_f[_h];revivedSubCollection={};subCollectionPath=collectionName+"/"+docId+"/"+subIndex;revivedSubCollection[subCollectionPath]=subCollections[subIndex];return[4,updateCollection(db,revivedSubCollection,options)];case 9:_j.sent();_j.label=10;case 10:_h++;return[3,8];case 11:_e++;return[3,2];case 12:_i++;return[3,1];case 13:return[2];}});});};var startUpdating=function(db,collectionName,docId,data,options){if(options.dates&&options.dates.length>0){updateTime(options.dates,data);}
if(options.refs&&options.refs.length>0){options.refs.forEach(function(ref){if(data.hasOwnProperty(ref)){if(Array.isArray(data[ref])){data[ref]=data[ref].map(function(ref){return db.doc(ref);});}
else{data[ref]=db.doc(data[ref]);}}});}
if(options.geos&&options.geos.length>0){options.geos.forEach(function(geo){if(data.hasOwnProperty(geo)){data[geo]=new admin.firestore.GeoPoint(data[geo]._latitude,data[geo]._longitude);}
else{console.warn('Please check your geo parameters!!!',options.geos);}});}
return new Promise(function(resolve,reject){db.collection(collectionName).doc(docId).set(data).then(function(){console.log(docId+" was successfully added to firestore!");resolve({status:true,message:docId+" was successfully added to firestore!"});}).catch(function(error){console.log(error);reject({status:false,message:error.message});});});};
{
"name": "firestore-export-import",
"version": "0.3.3",
"version": "0.3.4",
"description": "NPM package for backup and restore Firebase Firestore",

@@ -31,7 +31,8 @@ "main": "dist/index.js",

"devDependencies": {
"@types/chai": "^4.2.10",
"@types/chai": "^4.2.11",
"@types/mocha": "^7.0.2",
"@types/node": "^13.9.0",
"@types/node": "^13.9.1",
"chai": "^4.2.0",
"jsmin": "^1.0.1",
"minimist": "^1.2.5",
"mocha": "^7.1.0",

@@ -44,4 +45,7 @@ "request": "^2.88.2",

"dependencies": {
"firebase-admin": "^8.9.2"
"firebase-admin": "^8.10.0"
},
"resolutions": {
"minimist": "1.2.5"
},
"engines": {

@@ -48,0 +52,0 @@ "node": ">=7.6.0"

@@ -38,7 +38,7 @@ # firestore-export-import

const firestoreService = require('firestore-export-import');
const serviceAccount = require('./serviceAccountKey.json');
const firestoreService = require('firestore-export-import')
const serviceAccount = require('./serviceAccountKey.json')
// Initiate Firebase App
firestoreService.initializeApp(serviceAccount, databaseURL);
firestoreService.initializeApp(serviceAccount, databaseURL)

@@ -48,3 +48,3 @@ // Start exporting your data

.backup('collection-name')
.then(data => console.log(JSON.stringify(data)));
.then(data => console.log(JSON.stringify(data)))
```

@@ -67,4 +67,4 @@

// You can do whatever you want with collections
console.log(JSON.stringify(collections));
});
console.log(JSON.stringify(collections))
})
```

@@ -97,3 +97,3 @@

refs: ['refKey']
};
}
```

@@ -106,15 +106,15 @@

const firestoreService = require('firestore-export-import');
const serviceAccount = require('./serviceAccountKey.json');
const firestoreService = require('firestore-export-import')
const serviceAccount = require('./serviceAccountKey.json')
// Initiate Firebase App
firestoreService.initializeApp(serviceAccount, databaseURL);
firestoreService.initializeApp(serviceAccount, databaseURL)
// Start importing your data
// The array of date and location fields are optional
// The array of date, location and reference fields are optional
firestoreService.restore('your-file-path.json', {
dates: ['date1', 'date1.date2', 'date1.date2.date3'],
geos: ['location1', 'location2'],
refs: ['refKey']
});
refs: ['refKey', 'arrayRef']
})
```

@@ -169,2 +169,3 @@

"secondRef": "test/second-key",
"arrayRef": ["test/second-key", "test/second-key"],
"subCollection": {

@@ -213,3 +214,15 @@ "test/first-key/details": {

"name": "Dale Nguyen",
"email": "dale@dalenguyen.me"
"email": "dale@dalenguyen.me",
"subCollection": {
"details": [
{
"dogId": "2",
"dogName": "hello"
},
{
"dogName": "lala",
"dogId": "2"
}
]
}
},

@@ -216,0 +229,0 @@ {

@@ -1,9 +0,9 @@

import * as fs from 'fs';
import { v1 as uuidv1 } from 'uuid';
import * as admin from 'firebase-admin';
import * as fs from 'fs'
import { v1 as uuidv1 } from 'uuid'
import * as admin from 'firebase-admin'
export interface IImportOptions {
dates?: string[];
geos?: string[];
refs?: string[];
dates?: string[]
geos?: string[]
refs?: string[]
}

@@ -20,7 +20,7 @@

if (!a[i + 1] && acc[cur] && acc[cur]._seconds) {
acc[cur] = new Date(acc[cur]._seconds * 1000);
} else return acc[cur] || {};
}, documentObj);
});
};
acc[cur] = new Date(acc[cur]._seconds * 1000)
} else return acc[cur] || {}
}, documentObj)
})
}

@@ -37,9 +37,9 @@ /**

): Promise<any> => {
const db = admin.firestore();
const db = admin.firestore()
return new Promise((resolve, reject) => {
if (typeof fileName === 'object') {
let dataArray = fileName;
let dataObj = fileName
updateCollection(db, dataArray, options)
updateCollection(db, dataObj, options)
.then(() => {

@@ -49,18 +49,18 @@ resolve({

message: 'Collection successfully imported!'
});
})
})
.catch(error => {
reject({ status: false, message: error.message });
});
reject({ status: false, message: error.message })
})
} else {
fs.readFile(fileName, 'utf8', function(err, data) {
if (err) {
console.log(err);
reject({ status: false, message: err.message });
console.log(err)
reject({ status: false, message: err.message })
}
// Turn string from file to an Array
let dataArray = JSON.parse(data);
let dataObj = JSON.parse(data)
updateCollection(db, dataArray, options)
updateCollection(db, dataObj, options)
.then(() => {

@@ -70,11 +70,11 @@ resolve({

message: 'Collection successfully imported!'
});
})
})
.catch(error => {
reject({ status: false, message: error.message });
});
});
reject({ status: false, message: error.message })
})
})
}
}).catch(error => console.error(error));
};
}).catch(error => console.error(error))
}

@@ -85,20 +85,19 @@ /**

* @param {any} db
* @param {Array<any>} dataArray
* @param {Array<string>} dateArray
* @param {Array<string>} geoArray
* @param {object} dataObj
* @param {IImportOptions} options
*/
const updateCollection = async (
db,
dataArray: Array<any>,
dataObj: object,
options: IImportOptions = {}
) => {
for (var index in dataArray) {
var collectionName = index;
for (var doc in dataArray[index]) {
if (dataArray[index].hasOwnProperty(doc)) {
for (var index in dataObj) {
var collectionName = index
for (var doc in dataObj[index]) {
if (dataObj[index].hasOwnProperty(doc)) {
// asign document id for array type
let docId = Array.isArray(dataArray[index]) ? uuidv1() : doc;
if (dataArray[index][doc]['subCollection']) {
const subCollections = dataArray[index][docId]['subCollection'];
delete dataArray[index][doc]['subCollection'];
let docId = Array.isArray(dataObj[index]) ? uuidv1() : doc
if (!Array.isArray(dataObj[index])) {
const subCollections = dataObj[index][docId]['subCollection']
delete dataObj[index][doc]['subCollection']
await startUpdating(

@@ -108,8 +107,14 @@ db,

docId,
dataArray[index][doc],
dataObj[index][doc],
options
);
// Update sub collection
await updateCollection(db, subCollections);
)
if (subCollections) {
await updateCollection(db, subCollections, options)
}
} else {
const subCollections = dataObj[index][doc]['subCollection']
delete dataObj[index][doc]['subCollection']
await startUpdating(

@@ -119,5 +124,14 @@ db,

docId,
dataArray[index][doc],
dataObj[index][doc],
options
);
)
if (subCollections) {
for (const subIndex in subCollections) {
const revivedSubCollection = {}
const subCollectionPath = `${collectionName}/${docId}/${subIndex}`
revivedSubCollection[subCollectionPath] = subCollections[subIndex]
await updateCollection(db, revivedSubCollection, options)
}
}
}

@@ -127,3 +141,3 @@ }

}
};
}

@@ -136,4 +150,3 @@ /**

* @param data
* @param dateArray
* @param geoArray
* @param options
*/

@@ -150,3 +163,3 @@

if (options.dates && options.dates.length > 0) {
updateTime(options.dates, data);
updateTime(options.dates, data)
}

@@ -158,5 +171,10 @@

if (data.hasOwnProperty(ref)) {
data[ref] = db.doc(data[ref]);
// check type of the reference
if (Array.isArray(data[ref])) {
data[ref] = data[ref].map(ref => db.doc(ref))
} else {
data[ref] = db.doc(data[ref])
}
}
});
})
}

@@ -171,7 +189,7 @@

data[geo]._longitude
);
)
} else {
console.warn('Please check your geo parameters!!!', options.geos);
console.warn('Please check your geo parameters!!!', options.geos)
}
});
})
}

@@ -184,16 +202,16 @@

.then(() => {
console.log(`${docId} was successfully added to firestore!`);
console.log(`${docId} was successfully added to firestore!`)
resolve({
status: true,
message: `${docId} was successfully added to firestore!`
});
})
})
.catch(error => {
console.log(error);
console.log(error)
reject({
status: false,
message: error.message
});
});
});
};
})
})
})
}

@@ -1,5 +0,5 @@

import { expect } from 'chai';
import request from 'request-promise';
import * as firestoreService from '../dist';
import { serviceAccount } from './serviceAccount';
import { expect } from 'chai'
import request from 'request-promise'
import * as firestoreService from '../dist'
import { serviceAccount } from './serviceAccount'

@@ -9,33 +9,33 @@ const app = firestoreService.initializeApp(

serviceAccount.databaseUrl
);
)
const backupAPI =
'https://firebasestorage.googleapis.com/v0/b/firbase-function-helper-qa.appspot.com/o/import-to-firestore.json?alt=media&token=a0530902-8983-45a4-90c2-72c345c7a3d5';
'https://firebasestorage.googleapis.com/v0/b/firbase-function-helper-qa.appspot.com/o/import-to-firestore.json?alt=media&token=a0530902-8983-45a4-90c2-72c345c7a3d5'
describe('initializeApp function test', () => {
it('Initialize app', () => {
expect(app).to.equal(true);
});
expect(app).to.equal(true)
})
it('Restore data from API', async () => {
const backupData = await request(backupAPI);
const backupData = await request(backupAPI)
const status = await firestoreService.restore(JSON.parse(backupData), {
dates: ['date'],
geos: ['location']
});
expect(status.status).ok;
});
})
expect(status.status).ok
})
it('Get all collections', async () => {
try {
const all = await firestoreService.backups();
expect(Object.keys(all).length).is.greaterThan(0);
const all = await firestoreService.backups()
expect(Object.keys(all).length).is.greaterThan(0)
} catch (error) {
console.log(error);
console.log(error)
}
});
})
it('Get an array of collections', async () => {
const all = await firestoreService.backups(['test', 'users']);
expect(Object.keys(all).length).is.equal(2);
});
const all = await firestoreService.backups(['test', 'users'])
expect(Object.keys(all).length).is.equal(2)
})

@@ -48,12 +48,12 @@ it('Restore data with document id', async () => {

geos: ['location'],
refs: ['secondRef']
refs: ['secondRef', 'arrayRef']
}
);
expect(status.status).ok;
)
expect(status.status).ok
const result = await firestoreService.backup('test');
const result = await firestoreService.backup('test')
expect(result.test['first-key'].email).is.equal('dungnq@itbox4vn.com');
expect(result.test['first-key'].schedule.time._seconds).equals(1534046400);
expect(typeof result.test['first-key'].secondRef).is.equal('object');
expect(result.test['first-key'].email).is.equal('dungnq@itbox4vn.com')
expect(result.test['first-key'].schedule.time._seconds).equals(1534046400)
expect(typeof result.test['first-key'].secondRef).is.equal('object')
expect(

@@ -63,4 +63,4 @@ result.test['first-key'].subCollection['test/first-key/details'][

].dogName
).is.equal('hello');
});
).is.equal('hello')
})

@@ -70,22 +70,17 @@ it('Restore data as an array without document id', async () => {

'test/import-array-to-firestore.json'
);
expect(status.status).ok;
});
)
expect(status.status).ok
})
it('Get a colection with sub-collection', async () => {
try {
const data = await firestoreService.backup('test');
const subCol = data['test']['first-key']['subCollection'];
const data = await firestoreService.backup('test')
const subCol = data['test']['first-key']['subCollection']
expect(subCol).is.exist;
expect(Object.values(subCol).length).is.greaterThan(0);
expect(subCol).is.exist
expect(Object.values(subCol).length).is.greaterThan(0)
} catch (error) {
console.log(error);
console.log(error)
}
});
it('Get one collection', async () => {
const result = await firestoreService.backup('test');
expect(Object.keys(result).length).is.equal(1);
});
});
})
})

@@ -5,3 +5,15 @@ {

"name": "Dale Nguyen",
"email": "dale@dalenguyen.me"
"email": "dale@dalenguyen.me",
"subCollection": {
"details": [
{
"dogId": "2",
"dogName": "hello"
},
{
"dogName": "lala",
"dogId": "2"
}
]
}
},

@@ -8,0 +20,0 @@ {

@@ -33,2 +33,3 @@ {

"secondRef": "test/second-key",
"arrayRef": ["test/second-key", "test/second-key"],
"subCollection": {

@@ -35,0 +36,0 @@ "test/first-key/details": {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc