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

128 lines (101 loc) 4.1 kB
'use strict'; const yargs = require('yargs/yargs'); const flatten = require('flat'); const { castArray, some, isPlainObject, camelCase, kebabCase, omitBy } = require('lodash'); function isAlias(key, alias) { return some(alias, (aliases) => castArray(aliases).indexOf(key) !== -1); } function hasDefaultValue(key, value, defaults) { return value === defaults[key]; } function isCamelCased(key, argv) { return /[A-Z]/.test(key) && camelCase(key) === key && // Is it camel case? argv[kebabCase(key)] != null; // Is the standard version defined? } function keyToFlag(key) { return key.length === 1 ? `-${key}` : `--${key}`; } function unparseOption(key, value, unparsed) { if (typeof value === 'string') { unparsed.push(keyToFlag(key), value); } else if (value === true) { unparsed.push(keyToFlag(key)); } else if (value === false) { unparsed.push(`--no-${key}`); } else if (Array.isArray(value)) { value.forEach((item) => unparseOption(key, item, unparsed)); } else if (isPlainObject(value)) { const flattened = flatten(value, { safe: true }); for (const flattenedKey in flattened) { if (!isCamelCased(flattenedKey, flattened)) { unparseOption(`${key}.${flattenedKey}`, flattened[flattenedKey], unparsed); } } // Fallback case (numbers and other types) } else if (value != null) { unparsed.push(keyToFlag(key), `${value}`); } } function unparsePositional(argv, options, unparsed) { const knownPositional = []; // Unparse command if set, collecting all known positional arguments // e.g.: build <first> <second> <rest...> if (options.command) { const { 0: cmd, index } = options.command.match(/[^<[]*/); const { demanded, optional } = yargs() .getCommandInstance() .parseCommand(`foo ${options.command.substr(index + cmd.length)}`); // Push command (can be a deep command) unparsed.push(...cmd.trim().split(/\s+/)); // Push positional arguments [...demanded, ...optional].forEach(({ cmd: cmds, variadic }) => { knownPositional.push(...cmds); const cmd = cmds[0]; const args = (variadic ? argv[cmd] || [] : [argv[cmd]]) .filter((arg) => arg != null) .map((arg) => `${arg}`); unparsed.push(...args); }); } // Unparse unkown positional arguments argv._ && unparsed.push(...argv._.slice(knownPositional.length)); return knownPositional; } function unparseOptions(argv, options, knownPositional, unparsed) { const optionsArgv = omitBy(argv, (value, key) => // Remove positional arguments knownPositional.includes(key) || // Remove special _, -- and $0 ['_', '--', '$0'].includes(key) || // Remove aliases isAlias(key, options.alias) || // Remove default values hasDefaultValue(key, value, options.default) || // Remove camel-cased isCamelCased(key, argv)); for (const key in optionsArgv) { unparseOption(key, optionsArgv[key], unparsed); } } function unparseEndOfOptions(argv, options, unparsed) { // Unparse ending (--) arguments if set argv['--'] && unparsed.push('--', ...argv['--']); } // ------------------------------------------------------------ function unparser(argv, options) { options = Object.assign({ alias: {}, default: {}, command: null, }, options); const unparsed = []; // Unparse known & unknown positional arguments (foo <first> <second> [rest...]) // All known positional will be returned so that they are not added as flags const knownPositional = unparsePositional(argv, options, unparsed); // Unparse option arguments (--foo hello --bar hi) unparseOptions(argv, options, knownPositional, unparsed); // Unparse "end-of-options" arguments (stuff after " -- ") unparseEndOfOptions(argv, options, unparsed); return unparsed; } module.exports = unparser;