UNPKG

luhn-generator

Version:

A generator of numbers that passes the validation of Luhn algorithm or Luhn formula, also known as the 'modulus 10' or 'mod 10' algorithm

149 lines (127 loc) 3.61 kB
'use strict'; /** * Base prompt implementation * Should be extended by prompt types. */ var _ = require('lodash'); var chalk = require('chalk'); var runAsync = require('run-async'); var { filter, flatMap, share, take, takeUntil } = require('rxjs/operators'); var Choices = require('../objects/choices'); var ScreenManager = require('../utils/screen-manager'); class Prompt { constructor(question, rl, answers) { // Setup instance defaults property _.assign(this, { answers: answers, status: 'pending' }); // Set defaults prompt options this.opt = _.defaults(_.clone(question), { validate: () => true, filter: val => val, when: () => true, suffix: '', prefix: chalk.green('?') }); // Make sure name is present if (!this.opt.name) { this.throwParamError('name'); } // Set default message if no message defined if (!this.opt.message) { this.opt.message = this.opt.name + ':'; } // Normalize choices if (Array.isArray(this.opt.choices)) { this.opt.choices = new Choices(this.opt.choices, answers); } this.rl = rl; this.screen = new ScreenManager(this.rl); } /** * Start the Inquiry session and manage output value filtering * @return {Promise} */ run() { return new Promise(resolve => { this._run(value => resolve(value)); }); } // Default noop (this one should be overwritten in prompts) _run(cb) { cb(); } /** * Throw an error telling a required parameter is missing * @param {String} name Name of the missing param * @return {Throw Error} */ throwParamError(name) { throw new Error('You must provide a `' + name + '` parameter'); } /** * Called when the UI closes. Override to do any specific cleanup necessary */ close() { this.screen.releaseCursor(); } /** * Run the provided validation method each time a submit event occur. * @param {Rx.Observable} submit - submit event flow * @return {Object} Object containing two observables: `success` and `error` */ handleSubmitEvents(submit) { var self = this; var validate = runAsync(this.opt.validate); var asyncFilter = runAsync(this.opt.filter); var validation = submit.pipe( flatMap(value => asyncFilter(value, self.answers).then( filteredValue => validate(filteredValue, self.answers).then( isValid => ({ isValid: isValid, value: filteredValue }), err => ({ isValid: err }) ), err => ({ isValid: err }) ) ), share() ); var success = validation.pipe( filter(state => state.isValid === true), take(1) ); var error = validation.pipe( filter(state => state.isValid !== true), takeUntil(success) ); return { success: success, error: error }; } /** * Generate the prompt question string * @return {String} prompt question string */ getQuestion() { var message = this.opt.prefix + ' ' + chalk.bold(this.opt.message) + this.opt.suffix + chalk.reset(' '); // Append the default if available, and if question isn't answered if (this.opt.default != null && this.status !== 'answered') { // If default password is supplied, hide it if (this.opt.type === 'password') { message += chalk.italic.dim('[hidden] '); } else { message += chalk.dim('(' + this.opt.default + ') '); } } return message; } } module.exports = Prompt;