UNPKG

file-prompt

Version:

An interactive prompt for selecting files from a directory.

196 lines (174 loc) 4.52 kB
import bindMethods from '../util/bind_methods'; import stripAnsi from 'strip-ansi'; import TransformAction from '../transform_action'; import { Transform } from 'stream'; /** * Generic Transform * A test class to expiriment with creating a series of transforms * * @class * @extends {stream.Transform} * @property {object} filters - Hash of filters to test the input against */ export default class BaseTransform extends Transform { filters = {}; params = {}; name = 'BaseTransform'; isDestroyed = false; /** * Constructor * Initializes the transform constructor * * @constructor * @param {object} [options] - Stream constructor options */ constructor (options) { super({ objectMode: true }); if (typeof this.getParams === 'function') { Object.assign(this.params, this.getParams(options)); } /** Manually bind the given methods to this instance for convienence */ bindMethods(this, 'errorHandler'); this.setListeners(); } /** * Create Action * Creates a transform action instance * * @method * @public * @param {object} data - Initial data to push * @returns {TransformAction} A new transform action */ createAction (data) { if (!data.creator) data.creator = this.name; return new TransformAction(data); } /** * Destroys the transform with an optional err param * * @param {string} err - Reason for destroying the stream from error */ destroy (err) { if (this.isDestroyed) return; this.isDestroyed = true; process.nextTick(() => { if (err) this.emit('error', err); this.emit('close'); }); } /** * Error Handler * Default handler for stream errors * * @method * @public * @param {Error} err - Caught exception error instance */ errorHandler (err) { process.stderr.write(`${err.stack || err.message}\n`); process.exit(1); } /** * Filter Data * Predicate to determine if the incoming chunk matches the filters of this * transformation. * * @method * @public * @param {object} filters - Object containing filtered props and values * @param {object} chunk - Raw input read from input stream * @returns {boolean} If the chunk matches the given filter */ filterData (filters, chunk) { return Object.keys(filters).every((name) => { return filters[name] === chunk[name]; }); } /** * Match Error * Pushes a match error down the stream. This is used when the raw input * is invalid or no matches were found. * * @method * @public * @param {string} searchFor - Original query value */ matchError (searchFor) { let err = stripAnsi(searchFor.toString()).trim(); /** Format the match error */ if (err) err = ` (${err})`; err = `Huh${err}?`; this.pushError(err); } /** * Push Action * Pushes an action down the stream * * @method * @public * @param {object} data - Action data to push * @param {object} options - Extra options and flags */ pushAction (data) { this.push(this.createAction(data)); } /** * Push Error * * @method * @public * @param {Error} err - Error instance to push down the stream */ pushError (err) { this.pushAction({ type: 'error', data: err, }); } /** * Set Listeners * Sets any necessary listeners such as an error handler. Can be overridden * in a subclass. * * @method * @private */ setListeners () { this.on('error', this.errorHandler); } /** * Transform * Transforms the incoming data and returns the new output * * @method * @public * @param {object} input - Original input read from the incoming stream */ transform (input) { this.push(input); } /** * Transform * Stream method to transform read data, transform it, then move it to the * next stream. * * @method * @param {buffer} chunk - Buffer read from the input stream * @param {string} enc - Encoding of the input stream chunk buffer * @param {function} done - Callback to fire when transform is complete * @returns {*} Result of the done callback */ _transform (chunk, enc, done) { try { // Filter the chunk and see if we should be transforming it at all if (!this.filterData(this.filters, chunk)) return done(null, chunk); this.transform(chunk); return done(); } catch (e) { this.emit('error', e); done(); } } }