sage-fifty
Version:
Interact with Sage50 Accounts
107 lines (81 loc) • 2.95 kB
JavaScript
var sageAccessQueue = require('./access-queue');
var Promise = require('bluebird');
var retry = require('bluebird-retry');
var child_process = require('child_process');
var path = require('path');
var _ = require('lodash');
var debug = require('debug')('sage-fifty:bridge');
var bridgeExe = path.resolve(__dirname, "./bin/sage50-bridge.exe");
module.exports = Promise.method(function Bridge(options, onprogress){
function tryBridge() {
onprogress = onprogress || (function(){});
// queue will ensure we won't conflict with other apps on the same accdata/username
return sageAccessQueue(options.accdata, options.username)(function(){
debug("Spawning", bridgeExe, "with params", options);
var cp = child_process.spawn(bridgeExe, ["--pipe"], {stdio: 'pipe', windowsHide: true});
return new Promise(function(resolve, reject){
// provide program input
cp.stdin.write(JSON.stringify(options));
cp.stdin.end();
// store program output
var dataBuffer = "";
function parseJSONOut(js){
if (!js || !js.type) {
reject(Error("Invalid JSON response"));
}
switch (js.type) {
case 'progress':
debug("->progress", js.activity, js.current +"/"+ js.total);
onprogress(js.activity, js.current, js.total);
break;
case 'error':
debug("->error", js.message);
reject(Error(js.message));
break;
case 'data':
debug("->data");
resolve(js.data);
break;
}
}
function readOutput(){
var lines = dataBuffer.split("\x00");
while (lines.length) {
var line = lines.shift();
try {
parseJSONOut(JSON.parse(line));
} catch (x) {
if (lines.length > 0) {
// this line didn't parse and we have more queued up that need parsing?
reject(Error("Bridge data parse error"));
} else {
// if this was the last line, we can expect that it might be incomplete
dataBuffer = line;
}
}
}
}
cp.stdout.on('data', function(data){
dataBuffer += data;
readOutput();
});
var onerror = function(err){
reject(err);
removelisteners();
};
var onexit = function(code){
reject(Error("Premature exit: "+code));
removelisteners();
};
function removelisteners(){
cp.stdout.removeAllListeners();
cp.removeListener('error', onerror);
cp.removeListener('exit', onexit);
};
cp.on('error', onerror);
cp.on('exit', onexit);
});
});
}
return retry(tryBridge, {max_tries: 10, interval: 500, backoff: 1000, max_interval: 5000});
});