UNPKG

mush-format

Version:

A javascript library that minifies pretty formatted mushcode.

126 lines (109 loc) 3.33 kB
const { EventEmitter } = require("events"); const fileType = require("../plugins/core/fileType"); const openFile = require("../plugins/core/open"); const render = require("../plugins/core/render"); const compress = require("../plugins/core/compress"); const pkg = require("../package.json"); /** new MushFormatter() */ class MushFormatter extends EventEmitter { constructor() { super(); this.log = []; this._stack = new Map(); this._stack.set("pre", []); this._stack.set("open", []); this._stack.set("render", []); this._stack.set("compress", []); this._stack.set("finishing", []); } /** * Register middleware to be used during the formatting process. * @param {String} step The portion of the formatting process * where the middleware should fire. * @param {*} middleware The function to be run against included * data during a particular step. */ use(step, middleware) { if (typeof middleware !== "function") { throw new Error("Middleware must be a function."); } if (!step) { throw new Error("Formatting step must be supplied."); } const stepValue = this._stack.get(step); stepValue.push(middleware); this._stack.set(step, stepValue); } /** * Process data with middleware functions. * @param {Object} [data = {}] Data passed to the middleware functions */ async process(step, data) { let idx = 0; const next = async (err, data) => { if (err) return Promise.reject(err); if (idx >= this._stack.get(step).length) return Promise.resolve(data); const layer = this._stack.get(step)[idx++]; try { data = await layer(data, next); } catch (error) { next(error); } }; await next(null, data); } /** * Format text. * @param {String} text The relative file path, url or text string to * be formatted */ async format(text) { // In the future I might turn this into it's own class. let data = { input: text, type: "", raw: "", headers: [], footers: [], github: { user: "", repo: "" }, output: "", cache: new Map(), emit: (type, data) => this.emit(type, data), logger: message => this.logger(message), debug: false }; // Install the core middleware. this.use("pre", fileType); this.use("open", openFile); this.use("render", render); this.use("compress", compress); // I'm passing data around here. There's probably a more elegant // way to do this. this.log = []; this.logger("Begin formatting"); await this.process("pre", data); await this.process("open", data); await this.process("render", data); await this.process("compress", data); data.log = this.log; this.emit("done", { text: data.output, log: this.log }); return { version: this.version(), text: data.output.trim() }; } /** * Send the current version of the library */ version() { return pkg.version; } logger(message) { const date = new Date(); this.log.push(`[${date.toLocaleString()}] ${message}`); } } module.exports = MushFormatter;