Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

babel-plugin-prototype-prop-define

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-prototype-prop-define - npm Package Compare versions

Comparing version
1.0.1
to
2.0.1
+3
-4
package.json
{
"name": "babel-plugin-prototype-prop-define",
"version": "1.0.1",
"description": "Rewrite assignments on the prototypes to Object.defineProperty calls",
"version": "2.0.1",
"description": "Transform assignments to properties on built-in prototypes to Object.defineProperty calls",
"main": "src/index.js",

@@ -27,3 +27,2 @@ "engines": {

"dependencies": {
"babel-plugin-macros": "^2.2.1",
"require-from-string": "^2.0.2"

@@ -34,3 +33,3 @@ },

"babel-plugin-tester": "^5.0.0",
"kcd-scripts": "^0.39.0"
"kcd-scripts": "^1.6.0"
},

@@ -37,0 +36,0 @@ "eslintConfig": {

+22
-202

@@ -1,219 +0,39 @@

<div align="center">
<h1>babel-plugin-boilerplate :emoji:</h1>
<p>your next babel plugin description</p>
</div>
<hr />
<!-- prettier-ignore-start -->
[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors)
[![PRs Welcome][prs-badge]][prs]
[![Code of Conduct][coc-badge]][coc]
[![Babel Macro](https://img.shields.io/badge/babel--macro-%F0%9F%8E%A3-f5da55.svg?style=flat-square)](https://github.com/kentcdodds/babel-plugin-macros)
<!-- prettier-ignore-end -->
## The problem
The problem your plugin solves
> more resources the user shoudl read
## This solution
What this plugin does
How this plugin works
## Table of Contents
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
- [Installation](#installation)
- [Usage](#usage)
- [first usage style](#first-usage-style)
- [usage style 2](#usage-style-2)
- [Configure with Babel](#configure-with-babel)
- [Via `.babelrc` (Recommended)](#via-babelrc-recommended)
- [Via CLI](#via-cli)
- [Via Node API](#via-node-api)
- [Use with `babel-plugin-macros`](#use-with-babel-plugin-macros)
- [APIs not supported by the macro](#apis-not-supported-by-the-macro)
- [Caveats](#caveats)
- [Examples](#examples)
- [Inspiration](#inspiration)
- [Other Solutions](#other-solutions)
- [Contributors](#contributors)
- [LICENSE](#license)
- [babel-plugin-prototype-prop-define](#babel-plugin-prototype-prop-define)
- [background](#background)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
## Installation
# babel-plugin-prototype-prop-define
This module is distributed via [npm][npm] which is bundled with [node][node] and
should be installed as one of your project's `devDependencies`:
A babel plugin for working around javascript's "override mistake" when dealing with frozen Primordials (built-ins).
```
npm install --save-dev babel-plugin-boilerplate
```
### background
## Usage
If your primordials are frozen, such as in [SES](https://github.com/agoric/ses), assigning keys that are found on the prototype will throw an error.
More notes on usage
```js
Object.freeze(Object.prototype)
### first usage style
**Before**:
```javascript
// before
const x = {}
x.toString = () => 'hello'
// => TypeError: Cannot assign to read only property 'toString' of object '#<Object>'
```
**After** some notes here:
Since this is a common, this plugin is provided to transform code into a safe form using `Object.defineProperty`:
```javascript
// after
```
```js
Object.freeze(Object.prototype)
more notes here!
**Before**:
```javascript
// before
```
**After** more notes here:
```javascript
// after
```
### usage style 2
**Before**:
```javascript
// before
```
**After** more notes here:
```javascript
// after
```
## Configure with Babel
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["BOILERPLATE"]
}
```
### Via CLI
```sh
babel --plugins BOILERPLATE script.js
```
### Via Node API
```javascript
require('babel-core').transform('code', {
plugins: ['BOILERPLATE'],
const x = {}
Object.defineProperty(x, 'toString', {
value: () => 'hello',
writable: true,
enumerable: true,
configurable: true,
})
x.toString()
// => 'hello'
```
## Use with `babel-plugin-macros`
Once you've
[configured `babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros/blob/master/other/docs/user.md)
you can import/require the boilerplate macro at `babel-plugin-boilerplate/macro`. For
example:
```javascript
import yourmacro from 'babel-plugin-boilerplate/macro'
// user yourmacro
↓ ↓ ↓ ↓ ↓ ↓
// output
```
### APIs not supported by the macro
- one
- two
> You could also use [`boilerplate.macro`][boilerplate.macro] if you'd prefer to type
> less 😀
## Caveats
any caveats you like to say
## Examples
- Some examples and links here
## Inspiration
This is based on [babel-plugin-boilerplate](https://github.com/kentcdodds/babel-plugin-boilerplate).
## Other Solutions
I'm not aware of any, if you are please [make a pull request][prs] and add it
here!
## Contributors
Thanks goes to these people ([emoji key][emojis]):
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
| [<img src="https://avatars.githubusercontent.com/u/1500684?v=3" width="100px;"/><br /><sub><b>Kent C. Dodds</b></sub>](https://kentcdodds.com)<br />[💻](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=kentcdodds "Code") [📖](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=kentcdodds "Documentation") [🚇](#infra-kentcdodds "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=kentcdodds "Tests") | [<img src="https://avatars1.githubusercontent.com/u/1958812?v=4" width="100px;"/><br /><sub><b>Michael Rawlings</b></sub>](https://github.com/mlrawlings)<br />[💻](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=mlrawlings "Code") [📖](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=mlrawlings "Documentation") [⚠️](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=mlrawlings "Tests") | [<img src="https://avatars3.githubusercontent.com/u/5230863?v=4" width="100px;"/><br /><sub><b>Jan Willem Henckel</b></sub>](https://jan.cologne)<br />[💻](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=djfarly "Code") [📖](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=djfarly "Documentation") [⚠️](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=djfarly "Tests") | [<img src="https://avatars3.githubusercontent.com/u/1824298?v=4" width="100px;"/><br /><sub><b>Karan Thakkar</b></sub>](https://twitter.com/geekykaran)<br />[📖](https://github.com/sw-yx/babel-plugin-boilerplate/commits?author=karanjthakkar "Documentation") |
| :---: | :---: | :---: | :---: |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors][all-contributors] specification.
Contributions of any kind welcome!
## LICENSE
MIT
<!-- prettier-ignore-start -->
[npm]: https://www.npmjs.com/
[node]: https://nodejs.org
[build-badge]: https://img.shields.io/travis/kentcdodds/babel-plugin-boilerplate.svg?style=flat-square
[build]: https://travis-ci.org/kentcdodds/babel-plugin-boilerplate
[coverage-badge]: https://img.shields.io/codecov/c/github/kentcdodds/babel-plugin-boilerplate.svg?style=flat-square
[coverage]: https://codecov.io/github/kentcdodds/babel-plugin-boilerplate
[version-badge]: https://img.shields.io/npm/v/babel-plugin-boilerplate.svg?style=flat-square
[package]: https://www.npmjs.com/package/babel-plugin-boilerplate
[downloads-badge]: https://img.shields.io/npm/dm/babel-plugin-boilerplate.svg?style=flat-square
[npmtrends]: http://www.npmtrends.com/babel-plugin-boilerplate
[license-badge]: https://img.shields.io/npm/l/babel-plugin-boilerplate.svg?style=flat-square
[license]: https://github.com/kentcdodds/babel-plugin-boilerplate/blob/master/LICENSE
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[prs]: http://makeapullrequest.com
[donate-badge]: https://img.shields.io/badge/$-support-green.svg?style=flat-square
[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
[coc]: https://github.com/kentcdodds/babel-plugin-boilerplate/blob/master/other/CODE_OF_CONDUCT.md
[emojis]: https://github.com/kentcdodds/all-contributors#emoji-key
[all-contributors]: https://github.com/kentcdodds/all-contributors
[glamorous]: https://github.com/paypal/glamorous
[preval]: https://github.com/kentcdodds/babel-plugin-preval
[boilerplate.macro]: https://www.npmjs.com/package/boilerplate.macro
[babel-plugin-macros]: https://github.com/kentcdodds/babel-plugin-macros
<!-- prettier-ignore-end -->

@@ -21,65 +21,39 @@ import path from 'path'

tests: {
// 'does not touch non-boilerplate code': {
// snapshot: false,
// code: 'const x = notboilerplate`module.exports = "nothing"`;',
// },
'basic value': `
function MyClass () {}
MyClass.prototype.toString = () => '[[MyClass]]'
'should ignore': `
const x = {}
x.a = () => true
`,
// 'simple variable assignment':
// 'boilerplate`module.exports = "var x = \'some directive\'"`',
// 'object with arrow function': `
// const y = boilerplate\`
// module.exports = '({booyah: () => "booyah"})'
// \`
'on object': `
const x = {}
x.toString = () => true
`,
'on prototype': `
function MyClass () {}
MyClass.prototype.toString = () => true
`,
'on array': `
const x = []
x.splice = () => true
`,
'on function': `
const x = () => {}
x.bind = () => true
`,
// 'key as string': `
// const x = {}
// x["toString"] = () => true
// `,
// 'must export a string': {
// code: 'const y = boilerplate`module.exports = {}`',
// error: true,
// },
// 'boilerplate comment': `
// // @boilerplate
// const array = ['apple', 'orange', 'pear']
// module.exports = array
// .map(fruit => \`export const \${fruit} = "\${fruit}";\`)
// .join('')
// `,
// 'dynamic value that is wrong': {
// code: `const x = boilerplate\`module.exports = "\${dynamic}"\``,
// error: true,
// },
// 'import comment': 'import /* boilerplate */ "./fixtures/assign-one.js"',
// 'import comment with extra comments after':
// 'import /* boilerplate */ /* this is extra stuff */ "./fixtures/assign-one.js"',
// 'import comment with extra comments before':
// 'import /* this is extra stuff */ /* boilerplate */ "./fixtures/assign-one.js"',
// 'does not touch import comments that are irrelevant': {
// code: 'import /* this is extra stuff */"./fixtures/assign-one.js";',
// snapshot: false,
// },
},
})
// // This is for any of the exta tests. We give these a name.
// pluginTester({
// plugin,
// snapshot: true,
// babelOptions: {filename: __filename},
// tests: {
// 'handles some dynamic values': `
// const three = 3
// const x = boilerplate\`module.exports = "\${three}"\`
// `,
// 'accepts babels parser options for generated code': {
// babelOptions: {
// filename: __filename,
// parserOpts: {plugins: ['flow', 'doExpressions']},
// },
// code: `
// // @boilerplate
// module.exports = "var fNum: number = do { if(true) {100} else {200} };"
// `,
// },
// },
// })

@@ -1,8 +0,56 @@

// const getReplacers = require('./replace')
// const {looksLike} = require('./helpers')
const primordialKeySet = new Set([
...Object.getOwnPropertyNames(Object.prototype),
...Object.getOwnPropertyNames(Array.prototype),
...Object.getOwnPropertyNames(Function.prototype),
...Object.getOwnPropertyNames(Error.prototype),
])
// Set {
// 'constructor',
// '__defineGetter__',
// '__defineSetter__',
// 'hasOwnProperty',
// '__lookupGetter__',
// '__lookupSetter__',
// 'isPrototypeOf',
// 'propertyIsEnumerable',
// 'toString',
// 'valueOf',
// '__proto__',
// 'toLocaleString',
// 'length',
// 'concat',
// 'find',
// 'findIndex',
// 'pop',
// 'push',
// 'shift',
// 'unshift',
// 'slice',
// 'splice',
// 'includes',
// 'indexOf',
// 'keys',
// 'entries',
// 'forEach',
// 'filter',
// 'map',
// 'every',
// 'some',
// 'reduce',
// 'reduceRight',
// 'join',
// 'reverse',
// 'sort',
// 'lastIndexOf',
// 'copyWithin',
// 'fill',
// 'values',
// 'name',
// 'arguments',
// 'caller',
// 'apply',
// 'bind',
// 'call',
// 'message' }
// TODO: WRITE BABEL PLUGIN
// TODO: ???
// TODO: PROFIT
module.exports = () =>

@@ -24,3 +72,2 @@ // {

AssignmentExpression(path) {
//

@@ -30,5 +77,5 @@ // match

// node -> MyClass.prototype.toString = function(){ return "hello" }
const { node } = path
// member -> MyClass.prototype.toString
// node -> "Xyz.toString = function(){ return "hello" }"
const {node} = path
// member -> "Xyz.toString"
const member = node.left

@@ -39,10 +86,10 @@ // ensure assigning to a non-computed member

// ensure member is a member expression for "prototype"
// assignmentParent -> MyClass.prototype
// assignmentParent -> "Xyz"
const assignmentParent = member.object
if (assignmentParent.type !== 'MemberExpression') return
if (assignmentParent.computed) return
// assignmentTarget -> prototype
const assignmentTarget = assignmentParent.property
if (assignmentTarget.type !== 'Identifier') return
if (assignmentTarget.name !== 'prototype') return
// assignmentParent -> "toString"
const assignmentProperty = member.property
if (assignmentProperty.type !== 'Identifier') return
if (!primordialKeySet.has(assignmentProperty.name)) return
// assignmentValue -> "function(){ return "hello" }"
const assignmentValue = node.right

@@ -53,13 +100,15 @@ //

// parentStatement -> MyClass.prototype
// parentStatement -> "Xyz"
const parentStatement = assignmentParent
// propertyKeyStatement -> toString
const propertyKeyStatement = memberPropToDefinePropKeyArg(member.property)
// valueStatement -> function(){ return "hello" }
const valueStatement = node.right
// propertyKeyStatement -> "toString"
const propertyKeyStatement = memberPropToDefinePropKeyArg(
assignmentProperty,
)
// valueStatement -> "function(){ return "hello" }"
const valueStatement = assignmentValue
const definePropertyExpression = createDefinePropertyExpression(
parentStatement,
propertyKeyStatement,
valueStatement
valueStatement,
)

@@ -73,81 +122,84 @@

function createDefinePropertyExpression (parentStatement, propertyKeyStatement, valueStatement) {
function createDefinePropertyExpression(
parentStatement,
propertyKeyStatement,
valueStatement,
) {
return {
"type": "CallExpression",
"callee": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "Object"
type: 'CallExpression',
callee: {
type: 'MemberExpression',
object: {
type: 'Identifier',
name: 'Object',
},
"property": {
"type": "Identifier",
"name": "defineProperty"
property: {
type: 'Identifier',
name: 'defineProperty',
},
"computed": false
computed: false,
},
"arguments": [
arguments: [
parentStatement,
propertyKeyStatement,
createPropertyDescriptor(valueStatement)
]
createPropertyDescriptor(valueStatement),
],
}
}
function memberPropToDefinePropKeyArg (memberProp) {
function memberPropToDefinePropKeyArg(memberProp) {
return {
"type": "StringLiteral",
"value": memberProp.name,
type: 'StringLiteral',
value: memberProp.name,
}
}
function createPropertyDescriptor (valueStatement) {
function createPropertyDescriptor(valueStatement) {
return {
"type": "ObjectExpression",
type: 'ObjectExpression',
// { value: 1, writable: true, enumerable: true, configurable: true }
"properties": [
properties: [
{
"type": "ObjectProperty",
"key": {
"type": "Identifier",
"name": "value"
type: 'ObjectProperty',
key: {
type: 'Identifier',
name: 'value',
},
"value": valueStatement
value: valueStatement,
},
{
"type": "ObjectProperty",
"key": {
"type": "Identifier",
"name": "writable"
type: 'ObjectProperty',
key: {
type: 'Identifier',
name: 'writable',
},
"value": {
"type": "BooleanLiteral",
"value": true
}
value: {
type: 'BooleanLiteral',
value: true,
},
},
{
"type": "ObjectProperty",
"key": {
"type": "Identifier",
"name": "enumerable"
type: 'ObjectProperty',
key: {
type: 'Identifier',
name: 'enumerable',
},
"value": {
"type": "BooleanLiteral",
"value": true
}
value: {
type: 'BooleanLiteral',
value: true,
},
},
{
"type": "ObjectProperty",
"key": {
"type": "Identifier",
"name": "configurable"
type: 'ObjectProperty',
key: {
type: 'Identifier',
name: 'configurable',
},
"value": {
"type": "BooleanLiteral",
"value": true
}
value: {
type: 'BooleanLiteral',
value: true,
},
},
]
}
}
],
}
}
// this is here to make the import/require API nicer:
// import boilerplate from 'babel-plugin-boilerplate/macro'
module.exports = require('./dist/macro')

Sorry, the diff of this file is not supported yet

import path from 'path'
import pluginTester from 'babel-plugin-tester'
import plugin from 'babel-plugin-macros'
const projectRoot = path.join(__dirname, '../../')
expect.addSnapshotSerializer({
print(val) {
return val.split(projectRoot).join('<PROJECT_ROOT>/')
},
test(val) {
return typeof val === 'string'
},
})
pluginTester({
plugin,
snapshot: true,
babelOptions: {filename: __filename, parserOpts: {plugins: ['jsx']}},
tests: {
'as tag': `
import boilerplate from '../macro'
const greeting = 'Hello world!'
boilerplate\`module.exports = "module.exports = '\${greeting}';"\`
`,
// 'as function': `
// const myCodgen = require('../macro')
// myCodgen(\`
// module.exports = "var x = {booyah() { return 'booyah!'; } };"
// \`)
// `,
// 'as jsx': `
// const boilerplate = require('../macro')
// const ui = (
// <boilerplate>{"module.exports = '<div>Hi</div>'"}</boilerplate>
// )
// `,
// 'as jsx with tag': `
// const boilerplate = require('../macro')
// const ui = (
// <boilerplate>{\`module.exports = '<div>Hi</div>'\`}</boilerplate>
// )
// `,
// 'with multiple': `
// import boilerplate from '../macro'
// boilerplate\`module.exports = ['a', 'b', 'c'].map(l => 'export const ' + l + ' = ' + JSON.stringify(l)).join(';')\`
// `,
// 'as require call': `
// import boilerplate from '../macro';
// var x = boilerplate.require('./fixtures/return-one');
// `,
// 'invalid usage: as fn argument': {
// code: `
// import boilerplate from '../macro';
// var x = doSomething(boilerplate);
// `,
// error: true,
// },
// 'invalid usage: missing code string': {
// code: `
// import boilerplate from '../macro';
// var x = boilerplate;
// `,
// error: true,
// },
},
})
const p = require('path')
const fs = require('fs')
const requireFromCodeString = require('require-from-string')
module.exports = {
requireFromString,
getReplacement,
replace,
resolveModuleContents,
isCodegenComment,
isPropertyCall,
looksLike,
}
function requireFromString(code, filename) {
// Execute the transformed code, as if it were required
const module = requireFromCodeString(String(code), filename)
// Allow for es modules (default export)
return module && module.__esModule ? module.default : module
}
function getReplacement({code, fileOpts, args = []}, babel) {
let module = requireFromString(code, fileOpts.filename)
// If a function is epxorted, call it with args
if (typeof module === 'function') {
module = module(...args)
} else if (args.length) {
throw new Error(
`codegen module (${p.relative(
process.cwd(),
fileOpts.filename,
)}) cannot accept arguments because it does not export a function. You passed the arguments: ${args.join(
', ',
)}`,
)
}
// Convert whatever we got now (hopefully a string) into AST form
if (typeof module !== 'string') {
throw new Error('codegen: Must module.exports a string.')
}
return babel.template(module, {
preserveComments: true,
placeholderPattern: false,
...fileOpts.parserOpts,
sourceType: 'module',
})()
}
function applyReplacementToPath(replacement, path) {
if (!replacement) {
path.remove()
} else if (Array.isArray(replacement)) {
path.replaceWithMultiple(replacement)
} else {
path.replaceWith(replacement)
}
}
function replace({path, code, fileOpts, args}, babel) {
const replacement = getReplacement({code, args, fileOpts}, babel)
applyReplacementToPath(replacement, path)
}
function resolveModuleContents({filename, module}) {
const resolvedPath = p.resolve(p.dirname(filename), module)
const code = fs.readFileSync(require.resolve(resolvedPath))
return {code, resolvedPath}
}
function isCodegenComment(comment) {
const normalisedComment = comment.value
.trim()
.split(' ')[0]
.trim()
return (
normalisedComment.startsWith('codegen') ||
normalisedComment.startsWith('@codegen')
)
}
function isPropertyCall(path, name) {
return looksLike(path, {
node: {
type: 'CallExpression',
callee: {
property: {name},
},
},
})
}
function looksLike(a, b) {
return (
a &&
b &&
Object.keys(b).every(bKey => {
const bVal = b[bKey]
const aVal = a[bKey]
if (typeof bVal === 'function') {
return bVal(aVal)
}
return isPrimitive(bVal) ? bVal === aVal : looksLike(aVal, bVal)
})
)
}
function isPrimitive(val) {
// eslint-disable-next-line
return val == null || /^[sbn]/.test(typeof val)
}
/*
eslint
complexity: ["error", 8],
import/no-unassigned-import: "off",
import/no-dynamic-require: "off",
*/
const {createMacro} = require('babel-plugin-macros')
// const {getReplacement} = require('./helpers')
module.exports = createMacro(yourNewMacro)
// function yourNewMacro({references, state, babel}) {
function yourNewMacro() {
// do something here
}
const {
getReplacement,
replace,
resolveModuleContents,
isCodegenComment,
isPropertyCall,
requireFromString,
} = require('./helpers')
module.exports = getReplacers
function getReplacers(babel) {
function asProgram(path, fileOpts) {
const {code} = babel.transformFromAst(path.node, {
filename: fileOpts.filename,
plugins: fileOpts.plugins,
presets: fileOpts.presets,
})
const replacement = getReplacement({code, fileOpts}, babel)
path.node.body = Array.isArray(replacement) ? replacement : [replacement]
}
function asImportDeclaration(path, fileOpts) {
const codegenComment = path.node.source.leadingComments
.find(isCodegenComment)
.value.trim()
const {code, resolvedPath} = resolveModuleContents({
filename: fileOpts.filename,
module: path.node.source.value,
})
let args
if (codegenComment !== 'codegen') {
args = requireFromString(
`module.exports = [${codegenComment
.replace(/codegen\((.*)\)/, '$1')
.trim()}]`,
fileOpts.filename,
)
}
replace(
{
path,
code,
fileOpts: {
...fileOpts,
filename: resolvedPath,
},
args,
},
babel,
)
}
function asIdentifier(path, fileOpts) {
const targetPath = path.parentPath
switch (targetPath.type) {
case 'TaggedTemplateExpression': {
return asTag(targetPath, fileOpts)
}
case 'CallExpression': {
const isCallee = targetPath.get('callee') === path
if (isCallee) {
return asFunction(targetPath, fileOpts)
} else {
return false
}
}
case 'JSXOpeningElement': {
const jsxElement = targetPath.parentPath
return asJSX(jsxElement, fileOpts)
}
case 'JSXClosingElement': {
// ignore the closing element
// but don't mark as unhandled (return false)
// we already handled the opening element
return true
}
case 'MemberExpression': {
const callPath = targetPath.parentPath
const isRequireCall = isPropertyCall(callPath, 'require')
if (isRequireCall) {
return asImportCall(callPath, fileOpts)
} else {
return false
}
}
default: {
return false
}
}
}
function asImportCall(path, fileOpts) {
const [source, ...args] = path.get('arguments')
const {code, resolvedPath} = resolveModuleContents({
filename: fileOpts.filename,
module: source.node.value,
})
const argValues = args.map(a => {
const result = a.evaluate()
if (!result.confident) {
throw new Error(
'codegen cannot determine the value of an argument in codegen.require',
)
}
return result.value
})
replace(
{
path,
code,
fileOpts: {
...fileOpts,
filename: resolvedPath,
},
args: argValues,
},
babel,
)
}
function asTag(path, fileOpts) {
const code = path.get('quasi').evaluate().value
if (!code) {
throw path.buildCodeFrameError(
'Unable to determine the value of your codegen string',
Error,
)
}
replace({path, code, fileOpts}, babel)
}
function asFunction(path, fileOpts) {
const argumentsPaths = path.get('arguments')
const code = argumentsPaths[0].evaluate().value
replace(
{
path: argumentsPaths[0].parentPath,
code,
fileOpts,
},
babel,
)
}
function asJSX(path, fileOpts) {
const children = path.get('children')
let code = children[0].node.expression.value
if (children[0].node.expression.type === 'TemplateLiteral') {
code = children[0].get('expression').evaluate().value
}
replace(
{
path: children[0].parentPath,
code,
fileOpts,
},
babel,
)
}
return {
asTag,
asJSX,
asFunction,
asProgram,
asImportCall,
asImportDeclaration,
asIdentifier,
}
}
/*
eslint
complexity: ["error", 8]
*/

Sorry, the diff of this file is not supported yet