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

109 lines (87 loc) 2.48 kB
"use strict"; const flipSeen = Symbol("flipSeen"); module.exports = function (t) { return { hasSeen(node) { return !!node[flipSeen]; }, // Takes an expressions and determines if it has // more nodes that could benifit from flipping than not. shouldFlip(topNode, savings = 0) { visit(topNode); return savings > 0; function visit(node) { if (t.isUnaryExpression(node, { operator: "!" })) { savings++; return; } if (t.isLogicalExpression(node)) { visit(node.left); visit(node.right); return; } if (!(t.isBinaryExpression(node) && t.EQUALITY_BINARY_OPERATORS.indexOf(node.operator) > -1)) { // Binary expressions wouldn't hurut because we know how to flip them savings--; } } }, flip(node, resultNotUsed) { let lastNodeDesc; const ret = visit(node); ret[flipSeen] = true; if (resultNotUsed && lastNodeDesc) { const _lastNodeDesc = lastNodeDesc, parent = _lastNodeDesc.parent, key = _lastNodeDesc.key; if (parent && key && t.isUnaryExpression(parent[key], { operator: "!" })) { parent[key] = parent[key].argument; } } return ret; function visit(node, parent, key) { lastNodeDesc = { parent, key }; if (t.isUnaryExpression(node, { operator: "!" })) { return node.argument; } if (t.isLogicalExpression(node)) { node.operator = node.operator === "&&" ? "||" : "&&"; node.left = visit(node.left, node, "left"); node.right = visit(node.right, node, "right"); return node; } if (t.isBinaryExpression(node)) { let operator; switch (node.operator) { case "!==": operator = "==="; break; case "===": operator = "!=="; break; case "!=": operator = "=="; break; case "==": operator = "!="; break; } if (operator) { node.operator = operator; return node; } // Falls through to unary expression } return t.unaryExpression("!", node, true); } } }; };