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

194 lines (162 loc) 4.24 kB
'use strict'; var chars = require('./chars'); var utils = require('./utils'); /** * Expose `Glob` */ var Glob = module.exports = function Glob(pattern, options) { if (!(this instanceof Glob)) { return new Glob(pattern, options); } this.options = options || {}; this.pattern = pattern; this.history = []; this.tokens = {}; this.init(pattern); }; /** * Initialize defaults */ Glob.prototype.init = function(pattern) { this.orig = pattern; this.negated = this.isNegated(); this.options.track = this.options.track || false; this.options.makeRe = true; }; /** * Push a change into `glob.history`. Useful * for debugging. */ Glob.prototype.track = function(msg) { if (this.options.track) { this.history.push({msg: msg, pattern: this.pattern}); } }; /** * Return true if `glob.pattern` was negated * with `!`, also remove the `!` from the pattern. * * @return {Boolean} */ Glob.prototype.isNegated = function() { if (this.pattern.charCodeAt(0) === 33 /* '!' */) { this.pattern = this.pattern.slice(1); return true; } return false; }; /** * Expand braces in the given glob pattern. * * We only need to use the [braces] lib when * patterns are nested. */ Glob.prototype.braces = function() { if (this.options.nobraces !== true && this.options.nobrace !== true) { // naive/fast check for imbalanced characters var a = this.pattern.match(/[\{\(\[]/g); var b = this.pattern.match(/[\}\)\]]/g); // if imbalanced, don't optimize the pattern if (a && b && (a.length !== b.length)) { this.options.makeRe = false; } // expand brace patterns and join the resulting array var expanded = utils.braces(this.pattern, this.options); this.pattern = expanded.join('|'); } }; /** * Expand bracket expressions in `glob.pattern` */ Glob.prototype.brackets = function() { if (this.options.nobrackets !== true) { this.pattern = utils.brackets(this.pattern); } }; /** * Expand bracket expressions in `glob.pattern` */ Glob.prototype.extglob = function() { if (this.options.noextglob === true) return; if (utils.isExtglob(this.pattern)) { this.pattern = utils.extglob(this.pattern, {escape: true}); } }; /** * Parse the given pattern */ Glob.prototype.parse = function(pattern) { this.tokens = utils.parseGlob(pattern || this.pattern, true); return this.tokens; }; /** * Replace `a` with `b`. Also tracks the change before and * after each replacement. This is disabled by default, but * can be enabled by setting `options.track` to true. * * Also, when the pattern is a string, `.split()` is used, * because it's much faster than replace. * * @param {RegExp|String} `a` * @param {String} `b` * @param {Boolean} `escape` When `true`, escapes `*` and `?` in the replacement. * @return {String} */ Glob.prototype._replace = function(a, b, escape) { this.track('before (find): "' + a + '" (replace with): "' + b + '"'); if (escape) b = esc(b); if (a && b && typeof a === 'string') { this.pattern = this.pattern.split(a).join(b); } else { this.pattern = this.pattern.replace(a, b); } this.track('after'); }; /** * Escape special characters in the given string. * * @param {String} `str` Glob pattern * @return {String} */ Glob.prototype.escape = function(str) { this.track('before escape: '); var re = /["\\](['"]?[^"'\\]['"]?)/g; this.pattern = str.replace(re, function($0, $1) { var o = chars.ESC; var ch = o && o[$1]; if (ch) { return ch; } if (/[a-z]/i.test($0)) { return $0.split('\\').join(''); } return $0; }); this.track('after escape: '); }; /** * Unescape special characters in the given string. * * @param {String} `str` * @return {String} */ Glob.prototype.unescape = function(str) { var re = /__([A-Z]+)_([A-Z]+)__/g; this.pattern = str.replace(re, function($0, $1) { return chars[$1][$0]; }); this.pattern = unesc(this.pattern); }; /** * Escape/unescape utils */ function esc(str) { str = str.split('?').join('%~'); str = str.split('*').join('%%'); return str; } function unesc(str) { str = str.split('%~').join('?'); str = str.split('%%').join('*'); return str; }