Simon Priet e69a613a37 feat: Created a mini nodeJS server with NewMan for testing without PostMan GUI.
This will mimic a run in a CD/CI environment or docker container.
2021-09-08 14:01:19 +02:00

213 lines
5.8 KiB
JavaScript

const _ETA = require('./eta');
const _Terminal = require('./terminal');
const _formatter = require('./formatter');
const _EventEmitter = require('events');
// Progress-Bar constructor
module.exports = class GenericBar extends _EventEmitter{
constructor(options){
super();
// store options
this.options = options;
// store terminal instance
this.terminal = (this.options.terminal) ? this.options.terminal : new _Terminal(this.options.stream);
// the current bar value
this.value = 0;
// the end value of the bar
this.total = 100;
// last drawn string - only render on change!
this.lastDrawnString = null;
// start time (used for eta calculation)
this.startTime = null;
// stop time (used for duration calculation)
this.stopTime = null;
// last update time
this.lastRedraw = Date.now();
// default eta calculator (will be re-create on start)
this.eta = new _ETA(this.options.etaBufferLength, 0, 0);
// payload data
this.payload = {};
// progress bar active ?
this.isActive = false;
// use default formatter or custom one ?
this.formatter = (typeof this.options.format === 'function') ? this.options.format : _formatter;
}
// internal render function
render(){
// calculate the normalized current progress
let progress = (this.value/this.total);
// handle NaN Errors caused by total=0. Set to complete in this case
if (isNaN(progress)){
progress = (this.options && this.options.emptyOnZero) ? 0.0 : 1.0;
}
// limiter
progress = Math.min(Math.max(progress, 0.0), 1.0);
// formatter params
const params = {
progress: progress,
eta: this.eta.getTime(),
startTime: this.startTime,
stopTime: this.stopTime,
total: this.total,
value: this.value,
maxWidth: this.terminal.getWidth()
};
// automatic eta update ? (long running processes)
if (this.options.etaAsynchronousUpdate){
this.updateETA();
}
// format string
const s = this.formatter(this.options, params, this.payload);
const forceRedraw = this.options.forceRedraw
// force redraw in notty-mode!
|| (this.options.noTTYOutput && !this.terminal.isTTY());
// string changed ? only trigger redraw on change!
if (forceRedraw || this.lastDrawnString != s){
// trigger event
this.emit('redraw-pre');
// set cursor to start of line
this.terminal.cursorTo(0, null);
// write output
this.terminal.write(s);
// clear to the right from cursor
this.terminal.clearRight();
// store string
this.lastDrawnString = s;
// set last redraw time
this.lastRedraw = Date.now();
// trigger event
this.emit('redraw-post');
}
}
// start the progress bar
start(total, startValue, payload){
// set initial values
this.value = startValue || 0;
this.total = (typeof total !== 'undefined' && total >= 0) ? total : 100;
// store payload (optional)
this.payload = payload || {};
// store start time for duration+eta calculation
this.startTime = Date.now();
// reset string line buffer (redraw detection)
this.lastDrawnString = '';
// initialize eta buffer
this.eta = new _ETA(this.options.etaBufferLength, this.startTime, this.value);
// set flag
this.isActive = true;
// start event
this.emit('start', total, startValue);
}
// stop the bar
stop(){
// set flag
this.isActive = false;
// store stop timestamp to get total duration
this.stopTime = new Date();
// stop event
this.emit('stop', this.total, this.value);
}
// update the bar value
// update(value, payload)
// update(payload)
update(arg0, arg1 = {}){
// value set ?
// update(value, [payload]);
if (typeof arg0 === 'number') {
// update value
this.value = arg0;
// add new value; recalculate eta
this.eta.update(Date.now(), arg0, this.total);
}
// extract payload
// update(value, payload)
// update(payload)
const payloadData = ((typeof arg0 === 'object') ? arg0 : arg1) || {};
// update event (before stop() is called)
this.emit('update', this.total, this.value);
// merge payload
for (const key in payloadData){
this.payload[key] = payloadData[key];
}
// limit reached ? autostop set ?
if (this.value >= this.getTotal() && this.options.stopOnComplete) {
this.stop();
}
}
// update the bar value
// increment(delta, payload)
// increment(payload)
increment(arg0 = 1, arg1 = {}){
// increment([payload]) => step=1
// handle the use case when `step` is omitted but payload is passed
if (typeof arg0 === 'object') {
this.update(this.value + 1, arg0);
// increment([step=1], [payload={}])
}else{
this.update(this.value + arg0, arg1);
}
}
// get the total (limit) value
getTotal(){
return this.total;
}
// set the total (limit) value
setTotal(total){
if (typeof total !== 'undefined' && total >= 0){
this.total = total;
}
}
// force eta calculation update (long running processes)
updateETA(){
// add new value; recalculate eta
this.eta.update(Date.now(), this.value, this.total);
}
}