function transform(file, { j }, options) { const root = j(file.source); let dirtyFlag = false; const { identifier } = removeImport('is-number', root, j); root .find(j.CallExpression, { callee: { type: 'Identifier', name: identifier } }) .replaceWith((path) => { const arg = path.node.arguments[0]; dirtyFlag = true; // Construct the detailed check const detailedCheck = j.logicalExpression( '||', j.binaryExpression( '===', // @ts-expect-error j.unaryExpression('typeof', arg, true), j.literal('number') ), j.logicalExpression( '&&', j.binaryExpression( '===', // @ts-expect-error j.unaryExpression('typeof', arg, true), j.literal('string') ), j.callExpression( j.memberExpression( j.identifier('Number'), j.identifier('isFinite') ), // @ts-expect-error [j.unaryExpression('+', arg, true)] ) ) ); return j.parenthesizedExpression(detailedCheck); }); return dirtyFlag ? root.toSource(options) : file.source; } export default transform; function removeImport(name, root, j) { // Find the import or require statement for 'is-boolean-object' const importDeclaration = root.find(j.ImportDeclaration, { source: { value: name } }); const requireDeclaration = root .find(j.CallExpression, { callee: { name: 'require' }, arguments: [ { value: name } ] }) .closest(j.VariableDeclarator); // Require statements without declarations like `Object.is = require("object-is");` const requireAssignment = root.find(j.AssignmentExpression, { operator: '=', right: { callee: { name: 'require' }, arguments: [ { value: name } ] } }); // Side effect requires statements like `require("error-cause/auto");` const sideEffectRequireExpression = root.find(j.ExpressionStatement, { expression: { callee: { name: 'require' }, arguments: [ { value: name } ] } }); // Return the identifier name, e.g. 'fn' in `import { fn } from 'is-boolean-object'` // or `var fn = require('is-boolean-object')` const identifier = importDeclaration.paths().length > 0 ? importDeclaration.get().node.specifiers[0].local.name : requireDeclaration.paths().length > 0 ? requireDeclaration.find(j.Identifier).get().node.name : requireAssignment.paths().length > 0 ? requireAssignment.find(j.Identifier).get().node.name : null; importDeclaration.remove(); requireDeclaration.remove(); requireAssignment.remove(); sideEffectRequireExpression.remove(); const dirtyFlag = importDeclaration.length > 0 || requireDeclaration.length > 0 || requireAssignment.length > 0 || sideEffectRequireExpression.length > 0; return { identifier, dirtyFlag }; }
Input
import isNumber from 'is-number'; isNumber(5e3); // true isNumber(0xff); // true isNumber(-1.1); // true isNumber(0); // true isNumber(1); // true isNumber(1.1); // true isNumber(10); // true isNumber(10.10); // true isNumber(100); // true isNumber('-1.1'); // true isNumber('0'); // true isNumber('012'); // true isNumber('0xff'); // true isNumber('1'); // true isNumber('1.1'); // true isNumber('10'); // true isNumber('10.10'); // true isNumber('100'); // true isNumber('5e3'); // true isNumber(parseInt('012')); // true isNumber(parseFloat('012')); // true
Output
loading
Read-only