🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

babel-plugin-mobx-observer-on-every-react-component

Package Overview
Dependencies
Maintainers
0
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-mobx-observer-on-every-react-component - npm Package Compare versions

Comparing version

to
0.1.12

license

92

dist/index.cjs.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const helper_plugin_utils_1 = require("@babel/helper-plugin-utils");
const t = __importStar(require("@babel/types"));
exports.default = (0, helper_plugin_utils_1.declare)((api, options) => {

@@ -21,5 +45,4 @@ var _a;

const specifiers = path.node.specifiers;
observerImported = specifiers.some(spec =>
// @ts-expect-error
t.isImportSpecifier(spec) && spec.imported.name === 'observer');
observerImported = specifiers.some(spec => t.isImportSpecifier(spec) &&
(spec.imported.type === 'Identifier' && spec.imported.name === 'observer'));
}

@@ -35,4 +58,3 @@ },

const existingImport = path.node.body.find(node => t.isImportDeclaration(node) && node.source.value === 'mobx-react');
if (existingImport) {
// @ts-expect-error
if (existingImport && t.isImportDeclaration(existingImport)) {
existingImport.specifiers.push(t.importSpecifier(t.identifier('observer'), t.identifier('observer')));

@@ -46,5 +68,3 @@ }

if (!hasReactComponent) {
debug(
// @ts-expect-error
`no react components in this file ${path.hub.file.opts.filename}`, debugEnabled);
debug(`no react components in this file ${state.filename}`, debugEnabled);
}

@@ -56,4 +76,3 @@ },

}
// @ts-expect-error
debug(`arrow function expression ${path.hub.file.opts.filename}`, debugEnabled);
debug(`arrow function expression ${state.filename}`, debugEnabled);
if (isReactComponent(path)) {

@@ -181,25 +200,23 @@ debug("is react component", debugEnabled);

function isInNodeModules(state) {
const filename = state.file.opts.filename;
return filename && filename.includes("node_modules");
const filename = state.filename;
return !!(filename && filename.includes("node_modules"));
}
function isWrappedInObserver(path) {
// If this class is on the right hand side of an assignment expression,
// check to see if that assignment expression is a call expression to observer
// which we can know from the parent of the parentPath
if (path.parentPath.node.type === "AssignmentExpression") {
if (path.parentPath.parentPath.node.type === "CallExpression" && path.parentPath.parentPath.node.callee.name === "observer") {
const parent = path.parentPath;
if (parent && t.isAssignmentExpression(parent.node)) {
const grandParent = parent.parentPath;
if (grandParent && t.isCallExpression(grandParent.node) && t.isIdentifier(grandParent.node.callee) && grandParent.node.callee.name === 'observer') {
return true;
}
}
return (path.parentPath.node.type === "CallExpression" &&
path.parentPath.node.callee.name === "observer");
return (t.isCallExpression(parent === null || parent === void 0 ? void 0 : parent.node) &&
t.isIdentifier(parent.node.callee) &&
parent.node.callee.name === 'observer');
}
function isDecoratedWithObserver(path) {
return (path.node.decorators &&
return !!(path.node.decorators &&
path.node.decorators.length > 0 &&
// @ts-expect-errork
path.node.decorators.some(decorator => decorator.expression.type === 'Identifier' &&
path.node.decorators.some((decorator) => decorator.expression.type === 'Identifier' &&
decorator.expression.name === 'observer'));
}
// @ts-expect-error
function wrapClassDeclarationInObserver(path, t) {

@@ -216,3 +233,2 @@ const classExpression = t.classExpression(path.node.id, path.node.superClass, path.node.body, path.node.decorators);

}
// @ts-expect-error
function wrapClassExpressionInObserver(path, t) {

@@ -222,10 +238,5 @@ const classExpression = t.classExpression(path.node.id, path.node.superClass, path.node.body, path.node.decorators);

const observerFunction = t.callExpression(t.identifier("observer"), [classExpression]);
// Create a variable declaration with the observer-wrapped class
const variableDeclaration = t.variableDeclaration("const", [
t.variableDeclarator(path.node.id, observerFunction)
]);
// Replace the ClassDeclaration with the observer() wrapped version
path.replaceWith(observerFunction);
}
// @ts-expect-error
function isReactComponent(path) {

@@ -249,15 +260,15 @@ if (path.node.type === "ArrowFunctionExpression") {

}
// @ts-expect-error
function doesReturnJSX(body) {
if (!body)
return false;
if (body.type === "JSXElement" || body.type === "JSXFragment") {
if (t.isJSXElement(body) || t.isJSXFragment(body)) {
return true;
}
var block = body.body;
if (block && block.length) {
var lastBlock = block.slice(0).pop();
if (lastBlock.type === "ReturnStatement") {
return (lastBlock.argument !== null &&
(lastBlock.argument.type === "JSXElement" || lastBlock.argument.type === "JSXFragment"));
if (t.isBlockStatement(body)) {
const statements = body.body;
if (statements.length > 0) {
const lastStatement = statements[statements.length - 1];
if (t.isReturnStatement(lastStatement) && lastStatement.argument) {
return t.isJSXElement(lastStatement.argument) || t.isJSXFragment(lastStatement.argument);
}
}

@@ -267,3 +278,2 @@ }

}
// @ts-expect-error
function classHasRenderMethod(path) {

@@ -273,5 +283,5 @@ if (!path.node.body) {

}
var members = path.node.body.body;
for (var i = 0; i < members.length; i++) {
if (members[i].type === "ClassMethod" && members[i].key.name === "render") {
const members = path.node.body.body;
for (const member of members) {
if (t.isClassMethod(member) && t.isIdentifier(member.key) && member.key.name === "render") {
return true;

@@ -278,0 +288,0 @@ }

import { declare } from "@babel/helper-plugin-utils";
import * as t from '@babel/types';
export default declare((api, options) => {

@@ -19,5 +20,4 @@ var _a;

const specifiers = path.node.specifiers;
observerImported = specifiers.some(spec =>
// @ts-expect-error
t.isImportSpecifier(spec) && spec.imported.name === 'observer');
observerImported = specifiers.some(spec => t.isImportSpecifier(spec) &&
(spec.imported.type === 'Identifier' && spec.imported.name === 'observer'));
}

@@ -33,4 +33,3 @@ },

const existingImport = path.node.body.find(node => t.isImportDeclaration(node) && node.source.value === 'mobx-react');
if (existingImport) {
// @ts-expect-error
if (existingImport && t.isImportDeclaration(existingImport)) {
existingImport.specifiers.push(t.importSpecifier(t.identifier('observer'), t.identifier('observer')));

@@ -44,5 +43,3 @@ }

if (!hasReactComponent) {
debug(
// @ts-expect-error
`no react components in this file ${path.hub.file.opts.filename}`, debugEnabled);
debug(`no react components in this file ${state.filename}`, debugEnabled);
}

@@ -54,4 +51,3 @@ },

}
// @ts-expect-error
debug(`arrow function expression ${path.hub.file.opts.filename}`, debugEnabled);
debug(`arrow function expression ${state.filename}`, debugEnabled);
if (isReactComponent(path)) {

@@ -179,25 +175,23 @@ debug("is react component", debugEnabled);

function isInNodeModules(state) {
const filename = state.file.opts.filename;
return filename && filename.includes("node_modules");
const filename = state.filename;
return !!(filename && filename.includes("node_modules"));
}
function isWrappedInObserver(path) {
// If this class is on the right hand side of an assignment expression,
// check to see if that assignment expression is a call expression to observer
// which we can know from the parent of the parentPath
if (path.parentPath.node.type === "AssignmentExpression") {
if (path.parentPath.parentPath.node.type === "CallExpression" && path.parentPath.parentPath.node.callee.name === "observer") {
const parent = path.parentPath;
if (parent && t.isAssignmentExpression(parent.node)) {
const grandParent = parent.parentPath;
if (grandParent && t.isCallExpression(grandParent.node) && t.isIdentifier(grandParent.node.callee) && grandParent.node.callee.name === 'observer') {
return true;
}
}
return (path.parentPath.node.type === "CallExpression" &&
path.parentPath.node.callee.name === "observer");
return (t.isCallExpression(parent === null || parent === void 0 ? void 0 : parent.node) &&
t.isIdentifier(parent.node.callee) &&
parent.node.callee.name === 'observer');
}
function isDecoratedWithObserver(path) {
return (path.node.decorators &&
return !!(path.node.decorators &&
path.node.decorators.length > 0 &&
// @ts-expect-errork
path.node.decorators.some(decorator => decorator.expression.type === 'Identifier' &&
path.node.decorators.some((decorator) => decorator.expression.type === 'Identifier' &&
decorator.expression.name === 'observer'));
}
// @ts-expect-error
function wrapClassDeclarationInObserver(path, t) {

@@ -214,3 +208,2 @@ const classExpression = t.classExpression(path.node.id, path.node.superClass, path.node.body, path.node.decorators);

}
// @ts-expect-error
function wrapClassExpressionInObserver(path, t) {

@@ -220,10 +213,5 @@ const classExpression = t.classExpression(path.node.id, path.node.superClass, path.node.body, path.node.decorators);

const observerFunction = t.callExpression(t.identifier("observer"), [classExpression]);
// Create a variable declaration with the observer-wrapped class
const variableDeclaration = t.variableDeclaration("const", [
t.variableDeclarator(path.node.id, observerFunction)
]);
// Replace the ClassDeclaration with the observer() wrapped version
path.replaceWith(observerFunction);
}
// @ts-expect-error
function isReactComponent(path) {

@@ -247,15 +235,15 @@ if (path.node.type === "ArrowFunctionExpression") {

}
// @ts-expect-error
function doesReturnJSX(body) {
if (!body)
return false;
if (body.type === "JSXElement" || body.type === "JSXFragment") {
if (t.isJSXElement(body) || t.isJSXFragment(body)) {
return true;
}
var block = body.body;
if (block && block.length) {
var lastBlock = block.slice(0).pop();
if (lastBlock.type === "ReturnStatement") {
return (lastBlock.argument !== null &&
(lastBlock.argument.type === "JSXElement" || lastBlock.argument.type === "JSXFragment"));
if (t.isBlockStatement(body)) {
const statements = body.body;
if (statements.length > 0) {
const lastStatement = statements[statements.length - 1];
if (t.isReturnStatement(lastStatement) && lastStatement.argument) {
return t.isJSXElement(lastStatement.argument) || t.isJSXFragment(lastStatement.argument);
}
}

@@ -265,3 +253,2 @@ }

}
// @ts-expect-error
function classHasRenderMethod(path) {

@@ -271,5 +258,5 @@ if (!path.node.body) {

}
var members = path.node.body.body;
for (var i = 0; i < members.length; i++) {
if (members[i].type === "ClassMethod" && members[i].key.name === "render") {
const members = path.node.body.body;
for (const member of members) {
if (t.isClassMethod(member) && t.isIdentifier(member.key) && member.key.name === "render") {
return true;

@@ -276,0 +263,0 @@ }

{
"name": "babel-plugin-mobx-observer-on-every-react-component",
"version": "0.1.11",
"version": "0.1.12",
"description": "Wrap literally every React component in an MobX observer higher order component.",
"keywords": [
"babel-plugin",
"mobx"
"mobx",
"mobx-react",
"react",
"observer",
"babel"
],

@@ -44,3 +48,3 @@ "homepage": "https://github.com/coolsoftwaretyler/babel-plugin-mobx-observer-on-every-react-component",

"clean": "rimraf dist",
"build": "npm run clean && npm run build:cjs && npm run build:esm",
"build": "bun run clean && bun run build:cjs && bun run build:esm",
"build:cjs": "tsc --module commonjs --outDir dist && mv dist/index.js dist/index.cjs.js",

@@ -47,0 +51,0 @@ "build:esm": "tsc --module es2015 --outDir dist && mv dist/index.js dist/index.esm.js"

import { declare } from "@babel/helper-plugin-utils";
import { Decorator } from '@babel/types';
import { NodePath } from '@babel/core';
import * as t from '@babel/types';
import { PluginPass } from '@babel/core';

@@ -7,6 +11,8 @@ interface PluginOptions {

type BabelTypes = typeof import('@babel/types');
export default declare((api, options?: PluginOptions ) => {
const debugEnabled = options?.debugEnabled ?? false;
const t = api.types;
return {

@@ -28,4 +34,4 @@ name: "babel-plugin-mobx-observer-on-every-react-component",

observerImported = specifiers.some(spec =>
// @ts-expect-error
t.isImportSpecifier(spec) && spec.imported.name === 'observer'
t.isImportSpecifier(spec) &&
(spec.imported.type === 'Identifier' && spec.imported.name === 'observer')
);

@@ -37,3 +43,3 @@ }

) {
if (isReactComponent(path)) {
if (isReactComponent(path as NodePath<t.ArrowFunctionExpression | t.FunctionDeclaration | t.FunctionExpression | t.ClassDeclaration | t.ClassExpression>)) {
hasReactComponent = true;

@@ -48,5 +54,3 @@ }

);
if (existingImport) {
// @ts-expect-error
if (existingImport && t.isImportDeclaration(existingImport)) {
existingImport.specifiers.push(

@@ -66,4 +70,3 @@ t.importSpecifier(t.identifier('observer'), t.identifier('observer'))

debug(
// @ts-expect-error
`no react components in this file ${path.hub.file.opts.filename}`,
`no react components in this file ${state.filename}`,
debugEnabled

@@ -79,4 +82,3 @@ );

// @ts-expect-error
debug(`arrow function expression ${path.hub.file.opts.filename}`, debugEnabled);
debug(`arrow function expression ${state.filename}`, debugEnabled);

@@ -86,3 +88,3 @@ if (isReactComponent(path)) {

// Check to see if this is already wrapped in observer
if (isWrappedInObserver(path)) {
if (isWrappedInObserver(path as NodePath<t.ArrowFunctionExpression>)) {
debug("already wrapped in observer", debugEnabled);

@@ -116,3 +118,3 @@ return;

// Check to see if this is already wrapped in observer
if (isWrappedInObserver(path)) {
if (isWrappedInObserver(path as NodePath<t.ClassDeclaration>)) {
debug(

@@ -158,3 +160,3 @@ `already wrapped in observer ${path.node.id?.name ?? "Anonymous"}`,

// Check to see if this is already wrapped in observer
if (isWrappedInObserver(path)) {
if (isWrappedInObserver(path as NodePath<t.ClassExpression>)) {
debug(

@@ -280,31 +282,28 @@ `already wrapped in observer ${path.node.id?.name ?? "Anonymous"}`,

function isInNodeModules(state: any) {
const filename = state.file.opts.filename;
return filename && filename.includes("node_modules");
function isInNodeModules(state: PluginPass): boolean {
const filename = state.filename;
return !!(filename && filename.includes("node_modules"))
}
function isWrappedInObserver(path: any) {
// If this class is on the right hand side of an assignment expression,
// check to see if that assignment expression is a call expression to observer
// which we can know from the parent of the parentPath
if (path.parentPath.node.type === "AssignmentExpression") {
if (path.parentPath.parentPath.node.type === "CallExpression" && path.parentPath.parentPath.node.callee.name === "observer") {
return true
function isWrappedInObserver(path: NodePath<t.ArrowFunctionExpression | t.FunctionDeclaration | t.FunctionExpression | t.ClassDeclaration | t.ClassExpression>): boolean {
const parent = path.parentPath;
if (parent && t.isAssignmentExpression(parent.node)) {
const grandParent = parent.parentPath;
if (grandParent && t.isCallExpression(grandParent.node) && t.isIdentifier(grandParent.node.callee) && grandParent.node.callee.name === 'observer') {
return true;
}
}
return (
path.parentPath.node.type === "CallExpression" &&
path.parentPath.node.callee.name === "observer"
t.isCallExpression(parent?.node) &&
t.isIdentifier(parent.node.callee) &&
parent.node.callee.name === 'observer'
);
}
function isDecoratedWithObserver(path: any) {
return (
function isDecoratedWithObserver(path: NodePath<t.ClassDeclaration | t.ClassExpression>): boolean {
return !!(
path.node.decorators &&
path.node.decorators.length > 0 &&
// @ts-expect-errork
path.node.decorators.some(decorator =>
path.node.decorators.some((decorator: Decorator) =>
decorator.expression.type === 'Identifier' &&

@@ -316,4 +315,3 @@ decorator.expression.name === 'observer'

// @ts-expect-error
function wrapClassDeclarationInObserver(path, t) {
function wrapClassDeclarationInObserver(path: NodePath<t.ClassDeclaration>, t: BabelTypes) {
const classExpression = t.classExpression(

@@ -334,3 +332,3 @@ path.node.id,

const variableDeclaration = t.variableDeclaration("const", [
t.variableDeclarator(path.node.id, observerFunction)
t.variableDeclarator(path.node.id as t.Identifier, observerFunction)
]);

@@ -343,4 +341,3 @@

// @ts-expect-error
function wrapClassExpressionInObserver(path, t) {
function wrapClassExpressionInObserver(path: NodePath<t.ClassExpression>, t: BabelTypes) {
const classExpression = t.classExpression(

@@ -359,8 +356,2 @@ path.node.id,

// Create a variable declaration with the observer-wrapped class
const variableDeclaration = t.variableDeclaration("const", [
t.variableDeclarator(path.node.id, observerFunction)
]);
// Replace the ClassDeclaration with the observer() wrapped version

@@ -371,4 +362,3 @@ path.replaceWith(observerFunction);

// @ts-expect-error
function isReactComponent(path ) {
function isReactComponent(path: NodePath<t.ArrowFunctionExpression | t.FunctionDeclaration | t.FunctionExpression | t.ClassDeclaration | t.ClassExpression>): boolean {
if (path.node.type === "ArrowFunctionExpression") {

@@ -384,6 +374,6 @@ return doesReturnJSX(path.node.body);

if (path.node.type === "ClassDeclaration") {
return classHasRenderMethod(path);
return classHasRenderMethod(path as NodePath<t.ClassDeclaration>);
}
if (path.node.type === "ClassExpression") {
return classHasRenderMethod(path);
return classHasRenderMethod(path as NodePath<t.ClassExpression>);
}

@@ -394,18 +384,15 @@

// @ts-expect-error
function doesReturnJSX(body) {
function doesReturnJSX(body: t.BlockStatement | t.Expression): boolean {
if (!body) return false;
if (body.type === "JSXElement" || body.type === "JSXFragment") {
if (t.isJSXElement(body) || t.isJSXFragment(body)) {
return true;
}
var block = body.body;
if (block && block.length) {
var lastBlock = block.slice(0).pop();
if (lastBlock.type === "ReturnStatement") {
return (
lastBlock.argument !== null &&
(lastBlock.argument.type === "JSXElement" || lastBlock.argument.type === "JSXFragment")
);
if (t.isBlockStatement(body)) {
const statements = body.body;
if (statements.length > 0) {
const lastStatement = statements[statements.length - 1];
if (t.isReturnStatement(lastStatement) && lastStatement.argument) {
return t.isJSXElement(lastStatement.argument) || t.isJSXFragment(lastStatement.argument);
}
}

@@ -417,10 +404,9 @@ }

// @ts-expect-error
function classHasRenderMethod(path) {
function classHasRenderMethod(path: NodePath<t.ClassDeclaration | t.ClassExpression>): boolean {
if (!path.node.body) {
return false;
}
var members = path.node.body.body;
for (var i = 0; i < members.length; i++) {
if (members[i].type === "ClassMethod" && members[i].key.name === "render") {
const members = path.node.body.body;
for (const member of members) {
if (t.isClassMethod(member) && t.isIdentifier(member.key) && member.key.name === "render") {
return true;

@@ -433,3 +419,3 @@ }

function debug(message: string, debugEnabled: boolean) {
function debug(message: string, debugEnabled: boolean): void {
if (debugEnabled) {

@@ -436,0 +422,0 @@ console.log(message);