Skip to content

Commit

Permalink
Merge pull request #1 from steadyequipment/master
Browse files Browse the repository at this point in the history
upstream pull
  • Loading branch information
jeremylorino authored Feb 11, 2018
2 parents eb7e2fe + 8f4a40d commit 5930e97
Show file tree
Hide file tree
Showing 15 changed files with 6,923 additions and 233 deletions.
4 changes: 3 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
lib/.*

[ignore]
dist/.*
<PROJECT_ROOT>/node_modules/protobufjs/src/bower.json
<PROJECT_ROOT>/node_modules/google-gax/node_modules/protobufjs/tests/data/invalid.json


[libs]

Expand Down
171 changes: 171 additions & 0 deletions dist/firestore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
'use strict';

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.backupRootCollections = exports.backupCollection = exports.backupDocument = exports.constructDocumentValue = exports.constructReferenceUrl = undefined;

var _types = require('./types');

var _utility = require('./utility');

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _mkdirp = require('mkdirp');

var _mkdirp2 = _interopRequireDefault(_mkdirp);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var constructReferenceUrl = exports.constructReferenceUrl = function constructReferenceUrl(reference) {
var referenceSegments = reference._referencePath.segments;
var referencePath = void 0;
if (Array.isArray(referenceSegments)) {
referencePath = referenceSegments.join('/');
} else if (typeof referenceSegments === 'string') {
referencePath = referenceSegments;
}

if (referencePath) {
return {
value: referencePath,
type: 'reference'
};
} else {
return {
value: reference,
type: 'unknown'
};
}
};

var testValidDocumentValue = function testValidDocumentValue(key, documentData, validators) {
var validValue = void 0;

for (var index = 0; index < validators.length; index++) {
var testValidValue = validators[index](documentData[key]);
if (typeof testValidValue !== 'boolean') {
validValue = testValidValue;
break;
}
}

if (validValue) {
return validValue;
}
return false;
};

var constructDocumentValue = exports.constructDocumentValue = function constructDocumentValue() {
var documentDataToStore = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var keys = arguments[1];
var documentData = arguments[2];

keys.forEach(function (key) {
// Boolean - boolean
// Reference - reference
// Integer - number
// Array - array
// Object - object
// Float - number
// Geographical Point - todo
// Map = todo
// Null - null
var objectTypeValidators = [_types.isArray, _types.isObject];

var documentValue = testValidDocumentValue(key, documentData, objectTypeValidators);
if (documentValue) {
documentDataToStore[key] = Object.assign({}, documentDataToStore[key], { type: documentValue.type });
documentDataToStore[key] = Object.assign({}, documentDataToStore[key], constructDocumentValue({}, Object.keys(documentData[key]), documentData[key]));
} else {
var basicTypeValidators = [_types.isBoolean, _types.isDate, _types.isNumber, _types.isNull, _types.isString];

var _documentValue = testValidDocumentValue(key, documentData, basicTypeValidators);
if (_documentValue) {
documentDataToStore = Object.assign({}, documentDataToStore, _defineProperty({}, key, _documentValue));
} else {
var validValue = (0, _types.isReference)(documentData[key]);
if (validValue) {
documentDataToStore = Object.assign({}, documentDataToStore, _defineProperty({}, key, constructReferenceUrl(documentData[key])));
} else {
documentDataToStore = {
value: documentData[key],
type: 'unknown'
};
}
// TODO: stronger validation that we have a reference rather than being our fallback
}
}
});
return documentDataToStore;
};

var backupDocument = exports.backupDocument = function backupDocument(document, backupPath, logPath, prettyPrintJSON) {
console.log('Backing up Document \'' + logPath + document.id + '\'');
try {
_mkdirp2.default.sync(backupPath);
} catch (error) {
throw new Error('Unable to create backup path for Document \'' + document.id + '\': ' + error);
}

var fileContents = void 0;
try {
var documentData = document.data();
var keys = Object.keys(documentData);
var documentDataToStore = {};
documentDataToStore = Object.assign({}, constructDocumentValue(documentDataToStore, keys, documentData));
if (prettyPrintJSON === true) {
fileContents = JSON.stringify(documentDataToStore, null, 2);
} else {
fileContents = JSON.stringify(documentDataToStore);
}
} catch (error) {
throw new Error('Unable to serialize Document \'' + document.id + '\': ' + error);
}
try {
_fs2.default.writeFileSync(backupPath + '/' + document.id + '.json', fileContents);
} catch (error) {
throw new Error('Unable to write Document \'' + document.id + '\': ' + error);
}

return document.ref.getCollections().then(function (collections) {
return (0, _utility.promiseSerial)(collections.map(function (collection) {
return function () {
return backupCollection(collection, backupPath + '/' + collection.id, logPath + document.id + '/', prettyPrintJSON);
};
}));
});
};

var backupCollection = exports.backupCollection = function backupCollection(collection, backupPath, logPath, prettyPrintJSON) {
console.log('Backing up Collection \'' + logPath + collection.id + '\'');
try {
_mkdirp2.default.sync(backupPath);
} catch (error) {
throw new Error('Unable to create backup path for Collection \'' + collection.id + '\': ' + error);
}

return collection.get().then(function (documentSnapshots) {
var backupFunctions = [];
documentSnapshots.forEach(function (document) {
backupFunctions.push(function () {
return backupDocument(document, backupPath + '/' + document.id, logPath + collection.id + '/', prettyPrintJSON);
});
});
return (0, _utility.promiseSerial)(backupFunctions);
});
};

var backupRootCollections = exports.backupRootCollections = function backupRootCollections(database, backupPath, prettyPrintJSON) {
return database.getCollections().then(function (collections) {
return (0, _utility.promiseSerial)(collections.map(function (collection) {
return function () {
return backupCollection(collection, backupPath + '/' + collection.id, '/', prettyPrintJSON);
};
}));
});
};
169 changes: 169 additions & 0 deletions dist/firestore.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/* @flow */

import { isString, isNull, isObject, isArray, isNumber, isDate, isBoolean, isReference } from './types'
import type { ValueDescription, Validator } from './types'
import { promiseSerial } from './utility'

import fs from 'fs'
import mkdirp from 'mkdirp'

export const constructReferenceUrl = (reference: Object): ValueDescription => {
const referenceSegments = reference._referencePath.segments
let referencePath: ?string
if (Array.isArray(referenceSegments)) {
referencePath = referenceSegments.join('/')
} else if (typeof referenceSegments === 'string') {
referencePath = referenceSegments
}

if (referencePath) {
return {
value: referencePath,
type: 'reference'
}
} else {
return {
value: reference,
type: 'unknown'
}
}
}

const testValidDocumentValue = (
key: string,
documentData: Object,
validators: Array<Validator>) => {
let validValue: ?ValueDescription

for (let index = 0; index < validators.length; index++) {
const testValidValue = validators[index](documentData[key])
if (typeof testValidValue !== 'boolean') {
validValue = testValidValue
break
}
}

if (validValue) {
return validValue
}
return false
}

export const constructDocumentValue = (documentDataToStore: Object = {}, keys: Array<string>, documentData: Object) => {
keys.forEach(key => {
// Boolean - boolean
// Reference - reference
// Integer - number
// Array - array
// Object - object
// Float - number
// Geographical Point - todo
// Map = todo
// Null - null
// String - string
const objectTypeValidators: Array<Validator> = [
isArray,
isObject
]

const documentValue = testValidDocumentValue(key, documentData, objectTypeValidators)
if (documentValue) {
documentDataToStore[key] = Object.assign({}, documentDataToStore[key], { type: documentValue.type })
documentDataToStore[key] = Object.assign({}, documentDataToStore[key], constructDocumentValue({}, Object.keys(documentData[key]), documentData[key]))
} else {
const basicTypeValidators: Array<Validator> = [
isBoolean,
isDate,
isNumber,
isNull,
isString
]

const documentValue = testValidDocumentValue(key, documentData, basicTypeValidators)
if (documentValue) {
documentDataToStore = Object.assign({}, documentDataToStore, { [key]: documentValue })
} else {
const validValue = isReference(documentData[key])
if (validValue) {
documentDataToStore = Object.assign({}, documentDataToStore, { [key]: constructReferenceUrl(documentData[key]) })
} else {
documentDataToStore = {
value: documentData[key],
type: 'unknown'
}
}
// TODO: stronger validation that we have a reference rather than being our fallback
}
}
})
return documentDataToStore
}

export const backupDocument = (document: Object, backupPath: string, logPath: string, prettyPrintJSON: boolean) => {
console.log('Backing up Document \'' + logPath + document.id + '\'')
try {
mkdirp.sync(backupPath)
} catch (error) {
throw new Error('Unable to create backup path for Document \'' + document.id + '\': ' + error)
}

let fileContents: string
try {
const documentData = document.data()
const keys = Object.keys(documentData)
var documentDataToStore = {}
documentDataToStore = Object.assign({}, constructDocumentValue(documentDataToStore, keys, documentData))
if (prettyPrintJSON === true) {
fileContents = JSON.stringify(documentDataToStore, null, 2)
} else {
fileContents = JSON.stringify(documentDataToStore)
}
} catch (error) {
throw new Error('Unable to serialize Document \'' + document.id + '\': ' + error)
}
try {
fs.writeFileSync(backupPath + '/' + document.id + '.json', fileContents)
} catch (error) {
throw new Error('Unable to write Document \'' + document.id + '\': ' + error)
}

return document.ref.getCollections()
.then((collections) => {
return promiseSerial(collections.map((collection) => {
return () => {
return backupCollection(collection, backupPath + '/' + collection.id, logPath + document.id + '/', prettyPrintJSON)
}
}))
})
}

export const backupCollection = (collection: Object, backupPath: string, logPath: string, prettyPrintJSON: boolean) => {
console.log('Backing up Collection \'' + logPath + collection.id + '\'')
try {
mkdirp.sync(backupPath)
} catch (error) {
throw new Error('Unable to create backup path for Collection \'' + collection.id + '\': ' + error)
}

return collection.get()
.then((documentSnapshots) => {
const backupFunctions = []
documentSnapshots.forEach((document) => {
backupFunctions.push(() => {
return backupDocument(document, backupPath + '/' + document.id, logPath + collection.id + '/', prettyPrintJSON)
})
})
return promiseSerial(backupFunctions)
})
}

export const backupRootCollections = (database: Object, backupPath: string, prettyPrintJSON: boolean) => {
return database.getCollections()
.then((collections) => {
return promiseSerial(collections.map((collection) => {
return () => {
return backupCollection(collection, backupPath + '/' + collection.id, '/', prettyPrintJSON)
}
}))
})
}
Loading

0 comments on commit 5930e97

Please sign in to comment.