multivocal
Version:
A node.js library to assist with building best practice, configuration driven, Actions for the Google Assistant.
109 lines (92 loc) • 2.79 kB
JavaScript
const admin = require('firebase-admin');
const functions = require('firebase-functions');
/**
*
* @param fb
* @param options
* @returns {Object} A Configuration that updates its data from Firebase.
*/
module.exports = function( fb, options ){
options = Object.assign( {}, {
addToMultivocal: true,
ignoreCache: false
}, (options || {}) );
fb = Object.assign( {}, {
config: functions.config().firebase,
name: undefined,
path: 'multivocal'
}, (fb || {}) );
this.fb = fb;
this.val = undefined;
this.updated = 0;
// Initialize the app if we need to
try{
this.app = admin.app( fb.name );
} catch( xx ){
// Default database not configured yet, so do so
this.app = admin.initializeApp( fb.config, fb.name );
//console.log('initialized', JSON.stringify(fb,null,1));
}
this.db = admin.database( this.app );
this.ref = this.db.ref( fb.path );
var promiseVal = () => {
var ret = Object.assign( {}, this.val || {} );
return Promise.resolve( ret );
};
var setSnapshot = (snapshot) => {
var val = snapshot.val();
this.val = cleanCopy( val );
this.updated = Date.now();
//console.log('setSnapshot',JSON.stringify(this.val,null,2));
console.log('config-firebase setSnapshot',this.updated);
return promiseVal();
};
this.shouldGet = (lastUpdate) => {
console.log('config-firebase shouldGet', this.updated, lastUpdate, this.updated > lastUpdate);
return options.ignoreCache || (this.updated > lastUpdate)
};
this.get = () => {
//console.log( 'ConfigFirebase val', this.val );
if( this.val ){
return promiseVal();
} else {
return this.load();
}
};
this.load = () => {
//console.log( 'ConfigFirebase load' );
return this.ref.once('value')
.then( snapshot => setSnapshot( snapshot ) )
.catch( err => {
console.error( 'Warning: Problem loading from firebase.', err );
return Promise.reject( err );
});
};
// Register a callback that will get updates when the database changes
this.ref.on('value', snapshot => {
console.log( 'Config updated from firebase' );
setSnapshot( snapshot );
});
if( options.addToMultivocal ){
const Multivocal = require('./multivocal');
Multivocal.addConfig( this );
}
return this;
};
var cleanCopy = function( obj ){
if( typeof obj !== 'object' ){
return obj;
} else if( Array.isArray( obj ) ){
return obj.map( e => cleanCopy(e) );
}
var ret = {};
var keys = Object.keys( obj );
for( var co=0; co<keys.length; co++ ){
var key = keys[co];
var val = obj[key];
var cleanKey = key.replace( /_/g, '.' ).replace( /\|/g, '/' );
var cleanVal = cleanCopy( val );
ret[cleanKey] = cleanVal;
}
return ret;
};