File size: 2,376 Bytes
a053984
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
'use strict';

var core = require('@babel/core');

const positionMethod = {
  start: "unshiftContainer",
  end: "pushContainer"
};
const addJSXAttribute = (_, opts) => {
  function getAttributeValue({
    literal,
    value
  }) {
    if (typeof value === "boolean") {
      return core.types.jsxExpressionContainer(core.types.booleanLiteral(value));
    }
    if (typeof value === "number") {
      return core.types.jsxExpressionContainer(core.types.numericLiteral(value));
    }
    if (typeof value === "string" && literal) {
      return core.types.jsxExpressionContainer(
        core.template.ast(value).expression
      );
    }
    if (typeof value === "string") {
      return core.types.stringLiteral(value);
    }
    return null;
  }
  function getAttribute({ spread, name, value, literal }) {
    if (spread) {
      return core.types.jsxSpreadAttribute(core.types.identifier(name));
    }
    return core.types.jsxAttribute(
      core.types.jsxIdentifier(name),
      getAttributeValue({ value, literal })
    );
  }
  return {
    visitor: {
      JSXOpeningElement(path) {
        if (!core.types.isJSXIdentifier(path.node.name))
          return;
        if (!opts.elements.includes(path.node.name.name))
          return;
        opts.attributes.forEach(
          ({
            name,
            value = null,
            spread = false,
            literal = false,
            position = "end"
          }) => {
            const method = positionMethod[position];
            const newAttribute = getAttribute({ spread, name, value, literal });
            const attributes = path.get("attributes");
            const isEqualAttribute = (attribute) => {
              if (spread)
                return attribute.isJSXSpreadAttribute() && attribute.get("argument").isIdentifier({ name });
              return attribute.isJSXAttribute() && attribute.get("name").isJSXIdentifier({ name });
            };
            const replaced = attributes.some((attribute) => {
              if (!isEqualAttribute(attribute))
                return false;
              attribute.replaceWith(newAttribute);
              return true;
            });
            if (!replaced) {
              path[method]("attributes", newAttribute);
            }
          }
        );
      }
    }
  };
};

module.exports = addJSXAttribute;
//# sourceMappingURL=index.js.map