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
JavaScript
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
};