# All files / src/utils map-node.js

100% Statements 31/31
100% Branches 20/20
100% Functions 8/8
100% Lines 30/30

    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
    6815092x

    3938x
    1x

    3937x
    3937x
    3937x
    3440x

    496x

    3936x
    3440x

    496x
    496x

    768x

    495x

    89x

    437x
    15088x
    65x

    15023x
    15023x
    5x

    15018x
    422x

    14596x

    15023x
    414x

    14609x
    14609x

    14609x

    437x

     const identity = id => id;

    function map(visitors) {
      function mapper(input) {
        if (!Array.isArray(input)) {
          throw new Error(
            'Transform must be used on an Array. Received ' + JSON.stringify(input)
          );
        }
        const visitor = (() => {
          const [node] = input;
          if (node.Type in visitors && typeof visitors[node.Type] === 'function') {
            return visitors[node.Type];
          }
          return identity;
        })();

        if (visitor.length === 2) {
          return visitor(input, mapper);
        }

        const [node, ...rest] = visitor(input);
        const params = node.params
          .filter(Boolean)
          .map(child => mapper([child, ...rest]));

        return { ...node, params };
      }

      return mapper;
    }

    // This should maybe be it's own module.
    export { map };

    export default function mapNode(visitor) {
      const nodeMapper = node => {
        if (node == null) {
          return node;
        }

        const mappingFunction = (() => {
          if ('*' in visitor && typeof visitor['*'] === 'function') {
            return visitor['*'];
          }

          if (node.Type in visitor && typeof visitor[node.Type] === 'function') {
            return visitor[node.Type];
          }
          return identity;
        })();

        if (mappingFunction.length === 2) {
          return mappingFunction(node, nodeMapper);
        }

        const mappedNode = mappingFunction(node);
        const params = mappedNode.params.map(nodeMapper);

        return {
          ...mappedNode,
          params,
        };
      };

      return nodeMapper;
    }