babel-plugin-prototype-prop-define
Advanced tools
Comparing version 1.0.1 to 2.0.1
{ | ||
"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": { |
224
README.md
@@ -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} };" | ||
// `, | ||
// }, | ||
// }, | ||
// }) |
206
src/index.js
@@ -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, | ||
}, | ||
}, | ||
] | ||
} | ||
} | ||
], | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
1
0
26733
18
235
40
1
- Removedbabel-plugin-macros@^2.2.1
- Removed@babel/code-frame@7.24.7(transitive)
- Removed@babel/helper-validator-identifier@7.24.7(transitive)
- Removed@babel/highlight@7.24.7(transitive)
- Removed@babel/runtime@7.25.6(transitive)
- Removed@types/parse-json@4.0.2(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedbabel-plugin-macros@2.8.0(transitive)
- Removedcallsites@3.1.0(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedcosmiconfig@6.0.0(transitive)
- Removederror-ex@1.3.2(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedimport-fresh@3.3.0(transitive)
- Removedis-arrayish@0.2.1(transitive)
- Removedis-core-module@2.15.1(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjson-parse-even-better-errors@2.3.1(transitive)
- Removedlines-and-columns@1.2.4(transitive)
- Removedparent-module@1.0.1(transitive)
- Removedparse-json@5.2.0(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedpath-type@4.0.0(transitive)
- Removedpicocolors@1.1.0(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedresolve@1.22.8(transitive)
- Removedresolve-from@4.0.0(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedyaml@1.10.2(transitive)