Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-estrela

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-estrela - npm Package Compare versions

Comparing version 0.3.1 to 0.10.0

dist/shared/tags.d.ts

17

dist/index.d.ts

@@ -1,4 +0,6 @@

import * as t from '@babel/types';
import { Options } from './options';
export type { Options } from './options';
import { transformComponent } from './transforms/component.transform';
import { transformJSX } from './transforms/jsx.transform';
import { transformStyles } from './transforms/styles.transform';
import { Options } from './types';
export * from './types';
declare const _default: (api: object, options: Options | null | undefined, dirname: string) => {

@@ -8,5 +10,12 @@ name: string;

visitor: {
Program(this: import("@babel/core").PluginPass, path: import("@babel/traverse").NodePath<t.Program>): void;
Program: {
enter(path: import("@babel/traverse").NodePath<import("@babel/types").Program>): void;
exit(path: import("@babel/traverse").NodePath<import("@babel/types").Program>): void;
};
Function: typeof transformComponent;
JSXElement: typeof transformJSX;
JSXFragment: typeof transformJSX;
TaggedTemplateExpression: typeof transformStyles;
};
};
export default _default;

@@ -112,3 +112,3 @@ var __create = Object.create;

});
exports.default = annotateAsPure3;
exports.default = annotateAsPure2;
var _t = require("@babel/types");

@@ -122,3 +122,3 @@ var {

}) => !!leadingComments && leadingComments.some((comment) => /[@#]__PURE__/.test(comment.value));
function annotateAsPure3(pathOrNode) {
function annotateAsPure2(pathOrNode) {
const node = pathOrNode["node"] || pathOrNode;

@@ -140,384 +140,529 @@ if (isPureAnnotated(node)) {

var import_helper_plugin_utils = __toESM(require_lib());
var t4 = __toESM(require("@babel/types"));
// src/functional.transform.ts
// src/transforms/component.transform.ts
var import_helper_annotate_as_pure = __toESM(require_lib2());
var t = __toESM(require("@babel/types"));
function functional_transform_default(options) {
const { enableGetStateFunction = true, getStateWithDolarSuffix = true } = options;
const visitor2 = {
CallExpression(path, state) {
var _a, _b;
if (enableGetStateFunction && path.get("callee").isIdentifier({ name: "getState" })) {
const param = path.node.arguments[0];
let object = null;
let prop = null;
if (t.isIdentifier(param)) {
const scopeNode = path.scope.getBindingIdentifier(param.name);
if (state.states.includes(scopeNode)) {
object = t.identifier("_$");
prop = param.name;
}
if (state.props.includes(scopeNode)) {
object = state.propsParam;
prop = param.name;
}
} else if (t.isMemberExpression(param) || t.isOptionalMemberExpression(param)) {
const member = param;
if (t.isIdentifier(member.object)) {
const scopeNode = path.scope.getBindingIdentifier(member.object.name);
if (state.propsParam === scopeNode) {
object = state.propsParam;
prop = (_b = (_a = member.property) == null ? void 0 : _a.name) != null ? _b : "0";
}
}
// src/shared/utils.ts
function getOptions(path) {
return path.hub.file.metadata.config;
}
// src/transforms/component.transform.ts
function transformComponent(path) {
var _a, _b, _c;
const { stateProxy } = path.state;
const states = [];
const body = path.get("body");
let returnValue = null;
let funcName;
if (t.isCallExpression(path.parent) && t.isIdentifier(path.parent.callee, { name: "styled" })) {
funcName = "Styled";
} else if (t.isVariableDeclarator(path.parent)) {
funcName = t.isIdentifier(path.parent.id) ? path.parent.id.name : "";
} else {
funcName = t.isFunctionDeclaration(path.node) ? (_b = (_a = path.node.id) == null ? void 0 : _a.name) != null ? _b : "" : "";
}
if (!funcName[0] || funcName[0] !== funcName[0].toUpperCase() || !body.isBlockStatement()) {
return;
}
for (const node of body.node.body) {
if (t.isReturnStatement(node)) {
returnValue = (_c = node.argument) != null ? _c : null;
}
}
if (t.isJSXElement(returnValue) || t.isJSXFragment(returnValue)) {
const param = path.node.params[0];
const props = [];
let propsParam = t.identifier("_props");
if (t.isIdentifier(param)) {
propsParam = param;
}
if (t.isObjectPattern(param)) {
for (const prop of param.properties) {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.value)) {
props.push(prop.value);
}
if (object && prop) {
path.skip();
path.node.arguments = [object, t.stringLiteral(prop)];
if (t.isRestElement(prop) && t.isIdentifier(prop.argument)) {
propsParam = prop.argument;
}
}
},
Identifier(path, state) {
const updateNode = (node, isDolar) => {
const scopeNode = path.scope.getBindingIdentifier(node.name);
if (scopeNode === node || path.parentPath.isMemberExpression({ property: node })) {
return false;
}
const getObject = (obj) => {
return isDolar ? t.memberExpression(obj, t.identifier("$")) : obj;
};
}
path.node.params[0] = propsParam;
body.traverse(visitor, { propsParam, props, states });
if (states.length > 0) {
const callExp = t.callExpression(stateProxy, []);
const declarator = t.variableDeclarator(t.identifier("_$"), callExp);
const declaration = t.variableDeclaration("const", [declarator]);
body.unshiftContainer("body", declaration);
(0, import_helper_annotate_as_pure.default)(callExp);
}
}
}
var visitor = {
CallExpression(path, state) {
var _a, _b;
const { enableGetStateFunction } = getOptions(path);
if (enableGetStateFunction && path.get("callee").isIdentifier({ name: "getState" })) {
const param = path.node.arguments[0];
let object = null;
let prop = null;
if (t.isIdentifier(param)) {
const scopeNode = path.scope.getBindingIdentifier(param.name);
if (state.states.includes(scopeNode)) {
path.skip();
path.replaceWith(t.memberExpression(getObject(t.identifier("_$")), node));
return true;
object = t.identifier("_$");
prop = param.name;
}
if (state.props.includes(scopeNode)) {
path.skip();
path.replaceWith(t.memberExpression(getObject(t.cloneNode(state.propsParam)), node));
return true;
object = state.propsParam;
prop = param.name;
}
};
if (getStateWithDolarSuffix && /[^$]\$$/.test(path.node.name)) {
const node = t.identifier(path.node.name.replace(/\$$/, ""));
if (updateNode(node, true)) {
return;
}
if (path.parentPath.isMemberExpression({ property: path.node }) || path.parentPath.isOptionalMemberExpression({ property: path.node })) {
const object = path.parentPath.node.object;
if (t.isIdentifier(object)) {
const scopeNode = path.scope.getBindingIdentifier(object.name);
if (state.propsParam === scopeNode) {
path.parentPath.replaceWith(t.memberExpression(t.memberExpression(object, t.identifier("$")), node));
return;
}
} else if (t.isMemberExpression(param) || t.isOptionalMemberExpression(param)) {
const member = param;
if (t.isIdentifier(member.object)) {
const scopeNode = path.scope.getBindingIdentifier(member.object.name);
if (state.propsParam === scopeNode) {
object = state.propsParam;
prop = (_b = (_a = member.property) == null ? void 0 : _a.name) != null ? _b : "0";
}
}
}
updateNode(path.node);
},
JSXExpressionContainer(path, state) {
const expPath = path.get("expression");
if (expPath.isFunction() || expPath.isCallExpression() && expPath.get("callee").isIdentifier({ name: "getState" })) {
path.traverse(visitor2, state);
if (object && prop) {
path.node.arguments = [object, t.stringLiteral(prop)];
path.skip();
return;
}
const hasStates = () => {
const node = path.node;
let hasState = false;
path.traverse({
Function(path2) {
if (path2.parent === node) {
path2.skip();
}
},
Identifier(path2) {
const scopeNode = path2.scope.getBindingIdentifier(path2.node.name);
if (state.states.includes(scopeNode) || state.props.includes(scopeNode) || t.isNodesEquivalent(state.propsParam, path2.node)) {
hasState = true;
path2.stop();
}
}
});
return hasState;
}
},
Identifier(path, state) {
const { getStateWithDolarSuffix } = getOptions(path);
const updateNode = (node, isDolar) => {
const scopeNode = path.scope.getBindingIdentifier(node.name);
if (scopeNode === node || path.parentPath.isMemberExpression({ property: node })) {
return false;
}
const getObject = (obj) => {
return isDolar ? t.memberExpression(obj, t.identifier("$")) : obj;
};
if (expPath.isExpression() && hasStates()) {
expPath.replaceWith(t.arrowFunctionExpression([], expPath.node));
if (state.states.includes(scopeNode)) {
path.skip();
path.replaceWith(t.memberExpression(getObject(t.identifier("_$")), node));
return true;
}
},
VariableDeclaration(path, state) {
if (path.node.kind === "let") {
const nodes = path.node.declarations.reduce((acc, declaration) => {
if (t.isIdentifier(declaration.id)) {
state.states.push(declaration.id);
if (declaration.init) {
const left = t.memberExpression(t.identifier("_$"), declaration.id);
const assignment = t.assignmentExpression("=", left, declaration.init);
acc.push(assignment);
}
}
return acc;
}, []);
path.replaceWithMultiple(nodes);
if (state.props.includes(scopeNode)) {
path.skip();
path.replaceWith(t.memberExpression(getObject(t.cloneNode(state.propsParam)), node));
return true;
}
}
};
return {
Function(path) {
var _a, _b, _c;
let funcName;
let returnValue = null;
if (t.isVariableDeclarator(path.parent)) {
funcName = t.isIdentifier(path.parent.id) ? path.parent.id.name : "";
} else {
funcName = t.isFunctionDeclaration(path.node) ? (_b = (_a = path.node.id) == null ? void 0 : _a.name) != null ? _b : "" : "";
}
if (!funcName[0] || funcName[0] !== funcName[0].toUpperCase()) {
};
if (getStateWithDolarSuffix && /[^$]\$$/.test(path.node.name)) {
const node = t.identifier(path.node.name.replace(/\$$/, ""));
if (updateNode(node, true)) {
return;
}
if (t.isBlockStatement(path.node.body)) {
for (const node of path.node.body.body) {
if (t.isReturnStatement(node)) {
returnValue = (_c = node.argument) != null ? _c : null;
if (path.parentPath.isMemberExpression({ property: path.node }) || path.parentPath.isOptionalMemberExpression({ property: path.node })) {
const object = path.parentPath.node.object;
if (t.isIdentifier(object)) {
const scopeNode = path.scope.getBindingIdentifier(object.name);
if (state.propsParam === scopeNode) {
path.parentPath.replaceWith(t.memberExpression(t.memberExpression(object, t.identifier("$")), node));
return;
}
}
} else {
returnValue = path.node.body;
}
if (t.isJSXElement(returnValue) || t.isJSXFragment(returnValue)) {
const param = path.node.params[0];
const props = [];
let propsParam = t.identifier("_props");
const body = path.get("body");
if (body.isBlockStatement()) {
const callExp = t.callExpression(t.identifier("_$$"), []);
const declaration = t.variableDeclarator(t.identifier("_$"), callExp);
body.unshiftContainer("body", t.variableDeclaration("const", [declaration]));
(0, import_helper_annotate_as_pure.default)(callExp);
}
if (t.isIdentifier(param)) {
propsParam = param;
}
if (t.isObjectPattern(param)) {
for (const prop of param.properties) {
if (t.isObjectProperty(prop) && t.isIdentifier(prop.value)) {
props.push(prop.value);
}
if (t.isRestElement(prop) && t.isIdentifier(prop.argument)) {
propsParam = prop.argument;
}
}
updateNode(path.node);
},
VariableDeclaration(path, state) {
if (path.node.kind === "let") {
const nodes = path.node.declarations.reduce((acc, declaration) => {
if (t.isIdentifier(declaration.id)) {
state.states.push(declaration.id);
if (declaration.init) {
const left = t.memberExpression(t.identifier("_$"), declaration.id);
const assignment = t.assignmentExpression("=", left, declaration.init);
acc.push(assignment);
}
}
path.skip();
path.node.params[0] = propsParam;
body.traverse(visitor2, { propsParam, props, states: [] });
}
return acc;
}, []);
path.replaceWithMultiple(nodes);
}
}
};
// src/transforms/jsx.transform.ts
var t2 = __toESM(require("@babel/types"));
// src/shared/tags.ts
var selfClosingTags = [
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"link",
"meta",
"param",
"source",
"track",
"wbr"
];
// src/transforms/jsx.transform.ts
function transformJSX(path) {
const result = {
index: 0,
isLastChild: false,
parentIndex: 0,
props: {},
template: ""
};
transformElement(path, result, true);
path.replaceWith(createVirtualNode(path, result));
}
// src/jsx.transform.ts
var import_helper_annotate_as_pure2 = __toESM(require_lib2());
var t2 = __toESM(require("@babel/types"));
function visitor() {
return {
JSXAttribute(path) {
if (t2.isJSXElement(path.node.value)) {
path.node.value = t2.jsxExpressionContainer(path.node.value);
function createVirtualNode(path, result) {
var _a, _b;
const state = path.state;
let tmpl;
if (path.isJSXElement() && isComponent(getTagName(path.node))) {
tmpl = t2.identifier(getTagName(path.node));
} else {
tmpl = path.scope.generateUidIdentifier("_tmpl");
const template = t2.callExpression(state.template, [
t2.stringLiteral(result.template)
]);
const declarator = t2.variableDeclarator(tmpl, template);
state.tmplDeclaration.declarations.push(declarator);
}
const args = [tmpl, createProps(result.props)];
const key = (_b = result.props.key) != null ? _b : (_a = result.props[0]) == null ? void 0 : _a.key;
if (key) {
args.push(key);
}
return t2.callExpression(state.h, args);
}
function createProps(props) {
const result = [];
for (const prop in props) {
let value = props[prop];
if (prop === "key") {
continue;
}
if (Array.isArray(value)) {
value = t2.arrayExpression(value);
}
if (typeof value === "object" && !t2.isNode(value)) {
value = createProps(props[prop]);
}
if (typeof value !== "object") {
if (typeof value === "string") {
value = t2.stringLiteral(value);
}
},
JSXElement: {
exit(path) {
const callExpr = buildJSXElementCall(path);
path.replaceWith(t2.inherits(callExpr, path.node));
if (typeof value === "number") {
value = t2.numericLiteral(value);
}
},
JSXFragment: {
exit(path) {
const callExpr = buildJSXFragmentCall(path);
if (callExpr) {
path.replaceWith(t2.inherits(callExpr, path.node));
if (typeof value === "boolean") {
value = t2.booleanLiteral(value);
}
if (typeof value === null) {
value = t2.nullLiteral();
}
if (typeof value === "undefined") {
value = t2.identifier("undefined");
}
}
result.push(t2.objectProperty(t2.stringLiteral(prop), value));
}
return t2.objectExpression(result);
}
function getAttrProps(path) {
const props = {};
path.get("openingElement").get("attributes").forEach((attribute) => {
if (attribute.isJSXAttribute()) {
const name = getAttrName(attribute.node);
const value = attribute.get("value");
if (!value.node) {
props[name] = true;
} else if (value.isStringLiteral()) {
props[name] = value.node.value;
} else {
if (value.isJSXExpressionContainer()) {
const expression = value.get("expression");
if (expression.isStringLiteral()) {
props[name] = expression.node.value;
} else if (expression.isNumericLiteral()) {
props[name] = expression.node.value;
} else if (expression.isJSXElement() || expression.isJSXFragment()) {
transformJSX(expression);
props[name] = expression.node;
} else if (expression.isExpression()) {
if (/^key|ref|on:.+|bind.*$/.test(name)) {
props[name] = expression.node;
} else {
props[name] = t2.arrowFunctionExpression([], expression.node);
}
}
} else if (value.isJSXElement() || value.isJSXFragment()) {
transformJSX(value);
props[name] = value.node;
}
}
} else {
throw new Error("Unsupported attribute type");
}
};
});
return props;
}
function accumulateAttribute(array, attribute) {
var _a;
if (t2.isJSXSpreadAttribute(attribute.node)) {
const arg = attribute.node.argument;
if (t2.isObjectExpression(arg)) {
array.push(...arg.properties);
function transformElement(path, result, isRoot) {
if (path.isJSXElement()) {
const tagName = getTagName(path.node);
const tagIsComponent = isComponent(tagName);
const isSelfClosing = !tagIsComponent && selfClosingTags.includes(tagName);
const props = getAttrProps(path);
if (tagIsComponent) {
if (isRoot) {
result.props = props;
const children = getChildren(path);
if (children.length) {
const childrenGetter = t2.arrowFunctionExpression([], children.length === 1 ? children[0] : t2.arrayExpression(children));
result.props.children = childrenGetter;
}
} else {
transformJSX(path);
replaceChild(path.node, result);
}
} else {
array.push(t2.spreadElement(arg));
result.template += `<${tagName}`;
if (tagName === "slot") {
result.props[result.index] = props;
} else {
handleAttributes(props, result);
}
result.template += isSelfClosing ? "/>" : ">";
if (!isSelfClosing) {
transformChildren(path, result);
result.template += `</${tagName}>`;
}
}
return array;
}
const value = convertAttributeValue(attribute.node.name.name !== "key" ? attribute.node.value || t2.booleanLiteral(true) : attribute.node.value);
if (attribute.node.name.name === "key" && value === null) {
throw attribute.buildCodeFrameError('Please provide an explicit key value. Using "key" as a shorthand for "key={true}" is not allowed.');
}
if (t2.isStringLiteral(value) && !t2.isJSXExpressionContainer(attribute.node.value)) {
value.value = value.value.replace(/\n\s+/g, " ");
(_a = value.extra) == null ? true : delete _a.raw;
}
if (t2.isJSXNamespacedName(attribute.node.name)) {
attribute.node.name = t2.stringLiteral(attribute.node.name.namespace.name + ":" + attribute.node.name.name.name);
} else if (t2.isValidIdentifier(attribute.node.name.name, false)) {
attribute.node.name.type = "Identifier";
} else {
attribute.node.name = t2.stringLiteral(attribute.node.name.name);
result.index--;
transformChildren(path, result);
}
array.push(t2.inherits(t2.objectProperty(attribute.node.name, value), attribute.node));
return array;
}
function buildChildrenProperty(children) {
let childrenNode;
if (children.length === 1) {
childrenNode = children[0];
} else if (children.length > 1) {
childrenNode = t2.arrayExpression(children);
} else {
return void 0;
}
return t2.objectProperty(t2.identifier("children"), childrenNode);
function getChildren(path) {
return path.get("children").filter(isValidChild).map((child) => {
if (child.isJSXElement() || child.isJSXFragment()) {
transformJSX(child);
} else if (child.isJSXExpressionContainer()) {
child.replaceWith(child.get("expression"));
} else if (child.isJSXText()) {
child.replaceWith(t2.stringLiteral(child.node.value));
} else {
throw new Error("Unsupported JSX child");
}
return child.node;
});
}
function buildJSXElementCall(path) {
const openingPath = path.get("openingElement");
const args = [getTag(openingPath)];
const attribsArray = [];
const extracted = /* @__PURE__ */ Object.create(null);
for (const attr of openingPath.get("attributes")) {
if (attr.isJSXAttribute() && t2.isJSXIdentifier(attr.node.name)) {
const { name } = attr.node.name;
switch (name) {
case "__source":
case "__self":
if (extracted[name])
throw sourceSelfError(path, name);
case "key": {
const keyValue = convertAttributeValue(attr.node.value);
if (keyValue === null) {
throw attr.buildCodeFrameError('Please provide an explicit key value. Using "key" as a shorthand for "key={true}" is not allowed.');
}
extracted[name] = keyValue;
break;
}
default:
attribsArray.push(attr);
function handleAttributes(props, result) {
let klass = "";
let style = "";
for (const prop in props) {
const value = props[prop];
if (prop === "slot") {
continue;
}
if (prop === "class" && typeof value === "string") {
klass += ` ${value}`;
delete props[prop];
continue;
}
if (/^class:/.test(prop)) {
if (value === true) {
const name = prop.replace(/^class:/, "");
klass += ` ${name}`;
delete props[prop];
continue;
}
} else {
attribsArray.push(attr);
if (value === false) {
delete props[prop];
continue;
}
}
if (prop === "style" && typeof value === "string") {
style += `${value}${value.at(-1) === ";" ? "" : ";"}`;
delete props[prop];
continue;
}
if (/^style:/.test(prop)) {
if (typeof value === "string" || typeof value === "number") {
const name = prop.replace(/^style:/, "");
style += `${name}:${value};`;
delete props[prop];
continue;
}
}
if (value === true) {
result.template += ` ${prop}`;
delete props[prop];
}
if (value === false) {
delete props[prop];
}
if (typeof value === "string" || typeof value === "number") {
result.template += ` ${prop}="${value}"`;
delete props[prop];
}
}
const children = t2.react.buildChildren(path.node);
let attribs;
if (attribsArray.length || children.length) {
attribs = buildJSXOpeningElementAttributes(attribsArray, children);
} else {
attribs = t2.objectExpression([]);
if (Object.keys(props).length > 0) {
result.props[result.index] = props;
}
args.push(attribs);
if (extracted.key !== void 0) {
args.push(extracted.key);
klass = klass.trim();
style = style.trim();
if (klass) {
result.template += ` class="${klass}"`;
}
return call("_jsx", args);
if (style) {
result.template += ` style="${style}"`;
}
}
function buildJSXFragmentCall(path) {
const args = [t2.nullLiteral()];
const children = t2.react.buildChildren(path.node);
args.push(t2.objectExpression(children.length > 0 ? [
buildChildrenProperty(children)
].filter((x) => x) : []));
return call("_jsx", args);
function transformChildren(path, result) {
const parentIndex = result.index;
path.get("children").filter(isValidChild).forEach((child, i, arr) => {
result.parentIndex = parentIndex;
result.isLastChild = i === arr.length - 1;
transformChild(child, result);
});
}
function buildJSXOpeningElementAttributes(attribs, children) {
const props = attribs.reduce(accumulateAttribute, []);
if ((children == null ? void 0 : children.length) > 0) {
const childrenProp = buildChildrenProperty(children);
if (childrenProp) {
props.push(childrenProp);
function transformChild(child, result) {
result.index++;
if (child.isJSXElement() || child.isJSXFragment()) {
transformElement(child, result);
} else if (child.isJSXExpressionContainer()) {
const expression = child.get("expression");
if (expression.isStringLiteral() || expression.isNumericLiteral()) {
result.template += expression.node.value;
} else if (expression.isExpression()) {
replaceChild(expression.node, result);
} else {
throw new Error("Unsupported JSX child");
}
} else if (child.isJSXText()) {
result.template += child.node.value;
} else {
throw new Error("Unsupported JSX child");
}
return t2.objectExpression(props);
}
function call(name, args) {
const node = t2.callExpression(t2.identifier(name), args);
(0, import_helper_annotate_as_pure2.default)(node);
return node;
}
function convertAttributeValue(node) {
if (t2.isJSXExpressionContainer(node)) {
return node.expression;
function replaceChild(node, result) {
var _a, _b, _c, _d, _e;
if (result.isLastChild) {
result.index--;
} else {
return node;
result.template += "<!>";
}
(_c = (_a = result.props)[_b = result.parentIndex]) != null ? _c : _a[_b] = {};
(_e = (_d = result.props[result.parentIndex]).children) != null ? _e : _d.children = [];
result.props[result.parentIndex].children.push(t2.arrayExpression([
t2.arrowFunctionExpression([], node),
result.isLastChild ? t2.nullLiteral() : t2.identifier(String(result.index))
]));
}
function convertJSXIdentifier(node, parent) {
if (t2.isJSXIdentifier(node)) {
if (node.name === "this" && t2.isReferenced(node, parent)) {
return t2.thisExpression();
} else if (t2.isValidIdentifier(node.name, false)) {
node.type = "Identifier";
} else {
return t2.stringLiteral(node.name);
}
} else if (t2.isJSXMemberExpression(node)) {
return t2.memberExpression(convertJSXIdentifier(node.object, node), convertJSXIdentifier(node.property, node));
} else if (t2.isJSXNamespacedName(node)) {
return t2.stringLiteral(`${node.namespace.name}:${node.name.name}`);
function getAttrName(attribute) {
if (t2.isJSXIdentifier(attribute.name)) {
return attribute.name.name;
}
return node;
if (t2.isJSXNamespacedName(attribute.name)) {
return `${attribute.name.namespace.name}:${attribute.name.name.name}`;
}
throw new Error("Unsupported attribute type");
}
function getTag(openingPath) {
const tagExpr = convertJSXIdentifier(openingPath.node.name, openingPath.node);
let tagName;
if (t2.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t2.isLiteral(tagExpr)) {
tagName = tagExpr.value;
function getTagName(node) {
const jsxName = node.openingElement.name;
return jsxElementNameToString(jsxName);
}
function isComponent(tagName) {
return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^a-zA-Z]/.test(tagName[0]);
}
function isValidChild(path) {
const regex = /^\s*$/;
if (path.isStringLiteral() || path.isJSXText()) {
return !regex.test(path.node.value);
}
if (t2.react.isCompatTag(tagName)) {
return t2.stringLiteral(tagName);
} else {
return tagExpr;
return true;
}
function jsxElementNameToString(node) {
if (t2.isJSXMemberExpression(node)) {
return `${jsxElementNameToString(node.object)}.${node.property.name}`;
}
if (t2.isJSXIdentifier(node) || t2.isIdentifier(node)) {
return node.name;
}
return `${node.namespace.name}:${node.name.name}`;
}
function sourceSelfError(path, name) {
return path.buildCodeFrameError(`Duplicate ${name} prop found.`);
}
var jsx_transform_default = visitor;
// src/styled.transform.ts
// src/transforms/program.transform.ts
var t3 = __toESM(require("@babel/types"));
var import_autoprefixer = __toESM(require("autoprefixer"));
var import_postcss = __toESM(require("postcss"));
var import_postcss_nested = __toESM(require("postcss-nested"));
var import_postcss_prefix_selector = __toESM(require("postcss-prefix-selector"));
function styled_transform_default() {
function transformProgram(options) {
return {
TaggedTemplateExpression(path) {
const tagPath = path.get("tag");
const isStyledComponent = tagPath.isCallExpression() && tagPath.get("callee").isIdentifier({ name: "styled" });
if (isStyledComponent) {
const css = path.get("quasi").get("quasis").map((quasi) => {
var _a;
return (_a = quasi.node.value.cooked) != null ? _a : quasi.node.value.raw;
}).join(`/*$$*/`);
const styleId = generateStyleId();
const processedQuasis = processCss(css, styleId).split(`/*$$*/`).map((str) => t3.templateElement({ raw: str, cooked: str }));
path.node.quasi.quasis = [
t3.templateElement({ raw: "", cooked: "" }),
...processedQuasis
];
path.node.quasi.expressions = [
t3.stringLiteral(styleId),
...path.node.quasi.expressions
];
path.skip();
enter(path) {
path.state = {
h: path.scope.generateUidIdentifier("h"),
stateProxy: path.scope.generateUidIdentifier("$$"),
tmplDeclaration: t3.variableDeclaration("const", []),
template: path.scope.generateUidIdentifier("template")
};
path.hub.file.metadata.config = options;
},
exit(path) {
const state = path.state;
const imports = {};
if (state.tmplDeclaration.declarations.length > 0) {
const index = path.node.body.reduce((index2, node, i) => t3.isImportDeclaration(node) || t3.isExportDeclaration(node) ? i : index2, 0);
path.node.body.splice(index + 1, 0, state.tmplDeclaration);
imports.template = state.template.name;
}
if (path.scope.hasBinding(state.h.name)) {
imports.h = state.h.name;
}
if (path.scope.hasBinding(state.stateProxy.name)) {
imports.$$ = state.stateProxy.name;
}
if (Object.keys(imports).length > 0) {
path.node.body.unshift(createImport(imports, "estrela/internal"));
}
}
};
}
function createImport(props, from) {
const imports = Object.entries(props).map(([prop, alias]) => {
const local = t3.identifier(alias);
const imported = t3.identifier(prop);
return t3.importSpecifier(local, imported);
});
const importSource = t3.stringLiteral(from);
return t3.importDeclaration(imports, importSource);
}
// src/transforms/styles.transform.ts
var t4 = __toESM(require("@babel/types"));
var import_autoprefixer = __toESM(require("autoprefixer"));
var import_postcss = __toESM(require("postcss"));
var import_postcss_nested = __toESM(require("postcss-nested"));
var import_postcss_prefix_selector = __toESM(require("postcss-prefix-selector"));
function transformStyles(path) {
const tag = path.get("tag");
const isStyledComponent = tag.isCallExpression() && tag.get("callee").isIdentifier({ name: "styled" });
if (isStyledComponent) {
const idArg = tag.get("arguments")[1];
const styleId = (idArg == null ? void 0 : idArg.isStringLiteral()) ? idArg.node.value : generateStyleId();
tag.node.arguments[1] = t4.stringLiteral(styleId);
const css = path.get("quasi").get("quasis").map((quasi) => {
var _a;
return (_a = quasi.node.value.cooked) != null ? _a : quasi.node.value.raw;
}).join(`/*$$*/`);
path.node.quasi.quasis = processCss(css, styleId).split(`/*$$*/`).map((str) => t4.templateElement({ raw: str, cooked: str }));
}
}
function generateStyleId() {

@@ -538,3 +683,7 @@ return Math.random().toString(36).slice(2, 7);

var src_default = (0, import_helper_plugin_utils.declare)((api, options) => {
const { autoDeclareStates = true } = options;
const {
autoDeclareStates = true,
enableGetStateFunction = true,
getStateWithDolarSuffix = true
} = options != null ? options : {};
return {

@@ -546,27 +695,15 @@ name: "babel-plugin-estrela",

visitor: {
Program(path) {
const imports = createImport({
h: "_jsx",
$$: "_$$"
}, "estrela/internal");
path.unshiftContainer("body", imports);
if (autoDeclareStates) {
path.traverse(functional_transform_default(options));
}
path.traverse(jsx_transform_default());
path.traverse(styled_transform_default());
}
Program: transformProgram({
autoDeclareStates,
enableGetStateFunction,
getStateWithDolarSuffix
}),
Function: transformComponent,
JSXElement: transformJSX,
JSXFragment: transformJSX,
TaggedTemplateExpression: transformStyles
}
};
});
function createImport(props, from) {
const imports = Object.entries(props).map(([prop, alias]) => {
const local = t4.identifier(alias);
const imported = t4.identifier(prop);
return t4.importSpecifier(local, imported);
});
const importSource = t4.stringLiteral(from);
return t4.importDeclaration(imports, importSource);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {});
{
"name": "babel-plugin-estrela",
"description": "A babel plugin to process estrela jsx/tsx files",
"description": "A babel plugin to preprocess estrela jsx/tsx files",
"author": "Eduardo Rosostolato",
"version": "0.3.1",
"version": "0.10.0",
"license": "MIT",

@@ -7,0 +7,0 @@ "main": "dist/index.js",

@@ -22,22 +22,32 @@ # babel-plugin-estrela

onDestroy(() => clearInterval(interval));
// return JSX element.
return <div>Count is { count * 2 }</div>
}
return <div>Count is {count * 2}</div>;
};
```
It will convert the code above to:
It will transpile the code above to:
```js
import { h as _jsx, $$ as _$$ } from 'estrela/internal';
import { state, onDestroy } from 'estrela';
import { template as _template, h as _h, $$ as _$$ } from "estrela/internal";
import { render } from "estrela";
import { onDestroy } from "estrela";
const App = () => {
const _tmpl = _template("<div>Count is </div>");
const App = _props => {
const _$ = /*#__PURE__*/_$$();
_$.count = 0;
_$.count = 0
_$.$.count.subscribe(console.log);
setInterval(() => _$.count++, 1000);
const interval = setInterval(() => _$.count++, 1e3);
onDestroy(() => clearInterval(interval));
return /*#__PURE__*/h('div', null, 'Count is ', [() => _$.count * 2]);
}
return _h(_tmpl, {
"0": {
"children": [[() => _$.count * 2, null]]
}
});
};
```

@@ -44,0 +54,0 @@

import { declare } from '@babel/helper-plugin-utils';
import * as t from '@babel/types';
import functionalTransform from './functional.transform';
import jsxTransform from './jsx.transform';
import { Options } from './options';
import styledTransform from './styled.transform';
import { transformComponent } from './transforms/component.transform';
import { transformJSX } from './transforms/jsx.transform';
import { transformProgram } from './transforms/program.transform';
import { transformStyles } from './transforms/styles.transform';
import { Options } from './types';
export * from './types';
export type { Options } from './options';
export default declare((api, options: Options) => {
const { autoDeclareStates = true } = options;
const {
autoDeclareStates = true,
enableGetStateFunction = true,
getStateWithDolarSuffix = true,
} = options ?? {};
return {

@@ -19,29 +21,13 @@ name: 'babel-plugin-estrela',

visitor: {
Program(path) {
const imports = createImport(
{
h: '_jsx',
$$: '_$$',
},
'estrela/internal'
);
path.unshiftContainer('body', imports);
if (autoDeclareStates) {
path.traverse(functionalTransform(options));
}
path.traverse(jsxTransform());
path.traverse(styledTransform());
},
Program: transformProgram({
autoDeclareStates,
enableGetStateFunction,
getStateWithDolarSuffix,
}),
Function: transformComponent,
JSXElement: transformJSX,
JSXFragment: transformJSX,
TaggedTemplateExpression: transformStyles,
},
};
});
function createImport(props: Record<string, string>, from: string) {
const imports = Object.entries(props).map(([prop, alias]) => {
const local = t.identifier(alias);
const imported = t.identifier(prop);
return t.importSpecifier(local, imported);
});
const importSource = t.stringLiteral(from);
return t.importDeclaration(imports, importSource);
}

@@ -13,3 +13,6 @@ {

"src"
]
],
"exclude": [
"node_modules"
],
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc