New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-which-builtins

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-which-builtins - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

.eslintignore

31

__tests__/test.js

@@ -18,2 +18,6 @@ const babel = require('babel-core');

expect(getBuiltinsForCode('Array.of([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator','core-js/modules/es6.array.of']);
// negative cases, calling a static method on the wrong object.
expect(getBuiltinsForCode('Reflect.from([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('Reflect.of([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator']);
});

@@ -24,4 +28,23 @@

expect(getBuiltinsForCode('Array["of"]([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator','core-js/modules/es6.array.of']);
// negative cases, calling a static method on the wrong object.
expect(getBuiltinsForCode('Reflect["from"]([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('Reflect["of"]([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator']);
});
test('test destructure static method', () => {
expect(getBuiltinsForCode('var { from } = Array;')).toEqual(['core-js/modules/es6.array.from','core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { foo, from } = Array;')).toEqual(['core-js/modules/es6.array.from','core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { from: foo } = Array;')).toEqual(['core-js/modules/es6.array.from','core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { foo, from: bar } = Array;')).toEqual(['core-js/modules/es6.array.from','core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('const { of } = Array;')).toEqual(['core-js/modules/es6.array.iterator','core-js/modules/es6.array.of']);
// negative cases, calling a static method on the wrong object.
expect(getBuiltinsForCode('var { from } = Reflect;')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { foo, from } = Reflect;')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { from: foo } = Reflect;')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('var { foo, from: bar } = Reflect;')).toEqual(['core-js/modules/es6.array.iterator']);
expect(getBuiltinsForCode('const { of } = Reflect;')).toEqual(['core-js/modules/es6.array.iterator']);
});
test('test ES5 static method', () => {

@@ -122,1 +145,9 @@ expect(getBuiltinsForCode('Array.isArray([1,2,3]);')).toEqual(['core-js/modules/es6.array.iterator']);

})
test('destructured instance method', () => {
expect(getBuiltinsForCode('var { codePointAt } = foo;')).toEqual(['core-js/modules/es6.array.iterator','core-js/modules/es6.string.code-point-at']);
})
test('destructured instance method 2', () => {
expect(getBuiltinsForCode('const { includes } = foo;')).toEqual(['core-js/modules/es6.array.iterator','core-js/modules/es6.string.includes','core-js/modules/es7.array.includes']);
})

65

index.js

@@ -127,2 +127,30 @@ const alwaysInclude = [

function handleStaticPropertyAccess(objectName, propertyName, builtins) {
const localBuiltins = builtins;
if (staticMethods[objectName]
&& staticMethods[objectName][propertyName]) {
// this is an ES2015/2016/2017 static method that is being used in the code.
localBuiltins[staticMethods[objectName][propertyName]] = true;
}
}
function handleInstancePropertyAccess(propertyName, builtins) {
const localBuiltins = builtins;
if (instanceMethods[propertyName]) {
// this is **potentially** a use of an ES2015/2016/2017/2017 instance method.
// include that instance method's polyfill in case.
instanceMethods[propertyName].forEach((module) => {
localBuiltins[module] = true;
});
}
}
function handlePropertyAccess(objectName, propertyName, scope, builtins) {
if (objectName && (!scope.hasBinding(objectName) || isFromInherentScope(objectName, scope))) {
// this is an ES2015/2016/2017 static method that is being used in the code.
handleStaticPropertyAccess(objectName, propertyName, builtins);
}
handleInstancePropertyAccess(propertyName, builtins);
}
function whichBuiltinsPlugin({ types: t }) {

@@ -154,2 +182,19 @@ let builtins = {};

VariableDeclarator(path) {
// we should ignore this variable declaration if it's not a destructuring
// declaration.
if (!t.isObjectPattern(path.node.id) || !t.isIdentifier(path.node.init)) {
return;
}
const objectName = path.node.init.name;
path.node.id.properties.forEach((property) => {
if (!t.isProperty(property) || !t.isIdentifier(property.key)) {
return;
}
const propertyName = property.key.name;
handlePropertyAccess(objectName, propertyName, path.scope, builtins);
});
},
MemberExpression(path) {

@@ -171,20 +216,8 @@ const object = path.node.object;

if (t.isIdentifier(object)
&& staticMethods[object.name]
&& staticMethods[object.name][propertyName]
&& (
!path.scope.hasBinding(object.name) || isFromInherentScope(object.name, path.scope)
)) {
// this is an ES2015/2016/2017 static method that is being used in the code.
builtins[staticMethods[object.name][propertyName]] = true;
return;
let objectName = null;
if (t.isIdentifier(object)) {
objectName = object.name;
}
if (instanceMethods[propertyName]) {
// this is **potentially** a use of an ES2015/2016/2017/2017 instance method.
// include that instance method's polyfill in case.
instanceMethods[propertyName].forEach((module) => {
builtins[module] = true;
});
}
handlePropertyAccess(objectName, propertyName, path.scope, builtins);
},

@@ -191,0 +224,0 @@ },

{
"name": "babel-plugin-which-builtins",
"version": "0.0.1",
"version": "0.0.2",
"description": "",
"main": "index.js",
"scripts": {
"test": "eslint --ignore-path ../../.eslintignore --quiet *.js && jest"
"test": "eslint --quiet *.js && jest"
},

@@ -14,4 +14,8 @@ "author": "Sasha Aickin",

"eslint": "^3.12.0",
"eslint-config-airbnb": "^12.0.0",
"eslint-plugin-import": "^1.16.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.4.1",
"jest": "^17.0.3"
}
}
#babel-plugin-which-builtins
============================

@@ -10,3 +9,2 @@ This is a Babel plugin which attempts to determine which ECMAScript 2015/2016/2017

##Instructions
============

@@ -29,3 +27,2 @@ First install the plugin to your project, along with `core-js` and `regenerator-runtime`:

##What does it do?
==================

@@ -57,3 +54,2 @@ When this plugin encounters code that seems to use new built-in JavaScript global

##When does the plugin fail?
============================

@@ -72,2 +68,3 @@ Unfortunately, in a completely dynamic language like JavaScript, static analysis

var a = Math.cos(90);
var { cos } = Math;

@@ -78,2 +75,3 @@ // this case will not work because Math doesn't have a direct

var b = getMath().cos(90);
var { cos } = getMath();
```

@@ -88,17 +86,22 @@

var b = "foo"["startsWith"]("f");
var { startsWith } = "foo";
var c = Math.cos(90);
var d = Math["cos"](90);
var { cos } = Math;
// these cases will not work.
var e = "foo"["starts" + "With"]("f");
var f = "startsWith".forEach(method => "foo"[method]("f"))[0];
var g = Math["c" + "os"](90);
var { ["starts" + "With"]: f } = "foo";
var g = "startsWith".forEach(method => "foo"[method]("f"))[0];
var h = Math["c" + "os"](90);
var { ["c" + "os"]: i } = Math;
function getCos() {
return "cos";
}
var h = Math[getCos()](90);
var j = Math[getCos()](90);
var { [getCos()]: k } = Math;
```
##Instance methods may produce false positives
==============================================
Some of the new built-ins in ES2015/2016/2017 are instance methods, like

@@ -114,2 +117,3 @@ `Array.prototype.find` or `String.prototype.startsWith`. It's very difficult

var a = "foo".startsWith("f");
var { startsWith } = "foo";

@@ -119,2 +123,3 @@ // this also triggers an import of String.prototype.startsWith (false positive).

var c = b.startsWith("f");
var { startsWith } = b;

@@ -129,77 +134,76 @@ // this also triggers an import of String.prototype.startsWith (false positive).

#What features are polyfilled?
==============================
* Generators
* `regeneratorRuntime`
* `regeneratorRuntime`
* Global objects
* `DataView`
* `Int8Array`
* `Uint8Array`
* `Uint8ClampedArray`
* `Int16Array`
* `Uint16Array`
* `Int32Array`
* `Uint32Array`
* `Float32Array`
* `Float64Array`
* `Map`
* `Set`
* `WeakMap`
* `WeakSet`
* `Promise`
* `Symbol`
* `Reflect`
* `DataView`
* `Int8Array`
* `Uint8Array`
* `Uint8ClampedArray`
* `Int16Array`
* `Uint16Array`
* `Int32Array`
* `Uint32Array`
* `Float32Array`
* `Float64Array`
* `Map`
* `Set`
* `WeakMap`
* `WeakSet`
* `Promise`
* `Symbol`
* `Reflect`
* Static methods
* `Array.from`
* `Array.of`
* `Math.acosh`
* `Math.asinh`
* `Math.atanh`
* `Math.cbrt`
* `Math.clz32`
* `Math.cosh`
* `Math.expm1`
* `Math.fround`
* `Math.hypot`
* `Math.imul`
* `Math.log1p`
* `Math.log10`
* `Math.log2`
* `Math.sign`
* `Math.sinh`
* `Math.tanh`
* `Math.trunc`
* `Number.isFinite`
* `Number.isInteger`
* `Number.isSafeInteger`
* `Number.isNaN`
* `Number.EPSILON`
* `Number.MIN_SAFE_INTEGER`
* `Number.MAX_SAFE_INTEGER`
* `Object.assign`
* `Object.is`
* `Object.getOwnPropertySymbols`
* `Object.setPrototypeOf`
* `Object.values`
* `Object.entries`
* `Object.getOwnPropertyDescriptors`
* `String.raw`
* `Array.from`
* `Array.of`
* `Math.acosh`
* `Math.asinh`
* `Math.atanh`
* `Math.cbrt`
* `Math.clz32`
* `Math.cosh`
* `Math.expm1`
* `Math.fround`
* `Math.hypot`
* `Math.imul`
* `Math.log1p`
* `Math.log10`
* `Math.log2`
* `Math.sign`
* `Math.sinh`
* `Math.tanh`
* `Math.trunc`
* `Number.isFinite`
* `Number.isInteger`
* `Number.isSafeInteger`
* `Number.isNaN`
* `Number.EPSILON`
* `Number.MIN_SAFE_INTEGER`
* `Number.MAX_SAFE_INTEGER`
* `Object.assign`
* `Object.is`
* `Object.getOwnPropertySymbols`
* `Object.setPrototypeOf`
* `Object.values`
* `Object.entries`
* `Object.getOwnPropertyDescriptors`
* `String.raw`
* Instance methods
* `Array.prototype.copyWithin`
* `Array.prototype.find`
* `Array.prototype.findIndex`
* `Array.prototype.fill`
* `Array.prototype.includes`
* `Function.prototype.name`
* `RegExp.prototype.flags`
* `RegExp.prototype.match`
* `RegExp.prototype.replace`
* `RegExp.prototype.split`
* `RegExp.prototype.search`
* `String.prototype.codePointAt`
* `String.prototype.fromCodePoint`
* `String.prototype.padStart`
* `String.prototype.padEnd`
* `String.prototype.repeat`
* `String.prototype.startsWith`
* `String.prototype.endsWith`
* `String.prototype.includes`
* `Array.prototype.copyWithin`
* `Array.prototype.find`
* `Array.prototype.findIndex`
* `Array.prototype.fill`
* `Array.prototype.includes`
* `Function.prototype.name`
* `RegExp.prototype.flags`
* `RegExp.prototype.match`
* `RegExp.prototype.replace`
* `RegExp.prototype.split`
* `RegExp.prototype.search`
* `String.prototype.codePointAt`
* `String.prototype.fromCodePoint`
* `String.prototype.padStart`
* `String.prototype.padEnd`
* `String.prototype.repeat`
* `String.prototype.startsWith`
* `String.prototype.endsWith`
* `String.prototype.includes`
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