Skip to content

Commit

Permalink
Parse Firestore data values and allow param substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
Lauren Long committed Nov 11, 2017
1 parent b5f10f9 commit 7788aa9
Showing 1 changed file with 74 additions and 116 deletions.
190 changes: 74 additions & 116 deletions lib/localFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ var _ = require('lodash');
var is = require('is');
var request = require('request');

var instance;

var LocalFunction = function(trigger, urls, controller) {
instance = this;
this.name = trigger.name;
this.eventTrigger = trigger.eventTrigger;
this.httpsTrigger = trigger.httpsTrigger;
Expand Down Expand Up @@ -45,162 +48,89 @@ LocalFunction.prototype._requestCallBack = function(err, response, body) {
return console.log('\nRESPONSE RECEIVED FROM FUNCTION: ' + status + body);
};

LocalFunction.prototype.encodeFirestoreValue = function(data) {

var isPlainObject= function(input) {
return (
typeof input === 'object' &&
LocalFunction.prototype._encodeFirestoreValue = function(data) {
var isPlainObject = function(input) {
return typeof input === 'object' &&
input !== null &&
Object.getPrototypeOf(input) === Object.prototype
);
_.isEqual(Object.getPrototypeOf(input), Object.prototype);
};

var encodeHelper = function(val) {

if (is.string(val)) {
return {
stringValue: val
};
}

if (is.boolean(val)) {
return {
booleanValue: val
};
}

if (is.integer(val)) {
return {
integerValue: val
};
}

// Integers are handled above, the remaining numbers are treated as doubles
if (is.number(val)) {
return {
doubleValue: val
};
}

// if (is.date(val)) {
// let epochSeconds = Math.floor(val.getTime() / 1000);
// let timestamp = {
// seconds: epochSeconds,
// nanos: (val.getTime() - epochSeconds * 1000) * 1000000,
// };
// return {
// timestampValue: timestamp
// };
// }

// if (is.array(val)) {
// let encodedElements = [];
// for (let i = 0; i < val.length; ++i) {
// let enc = this.encodeValue(val[i]);
// if (enc) {
// encodedElements.push(enc);
// }
// }
// return {
// arrayValue: {
// values: encodedElements
// },
// };
// }

if (is.date(val)) {
return {
timestampValue: val.toISOString()
};
}
if (is.array(val)) {
var encodedElements = [];
for (var i = 0; i < val.length; ++i) {
var enc = encodeHelper(val[i]);
if (enc) {
encodedElements.push(enc);
}
}
return {
arrayValue: {
values: encodedElements
}
};
}
if (is.nil(val)) {
return {
nullValue: 'NULL_VALUE'
};
}

// if (is.instance(val, DocumentReference) || is.instance(val, ResourcePath)) {
// return {
// referenceValue: val.formattedName,
// };
// }

// if (is.instance(val, GeoPoint)) {
// return {
// valueType: 'geoPointValue',
// geoPointValue: val.toProto(),
// };
// }

if (is.instanceof(val, Buffer) || is.instanceof(val, Uint8Array)) {
return {
bytesValue: val,
bytesValue: val
};
}
if (isPlainObject(val)) {
return {
mapValue: {
fields: instance._encodeFirestoreValue(val)
}
};
}

// if (isPlainObject(val)) {
// console.log(val + 'is a plain object')
// return {
// mapValue: {
// fields: this.encodeFields(val)
// },
// };
// }

throw new Error(
'Cannot encode ' + val + 'to a Firestore Value'
'Cannot encode ' + val + 'to a Firestore Value.' +
' The emulator does not yet support Firestore document reference values or geo points.'
);
};

return _.mapValues(data, encodeHelper);
};


// LocalFunction.prototype._convertToFirestoreWireFormat = function(fields) {
// if (!fields) {
// return {};
// }
// function convertHelper(data) {
// let result;
// _.forEach(data, (value, key) => {
// let dataPart;
// // var valueType =
// if (valueType === 'arrayValue') {
// let array = _.get(value, 'values', []);
// dataPart = {
// arrayValue: {
// values: _.map(array, (elem) => {
// return convertHelper(elem);
// }),
// },
// };
// } else if (valueType === 'mapValue') {
// let map = _.get(value, 'fields', {});
// dataPart = {
// mapValue: {
// fields: _.mapValues(map, (val) => {
// return convertHelper(val);
// }),
// },
// };
// } else if (valueType === 'timestampValue') {
// dataPart = {timestampValue: dateToTimestampProto(value)};
// } else {
// dataPart = data;
// }
// result = _.merge({}, dataPart, {valueType: valueType});
// });
// return result;
// }

// return _.mapValues(fields, (data) => {
// return convertHelper(data);
// });
// };

LocalFunction.prototype._call = function(data, opts) {
opts = opts || {};
var operationType;
var dataPayload;
if (this.httpsTrigger) {
this.controller.call(this.name, data || {});
} else if (this.eventTrigger) {
if (this._isDatabaseFunc(this.eventTrigger)) {
var operationType = _.last(this.eventTrigger.eventType.split('.'));
var dataPayload;
operationType = _.last(this.eventTrigger.eventType.split('.'));
if (operationType === 'create') {
dataPayload = {
data: null,
Expand All @@ -219,14 +149,42 @@ LocalFunction.prototype._call = function(data, opts) {
}
opts.resource = this._substituteParams(this.eventTrigger.resource, opts.params);
this.controller.call(this.name, dataPayload, opts);
} else if (this._isFirestoreFunc(this.eventTrigger)){
var dataPayload = {
value: {
"createTime": "2017-06-02T18:48:58.920638Z",
fields: this.encodeFirestoreValue(data),
"updateTime": "2017-06-16T04:50:48.293439Z"
}
} else if (this._isFirestoreFunc(this.eventTrigger)) {
operationType = _.last(this.eventTrigger.eventType.split('.'));
var currentTime = (new Date()).toISOString();
if (operationType === 'create') {
dataPayload = {
value: {
fields: this._encodeFirestoreValue(data),
createTime: currentTime,
updateTime: currentTime
},
oldValue: {}
};
} else if (operationType === 'update' || operationType === 'write') {
dataPayload = {
value: {
fields: this._encodeFirestoreValue(data.after),
createTime: currentTime,
updateTime: currentTime
},
oldValue: {
fields: this._encodeFirestoreValue(data.before),
createTime: currentTime,
updateTime: currentTime
}
};
} else if (operationType === 'delete') {
dataPayload = {
value: {},
oldValue: {
fields: this._encodeFirestoreValue(data),
createTime: currentTime,
updateTime: currentTime
}
};
}
opts.resource = this._substituteParams(this.eventTrigger.resource, opts.params);
this.controller.call(this.name, dataPayload, opts);
} else {
this.controller.call(this.name, data || {}, opts);
Expand Down

0 comments on commit 7788aa9

Please sign in to comment.