UNPKG

@lonu/stc

Version:

A tool for converting OpenApi/Swagger/Apifox into code.

298 lines (297 loc) 11.6 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _ProgressBar_end; import * as dntShim from "../../../../../_dnt.shims.js"; import { bgGreen, bgWhite, stripAnsiCode } from "./deps.js"; import { writeAll } from "./deps.js"; // import type { Writer } from "./deps.ts"; import { prettyTime } from "./time.js"; export { MultiProgressBar } from "./multi.js"; const isTerminal = dntShim.Deno.stdout.isTerminal; var Direction; (function (Direction) { Direction[Direction["left"] = 0] = "left"; Direction[Direction["right"] = 1] = "right"; Direction[Direction["all"] = 2] = "all"; })(Direction || (Direction = {})); /** * ProgressBar single progress bar. */ class ProgressBar { /** * Title, total, complete, incomplete, can also be set or changed in the render method * * - title Progress bar title, default: '' * - total total number of ticks to complete, * - width the displayed width of the progress, default: 50 * - complete completion character, default: colors.bgGreen(' '), can use any string * - incomplete incomplete character, default: colors.bgWhite(' '), can use any string * - clear clear the bar on completion, default: false * - interval minimum time between updates in milliseconds, default: 16 * - display What is displayed and display order, default: ':title :percent :bar :time :completed/:total' * - prettyTime Whether to pretty print time and eta * - output Output stream, can be Deno.stdout or Deno.stderr, default is Deno.stdout */ constructor({ title = "", total, width = 50, complete = bgGreen(" "), preciseBar = [], incomplete = bgWhite(" "), clear = false, interval = 16, display, prettyTime = false, output = dntShim.Deno.stdout, } = {}) { Object.defineProperty(this, "title", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "total", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "width", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "complete", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "preciseBar", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "incomplete", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "clear", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "interval", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "display", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "prettyTime", { enumerable: true, configurable: true, writable: true, value: void 0 }); _ProgressBar_end.set(this, false); Object.defineProperty(this, "lastStr", { enumerable: true, configurable: true, writable: true, value: "" }); Object.defineProperty(this, "lastStrLen", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "start", { enumerable: true, configurable: true, writable: true, value: Date.now() }); Object.defineProperty(this, "lastRenderTime", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "encoder", { enumerable: true, configurable: true, writable: true, value: new TextEncoder() }); // private writer: WritableStreamDefaultWriter<Uint8Array>; // private writer: Writer; Object.defineProperty(this, "writer", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.title = title; this.total = total; this.width = width; this.complete = complete; this.preciseBar = preciseBar.concat(complete); this.incomplete = incomplete; this.clear = clear; this.interval = interval; this.display = display ?? ":title :percent :bar :time :completed/:total :text"; this.prettyTime = prettyTime; // this.writer = output.writable.getWriter(); this.writer = output; } /** * "render" the progress bar * * - `completed` completed value * - `options` optional parameters * - `title` progress bar title * - `total` total number of ticks to complete * - `text` optional, custom text, default: '' * - `complete` completion character, If you want to change at a certain moment. For example, it turns red at 20% * - `incomplete` incomplete character, If you want to change at a certain moment. For example, it turns red at 20% * - `prettyTimeOptions` prettyTime options */ async render(completed, options = {}) { if (__classPrivateFieldGet(this, _ProgressBar_end, "f") || !isTerminal) return; if (completed < 0) { throw new Error(`completed must greater than or equal to 0`); } const total = options.total ?? this.total ?? 100; const now = Date.now(); const ms = now - this.lastRenderTime; const end = completed >= total; if (ms < this.interval && !end) return; this.lastRenderTime = now; const time = this.prettyTime ? prettyTime(now - this.start, options.prettyTimeOptions) : ((now - this.start) / 1000).toFixed(1) + "s"; const msEta = completed >= total ? 0 : (total / completed - 1) * (now - this.start); const eta = completed == 0 ? "-" : this.prettyTime ? prettyTime(msEta, options.prettyTimeOptions) : (msEta / 1000).toFixed(1) + "s"; const percent = ((completed / total) * 100).toFixed(2) + "%"; // :title :percent :bar :time :completed/:total let str = this.display .replace(":title", options.title ?? this.title) .replace(":time", time) .replace(":text", options.text ?? "") .replace(":eta", eta) .replace(":percent", percent) .replace(":completed", completed + "") .replace(":total", total + ""); // compute the available space (non-zero) for the bar const availableSpace = Math.max(0, this.ttyColumns - stripAnsiCode(str.replace(":bar", "")).length); const width = Math.min(this.width, availableSpace); const preciseBar = options.preciseBar ?? this.preciseBar; const precision = preciseBar.length > 1; // :bar const completeLength = (width * completed) / total; const roundedCompleteLength = Math.floor(completeLength); let precise = ""; if (precision) { const preciseLength = completeLength - roundedCompleteLength; precise = end ? "" : preciseBar[Math.floor(preciseBar.length * preciseLength)]; } const complete = new Array(roundedCompleteLength) .fill(options.complete ?? this.complete) .join(""); const incomplete = new Array(Math.max(width - roundedCompleteLength - (precision ? 1 : 0), 0)) .fill(options.incomplete ?? this.incomplete) .join(""); str = str.replace(":bar", complete + precise + incomplete); if (str !== this.lastStr) { const strLen = stripAnsiCode(str).length; if (strLen < this.lastStrLen) { str += " ".repeat(this.lastStrLen - strLen); } await this.write(str); this.lastStr = str; this.lastStrLen = strLen; } if (end) await this.end(); } /** * end: end a progress bar. * No need to call in most cases, unless you want to end before 100% */ async end() { if (__classPrivateFieldGet(this, _ProgressBar_end, "f")) return; __classPrivateFieldSet(this, _ProgressBar_end, true, "f"); if (this.clear) { await this.stdoutWrite("\r"); await this.clearLine(); } else { await this.breakLine(); } await this.showCursor(); // this.writer.releaseLock(); } /** * interrupt the progress bar and write a message above it * * @param message The message to write */ async console(message) { await this.clearLine(); await this.write(`${message}`); await this.breakLine(); await this.write(this.lastStr); } write(msg) { return this.stdoutWrite(`\r${msg}\x1b[?25l`); } get ttyColumns() { if (!dntShim.Deno.stdout.isTerminal()) return 100; return dntShim.Deno.consoleSize().columns; } breakLine() { return this.stdoutWrite("\n"); } stdoutWrite(msg) { // return this.writer.write(this.encoder.encode(msg)); return writeAll(this.writer, this.encoder.encode(msg)); } clearLine(direction = Direction.all) { switch (direction) { case Direction.all: return this.stdoutWrite("\x1b[2K"); case Direction.left: return this.stdoutWrite("\x1b[1K"); case Direction.right: return this.stdoutWrite("\x1b[0K"); } } showCursor() { return this.stdoutWrite("\x1b[?25h"); } } _ProgressBar_end = new WeakMap(); export default ProgressBar;