invoice-fs
Version:
Nostalgic command-line invoicing application producing plain text invoices and JSON data structures. Uses the file system as a database
108 lines (89 loc) • 2.95 kB
JavaScript
var obj = require('javascript-object-paraphernalia'),
colors = require('colors'),
out = require('./out'),
EditFlowType = require('./editFlowType');
function EditFlow(config) {
this.index = 0;
this.model = {};
this.steps = [];
obj.merge(this, config);
}
EditFlow.prototype.updateModel = function(step, input) {
this.model.data[step.property] = input;
};
EditFlow.prototype.getCurrentValue = function(step) {
try {
var existingValue = "";
if (this.model.data[step.property].length > 0) {
existingValue = this.model.data[step.property];
} else if (step.default.toString().length > 0) {
existingValue = step.format(step.default.toString());
}
return existingValue.length > 0 ? existingValue : "";
} catch (e) {
this.cancel();
out.error(e);
}
};
EditFlow.prototype.showStep = function(step) {
try {
process.stdout.write(step.label + (this.getCurrentValue(step).length > 0 ? " (" + this.getCurrentValue(step).bold.green + ")" : "") + " :");
} catch (e) {
this.cancel();
out.error(e);
}
};
EditFlow.prototype.castInput = function(input) {
switch (this.steps[this.index].type) {
case EditFlowType.Integer: {
input = parseInt(input, 10);
break;
}
case EditFlowType.Decimal: {
input = parseFloat(input);
break;
}
}
return input;
};
EditFlow.prototype.listener = function(input) {
input = input.toString().substring(0, input.length-1);
if (input.length === 0 && this.getCurrentValue(this.steps[this.index]).length === 0 && this.steps[this.index].required) {
out.write("Required Value".red);
this.showStep(this.steps[this.index]);
return;
}
if (input.length === 0) {
input = this.getCurrentValue(this.steps[this.index]);
}
if (!this.castInput(input).toString().match(this.steps[this.index].matches)) {
out.write("Invalid Entry".red);
this.showStep(this.steps[this.index]);
return;
}
this.updateModel(this.steps[this.index], this.steps[this.index].format(this.castInput(input)));
this.index++;
if (this.index < this.steps.length) {
this.showStep(this.steps[this.index]);
} else {
this.complete();
}
//TODO: cancel input
//this.cancel();
};
EditFlow.prototype.start = function() {
this.showStep(this.steps[this.index]);
process.stdin.addListener("data", this.listener.bind(this));
};
EditFlow.prototype.complete = function() {
this.model.save(function(data) {
process.stdin.removeAllListeners('data');
process.stdin.unref();
if (this.onSave) { this.onSave(data); }
}.bind(this));
};
EditFlow.prototype.cancel = function() {
process.stdin.removeAllListeners('data');
process.stdin.unref();
};
module.exports = EditFlow;