UNPKG

rozenite-preview

Version:

A Rozenite plugin that lets you select React Native components in DevTools and preview them live on your simulator. Ideal for rapid UI development, component testing, and debugging complex apps.

133 lines (132 loc) 3.92 kB
import * as o from "@babel/types"; import c from "node:path"; function u(n) { if (n.findParent( (e) => e.isJSXElement() || e.isJSXFragment() || e.isJSXExpressionContainer() ) || n.findParent((e) => { if (!e.isCallExpression()) return !1; const t = e.node.callee; return o.isIdentifier(t) && /^use[A-Z]/.test(t.name); }) || n.findParent((e) => e.isClassMethod() ? f(e) : !1)) return !0; const r = n.getFunctionParent(); return !!(r && m(r)); } function f(n) { const r = n.findParent((t) => t.isClassDeclaration()); if (!r || !r.isClassDeclaration()) return !1; const e = r.node.superClass; return e ? o.isIdentifier(e) ? ["Component", "PureComponent"].includes(e.name) : o.isMemberExpression(e) && o.isIdentifier(e.object) && o.isIdentifier(e.property) ? e.object.name === "React" && ["Component", "PureComponent"].includes(e.property.name) : !1 : !1; } function m(n) { let r = !1; return n.traverse({ ReturnStatement(e) { const t = e.node.argument; t && (o.isJSXElement(t) || o.isJSXFragment(t)) && (r = !0, e.stop()); }, JSXElement() { r = !0; }, JSXFragment() { r = !0; } }), r; } const d = "rozenite-preview", p = "registerPreview", g = 2; function R() { return { visitor: { Program(n, r) { const e = C(n, o); e.size !== 0 && n.traverse({ CallExpression(t) { b(t, e) && (P(t, r, o), w(t, o)); } }); } } }; } function C(n, r) { const e = /* @__PURE__ */ new Set(); return n.get("body").forEach((t) => { I(t) && t.isImportDeclaration() && t.node.specifiers.forEach((s) => { y(s, r) && e.add(s.local.name); }); }), e; } function I(n) { return n.isImportDeclaration() && n.node.source.value === d; } function y(n, r) { return r.isImportSpecifier(n) || r.isImportDefaultSpecifier(n); } function P(n, r, e) { const t = r.file.opts.filename || "", s = c.relative(process.cwd(), t), i = v(n), a = e.stringLiteral(t), l = e.objectExpression([ e.objectProperty(e.identifier("filePath"), a), e.objectProperty( e.identifier("relativeFilename"), e.stringLiteral(s) ), e.objectProperty( e.identifier("isInsideReactComponent"), e.booleanLiteral(u(n)) ), e.objectProperty( e.identifier("name"), e.stringLiteral(i.name ?? "") ), e.objectProperty( e.identifier("nameType"), e.stringLiteral(i.nameType) ), e.objectProperty(e.identifier("callId"), e.stringLiteral(i.callId)), e.objectProperty( e.identifier("componentType"), e.stringLiteral(i.componentType) ), e.objectProperty(e.identifier("line"), e.numericLiteral(i.line)), e.objectProperty(e.identifier("column"), e.numericLiteral(i.column)) ]); n.node.arguments.push(l); } function E(n) { if (!n) return "unknown"; switch (n.type) { case "Identifier": return `component:${n.name}`; case "ArrowFunctionExpression": case "FunctionExpression": return "inline-function"; case "CallExpression": return "call-expression"; default: return n.type.toLowerCase(); } } function v(n) { const r = n.node.arguments[0], e = n.node.arguments[1], t = n.node.loc; let s = null, i = "unknown"; r && r.type === "StringLiteral" ? (s = r.value, i = "literal") : r && r.type === "Identifier" && (s = `<dynamic:${r.name}>`, i = "identifier"); const a = `${s}:${t?.start?.line || 0}:${t?.start?.column || 0}`; return { name: s, nameType: i, callId: a, line: t?.start?.line || 0, column: t?.start?.column || 0, componentType: E(e) }; } function b(n, r) { const e = n.get("callee"); return e.isIdentifier() && e.node.name === p && r.has(e.node.name) && n.node.arguments.length === g; } function w(n, r) { const { node: e } = n; e.arguments.unshift(r.identifier("module")); } export { R as default };