UNPKG

@joenoon/mobx-react-hooks

Version:
56 lines 3.25 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); // @ts-ignore const babel_plugin_macros_1 = require("babel-plugin-macros"); const path_1 = __importDefault(require("path")); function createUseObserver(config) { return babel_plugin_macros_1.createMacro(function useObserverMacro({ references, state: { file: { opts: { filename } } }, babel: { types: t } }) { // transform the importSource to a relative path if its not a library let { importSource } = config; if (path_1.default.isAbsolute(importSource)) { importSource = `./${path_1.default.relative(path_1.default.dirname(filename), importSource)}`; } const { useObserver = [] } = references; useObserver.forEach((referencePath) => { // program is the top scope of the file const program = referencePath.scope.getProgramParent().path; const line = referencePath.getStatementParent(); if (line.key !== 0) { throw new babel_plugin_macros_1.MacroError(`${path_1.default.basename(filename)}:${line.node.loc.start.line}: ` + "useObserver() provided by the macro must be the first line of the FunctionComponent."); } // lineVars is the `{a, b}` in: const {a, b} = useObserver(); const lineVars = line.node.declarations ? line.node.declarations[0].id : null; const lineArgs = referencePath.container.arguments; // get all lines in the scope that follow. these get moved automatically const linesAfter = line.container.splice(line.key + 1, line.container.length - line.key - 1); // return a new function taking lineVars as args, containing linesAfter. // the name `useObserverRenderHook` is not important. line.insertAfter(t.returnStatement(t.callExpression(t.identifier(config.importSpecifier), [ t.functionExpression(t.identifier("useObserverRenderHook"), lineVars ? [lineVars] : [], t.blockStatement(linesAfter), false, false), ...lineArgs ]))); // remove the original line line.remove(); // check to see if we've already added the real import line to this file const foundImport = program.get("body").filter((x) => { if (t.isImportDeclaration(x) && x.node.source.value === importSource) { return (x.node.specifiers.filter((s) => s.local.name === config.importSpecifier).length > 0); } return false; }).length > 0; // if not, add it, i.e.: // import { importSpecifier } from importSource if (!foundImport) { program.unshiftContainer("body", t.importDeclaration([ t.importSpecifier(t.identifier(config.importSpecifier), t.identifier(config.importSpecifier)) ], t.stringLiteral(importSource))); } }); }); } exports.createUseObserver = createUseObserver; //# sourceMappingURL=createUseObserver.js.map