index.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. 'use strict';
  2. var core = require('@babel/core');
  3. const defaultTemplate = (variables, { tpl }) => {
  4. return tpl`
  5. ${variables.imports};
  6. ${variables.interfaces};
  7. const ${variables.componentName} = (${variables.props}) => (
  8. ${variables.jsx}
  9. );
  10. ${variables.exports};
  11. `;
  12. };
  13. var __defProp = Object.defineProperty;
  14. var __defProps = Object.defineProperties;
  15. var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  16. var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  17. var __hasOwnProp = Object.prototype.hasOwnProperty;
  18. var __propIsEnum = Object.prototype.propertyIsEnumerable;
  19. var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  20. var __spreadValues = (a, b) => {
  21. for (var prop in b || (b = {}))
  22. if (__hasOwnProp.call(b, prop))
  23. __defNormalProp(a, prop, b[prop]);
  24. if (__getOwnPropSymbols)
  25. for (var prop of __getOwnPropSymbols(b)) {
  26. if (__propIsEnum.call(b, prop))
  27. __defNormalProp(a, prop, b[prop]);
  28. }
  29. return a;
  30. };
  31. var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  32. const tsOptionalPropertySignature = (...args) => {
  33. return __spreadProps(__spreadValues({}, core.types.tsPropertySignature(...args)), {
  34. optional: true
  35. });
  36. };
  37. const getOrCreateImport = ({ imports }, sourceValue) => {
  38. const existing = imports.find(
  39. (imp2) => imp2.source.value === sourceValue && !imp2.specifiers.some(
  40. (specifier) => specifier.type === "ImportNamespaceSpecifier"
  41. )
  42. );
  43. if (existing)
  44. return existing;
  45. const imp = core.types.importDeclaration([], core.types.stringLiteral(sourceValue));
  46. imports.push(imp);
  47. return imp;
  48. };
  49. const tsTypeReferenceSVGProps = (ctx) => {
  50. if (ctx.opts.native) {
  51. const identifier2 = core.types.identifier("SvgProps");
  52. getOrCreateImport(ctx, "react-native-svg").specifiers.push(
  53. core.types.importSpecifier(identifier2, identifier2)
  54. );
  55. return core.types.tsTypeReference(identifier2);
  56. }
  57. const identifier = core.types.identifier("SVGProps");
  58. getOrCreateImport(ctx, ctx.importSource).specifiers.push(
  59. core.types.importSpecifier(identifier, identifier)
  60. );
  61. return core.types.tsTypeReference(
  62. identifier,
  63. core.types.tsTypeParameterInstantiation([
  64. core.types.tsTypeReference(core.types.identifier("SVGSVGElement"))
  65. ])
  66. );
  67. };
  68. const tsTypeReferenceSVGRef = (ctx) => {
  69. const identifier = core.types.identifier("Ref");
  70. getOrCreateImport(ctx, ctx.importSource).specifiers.push(
  71. core.types.importSpecifier(identifier, identifier)
  72. );
  73. return core.types.tsTypeReference(
  74. identifier,
  75. core.types.tsTypeParameterInstantiation([
  76. core.types.tsTypeReference(core.types.identifier("SVGSVGElement"))
  77. ])
  78. );
  79. };
  80. const getJsxRuntimeImport = (cfg) => {
  81. const specifiers = (() => {
  82. if (cfg.namespace)
  83. return [core.types.importNamespaceSpecifier(core.types.identifier(cfg.namespace))];
  84. if (cfg.specifiers)
  85. return cfg.specifiers.map((specifier) => {
  86. const identifier = core.types.identifier(specifier);
  87. return core.types.importSpecifier(identifier, identifier);
  88. });
  89. throw new Error(
  90. `Specify either "namespace" or "specifiers" in "jsxRuntimeImport" option`
  91. );
  92. })();
  93. return core.types.importDeclaration(specifiers, core.types.stringLiteral(cfg.source));
  94. };
  95. const defaultJsxRuntimeImport = {
  96. source: "react",
  97. namespace: "React"
  98. };
  99. const defaultImportSource = "react";
  100. const getVariables = ({
  101. opts,
  102. jsx
  103. }) => {
  104. var _a, _b, _c, _d;
  105. const interfaces = [];
  106. const props = [];
  107. const imports = [];
  108. const exports = [];
  109. const ctx = {
  110. importSource: (_a = opts.importSource) != null ? _a : defaultImportSource,
  111. exportIdentifier: core.types.identifier(opts.state.componentName),
  112. opts,
  113. interfaces,
  114. props,
  115. imports,
  116. exports
  117. };
  118. if (opts.jsxRuntime !== "automatic") {
  119. imports.push(
  120. getJsxRuntimeImport((_b = opts.jsxRuntimeImport) != null ? _b : defaultJsxRuntimeImport)
  121. );
  122. }
  123. if (opts.native) {
  124. getOrCreateImport(ctx, "react-native-svg").specifiers.push(
  125. core.types.importDefaultSpecifier(core.types.identifier("Svg"))
  126. );
  127. }
  128. if (opts.titleProp || opts.descProp) {
  129. const properties = [];
  130. const propertySignatures = [];
  131. const createProperty = (attr) => {
  132. return core.types.objectProperty(
  133. core.types.identifier(attr),
  134. core.types.identifier(attr),
  135. false,
  136. true
  137. );
  138. };
  139. const createSignature = (attr) => {
  140. return tsOptionalPropertySignature(
  141. core.types.identifier(attr),
  142. core.types.tsTypeAnnotation(core.types.tsStringKeyword())
  143. );
  144. };
  145. if (opts.titleProp) {
  146. properties.push(createProperty("title"), createProperty("titleId"));
  147. if (opts.typescript) {
  148. propertySignatures.push(
  149. createSignature("title"),
  150. createSignature("titleId")
  151. );
  152. }
  153. }
  154. if (opts.descProp) {
  155. properties.push(createProperty("desc"), createProperty("descId"));
  156. if (opts.typescript) {
  157. propertySignatures.push(
  158. createSignature("desc"),
  159. createSignature("descId")
  160. );
  161. }
  162. }
  163. const prop = core.types.objectPattern(properties);
  164. props.push(prop);
  165. if (opts.typescript) {
  166. interfaces.push(
  167. core.types.tsInterfaceDeclaration(
  168. core.types.identifier("SVGRProps"),
  169. null,
  170. null,
  171. core.types.tSInterfaceBody(propertySignatures)
  172. )
  173. );
  174. prop.typeAnnotation = core.types.tsTypeAnnotation(
  175. core.types.tsTypeReference(core.types.identifier("SVGRProps"))
  176. );
  177. }
  178. }
  179. if (opts.expandProps) {
  180. const identifier = core.types.identifier("props");
  181. if (core.types.isObjectPattern(props[0])) {
  182. props[0].properties.push(core.types.restElement(identifier));
  183. if (opts.typescript) {
  184. props[0].typeAnnotation = core.types.tsTypeAnnotation(
  185. core.types.tsIntersectionType([
  186. tsTypeReferenceSVGProps(ctx),
  187. props[0].typeAnnotation.typeAnnotation
  188. ])
  189. );
  190. }
  191. } else {
  192. props.push(identifier);
  193. if (opts.typescript) {
  194. identifier.typeAnnotation = core.types.tsTypeAnnotation(
  195. tsTypeReferenceSVGProps(ctx)
  196. );
  197. }
  198. }
  199. }
  200. if (opts.ref) {
  201. if (props.length === 0) {
  202. props.push(core.types.identifier("_"));
  203. }
  204. const prop = core.types.identifier("ref");
  205. props.push(prop);
  206. if (opts.typescript) {
  207. prop.typeAnnotation = core.types.tsTypeAnnotation(tsTypeReferenceSVGRef(ctx));
  208. }
  209. const forwardRef = core.types.identifier("forwardRef");
  210. const ForwardRef = core.types.identifier("ForwardRef");
  211. getOrCreateImport(ctx, ctx.importSource).specifiers.push(
  212. core.types.importSpecifier(forwardRef, forwardRef)
  213. );
  214. exports.push(
  215. core.types.variableDeclaration("const", [
  216. core.types.variableDeclarator(
  217. ForwardRef,
  218. core.types.callExpression(forwardRef, [ctx.exportIdentifier])
  219. )
  220. ])
  221. );
  222. ctx.exportIdentifier = ForwardRef;
  223. }
  224. if (opts.memo) {
  225. const memo = core.types.identifier("memo");
  226. const Memo = core.types.identifier("Memo");
  227. getOrCreateImport(ctx, ctx.importSource).specifiers.push(
  228. core.types.importSpecifier(memo, memo)
  229. );
  230. exports.push(
  231. core.types.variableDeclaration("const", [
  232. core.types.variableDeclarator(
  233. Memo,
  234. core.types.callExpression(memo, [ctx.exportIdentifier])
  235. )
  236. ])
  237. );
  238. ctx.exportIdentifier = Memo;
  239. }
  240. if (((_c = opts.state.caller) == null ? void 0 : _c.previousExport) || opts.exportType === "named") {
  241. if (!opts.namedExport) {
  242. throw new Error(`"namedExport" not specified`);
  243. }
  244. exports.push(
  245. core.types.exportNamedDeclaration(null, [
  246. core.types.exportSpecifier(ctx.exportIdentifier, core.types.identifier(opts.namedExport))
  247. ])
  248. );
  249. if ((_d = opts.state.caller) == null ? void 0 : _d.previousExport) {
  250. const previousExportAst = core.template.ast(opts.state.caller.previousExport);
  251. exports.push(
  252. ...Array.isArray(previousExportAst) ? previousExportAst : [previousExportAst]
  253. );
  254. }
  255. } else {
  256. exports.push(core.types.exportDefaultDeclaration(ctx.exportIdentifier));
  257. }
  258. return {
  259. componentName: opts.state.componentName,
  260. props,
  261. interfaces,
  262. imports,
  263. exports,
  264. jsx
  265. };
  266. };
  267. const plugin = (_, opts) => {
  268. const template = opts.template || defaultTemplate;
  269. const plugins = opts.typescript ? ["jsx", "typescript"] : ["jsx"];
  270. const tpl = core.template.smart({ plugins, preserveComments: true }).ast;
  271. return {
  272. visitor: {
  273. Program(path) {
  274. const jsx = path.node.body[0].expression;
  275. const variables = getVariables({
  276. opts,
  277. jsx
  278. });
  279. const body = template(variables, { options: opts, tpl });
  280. path.node.body = Array.isArray(body) ? body : [body];
  281. path.replaceWith(path.node);
  282. }
  283. }
  284. };
  285. };
  286. module.exports = plugin;
  287. //# sourceMappingURL=index.js.map