All files / style9/src/helpers normalize-arguments.js

100% Statements 31/31
100% Branches 14/14
100% Functions 9/9
100% Lines 31/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 878x     21x 5x         46x       46x 1x             6x 7x 5x   5x               9x 8x   8x             3x 2x 1x 1x   1x                   31x 30x         45x 51x 6x     45x 31x     14x 9x     5x 3x     2x       8x  
const t = require('@babel/types');
 
function assertType(nodePath, type, opts) {
  if (!t[`is${type}`](nodePath.node, opts)) {
    throw nodePath.buildCodeFrameError(`Unsupported type ${nodePath.type}`);
  }
}
 
function assertInStyles(stringOrIdentifier, styleNames) {
  const value = t.isStringLiteral(stringOrIdentifier)
    ? stringOrIdentifier.node.value
    : stringOrIdentifier.node.name;
 
  if (!styleNames.includes(value)) {
    throw stringOrIdentifier.buildCodeFrameError(
      `Property ${value} does not exist in style object`
    );
  }
}
 
function normalizeObjectExpression(objectExpr, styleNames) {
  return objectExpr.get('properties').map(prop => {
    assertType(prop, 'ObjectProperty', { computed: false });
    assertInStyles(prop.get('key'), styleNames);
 
    return {
      test: prop.node.value,
      value: prop.node.key.name
    };
  });
}
 
function normalizeLogicalExpression(logicalExpr, styleNames) {
  assertType(logicalExpr.get('right'), 'StringLiteral');
  assertInStyles(logicalExpr.get('right'), styleNames);
 
  return {
    test: logicalExpr.node.left,
    value: logicalExpr.node.right.value
  };
}
 
function normalizeConditionalExpression(conditionalExpr, styleNames) {
  assertType(conditionalExpr.get('consequent'), 'StringLiteral');
  assertType(conditionalExpr.get('alternate'), 'StringLiteral');
  assertInStyles(conditionalExpr.get('alternate'), styleNames);
  assertInStyles(conditionalExpr.get('consequent'), styleNames);
 
  return [
    conditionalExpr.node.alternate.value,
    {
      test: conditionalExpr.node.test,
      value: conditionalExpr.node.consequent.value
    }
  ];
}
 
function normalizeStringLiteral(stringLiteral, styleNames) {
  assertInStyles(stringLiteral, styleNames);
  return stringLiteral.node.value;
}
 
// Map resolver arguments to strings and logical ANDs
function normalizeArguments(callExpr, styleNames) {
  return callExpr.get('arguments').flatMap(arg => {
    if (t.isObjectExpression(arg.node)) {
      return normalizeObjectExpression(arg, styleNames);
    }
 
    if (t.isStringLiteral(arg.node)) {
      return normalizeStringLiteral(arg, styleNames);
    }
 
    if (t.isLogicalExpression(arg.node, { operator: '&&' })) {
      return normalizeLogicalExpression(arg, styleNames);
    }
 
    if (t.isConditionalExpression(arg.node)) {
      return normalizeConditionalExpression(arg, styleNames);
    }
 
    throw arg.buildCodeFrameError(`Unsupported type ${arg.node.type}`);
  });
}
 
module.exports = normalizeArguments;