jscodeshift
Advanced tools
Comparing version 0.1.5 to 0.1.6
@@ -13,2 +13,6 @@ /* | ||
var _createClass = require('babel-runtime/helpers/create-class')['default']; | ||
var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default']; | ||
var assert = require('assert'); | ||
@@ -29,2 +33,3 @@ var recast = require('recast'); | ||
var Collection = (function () { | ||
@@ -38,9 +43,11 @@ /** | ||
*/ | ||
function Collection(paths, parent, types) { | ||
_classCallCheck(this, Collection); | ||
assert.ok(Array.isArray(paths), 'Collection is passed an array'); | ||
assert.ok( | ||
paths.every(function(p) {return p instanceof NodePath;}), | ||
'Array contains only paths' | ||
); | ||
this.$Collection_parent = parent; | ||
assert.ok(paths.every(function (p) { | ||
return p instanceof NodePath; | ||
}), 'Array contains only paths'); | ||
this._parent = parent; | ||
this.__paths = paths; | ||
@@ -52,138 +59,169 @@ if (types && !Array.isArray(types)) { | ||
} | ||
this.$Collection_types = types.length === 0 ? _defaultType : types; | ||
this._types = types.length === 0 ? _defaultType : types; | ||
} | ||
/** | ||
* Returns a new collection containing the nodes for which the callback | ||
* returns true. | ||
* | ||
* @param {function} callback | ||
* @return {Collection} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"filter",{writable:true,configurable:true,value:function(callback) { | ||
return new this.constructor(this.__paths.filter(callback), this); | ||
}}); | ||
_createClass(Collection, [{ | ||
key: 'filter', | ||
/** | ||
* Executes callback for each node/path in the collection. | ||
* | ||
* @param {function} callback | ||
* @return {Collection} The collection itself | ||
*/ | ||
Object.defineProperty(Collection.prototype,"forEach",{writable:true,configurable:true,value:function(callback) { | ||
this.__paths.forEach(function(path) {return callback.apply(path, arguments);}); | ||
return this; | ||
}}); | ||
/** | ||
* Returns a new collection containing the nodes for which the callback | ||
* returns true. | ||
* | ||
* @param {function} callback | ||
* @return {Collection} | ||
*/ | ||
value: function filter(callback) { | ||
return new this.constructor(this.__paths.filter(callback), this); | ||
} | ||
}, { | ||
key: 'forEach', | ||
/** | ||
* Executes the callback for every path in the collection and returns a new | ||
* collection from the return values (which must be paths). | ||
* | ||
* The callback can return null to indicate to exclude the element from the | ||
* new collection. | ||
* | ||
* If an array is returned, the array will be flattened into the result | ||
* collection. | ||
* | ||
* @param {function} callback | ||
* @param {Type} type Force the new collection to be of a specific type | ||
*/ | ||
Object.defineProperty(Collection.prototype,"map",{writable:true,configurable:true,value:function(callback, type) { | ||
var paths = []; | ||
this.forEach(function(path) { | ||
/*jshint eqnull:true*/ | ||
var result = callback.apply(path, arguments); | ||
if (result == null) return; | ||
if (!Array.isArray(result)) { | ||
result = [result]; | ||
} | ||
for (var i = 0; i < result.length; i++) { | ||
if (paths.indexOf(result[i]) === -1) { | ||
paths.push(result[i]); | ||
/** | ||
* Executes callback for each node/path in the collection. | ||
* | ||
* @param {function} callback | ||
* @return {Collection} The collection itself | ||
*/ | ||
value: function forEach(callback) { | ||
this.__paths.forEach(function (path, i, paths) { | ||
return callback.call(path, path, i, paths); | ||
}); | ||
return this; | ||
} | ||
}, { | ||
key: 'map', | ||
/** | ||
* Executes the callback for every path in the collection and returns a new | ||
* collection from the return values (which must be paths). | ||
* | ||
* The callback can return null to indicate to exclude the element from the | ||
* new collection. | ||
* | ||
* If an array is returned, the array will be flattened into the result | ||
* collection. | ||
* | ||
* @param {function} callback | ||
* @param {Type} type Force the new collection to be of a specific type | ||
*/ | ||
value: function map(callback, type) { | ||
var paths = []; | ||
this.forEach(function (path) { | ||
/*jshint eqnull:true*/ | ||
var result = callback.apply(path, arguments); | ||
if (result == null) return; | ||
if (!Array.isArray(result)) { | ||
result = [result]; | ||
} | ||
} | ||
}); | ||
return fromPaths(paths, this, type); | ||
}}); | ||
for (var i = 0; i < result.length; i++) { | ||
if (paths.indexOf(result[i]) === -1) { | ||
paths.push(result[i]); | ||
} | ||
} | ||
}); | ||
return fromPaths(paths, this, type); | ||
} | ||
}, { | ||
key: 'size', | ||
/** | ||
* Returns the number of elements in this collection. | ||
* | ||
* @return {number} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"size",{writable:true,configurable:true,value:function() { | ||
return this.__paths.length; | ||
}}); | ||
/** | ||
* Returns an array of AST nodes in this collection. | ||
* | ||
* @return {Array} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"nodes",{writable:true,configurable:true,value:function() { | ||
return this.__paths.map(function(p) {return p.value;}); | ||
}}); | ||
Object.defineProperty(Collection.prototype,"paths",{writable:true,configurable:true,value:function() { | ||
return this.__paths; | ||
}}); | ||
Object.defineProperty(Collection.prototype,"getAST",{writable:true,configurable:true,value:function() { | ||
if (this.$Collection_parent) { | ||
return this.$Collection_parent.getAST(); | ||
/** | ||
* Returns the number of elements in this collection. | ||
* | ||
* @return {number} | ||
*/ | ||
value: function size() { | ||
return this.__paths.length; | ||
} | ||
return this.__paths; | ||
}}); | ||
}, { | ||
key: 'nodes', | ||
Object.defineProperty(Collection.prototype,"toSource",{writable:true,configurable:true,value:function(options) { | ||
if (this.$Collection_parent) { | ||
return this.$Collection_parent.toSource(); | ||
/** | ||
* Returns an array of AST nodes in this collection. | ||
* | ||
* @return {Array} | ||
*/ | ||
value: function nodes() { | ||
return this.__paths.map(function (p) { | ||
return p.value; | ||
}); | ||
} | ||
if (this.__paths.length === 1) { | ||
return recast.print(this.__paths[0], options).code; | ||
} else { | ||
return this.__paths.map(function(p) {return recast.print(p, options).code;}); | ||
}, { | ||
key: 'paths', | ||
value: function paths() { | ||
return this.__paths; | ||
} | ||
}}); | ||
}, { | ||
key: 'getAST', | ||
value: function getAST() { | ||
if (this._parent) { | ||
return this._parent.getAST(); | ||
} | ||
return this.__paths; | ||
} | ||
}, { | ||
key: 'toSource', | ||
value: function toSource(options) { | ||
if (this._parent) { | ||
return this._parent.toSource(); | ||
} | ||
if (this.__paths.length === 1) { | ||
return recast.print(this.__paths[0], options).code; | ||
} else { | ||
return this.__paths.map(function (p) { | ||
return recast.print(p, options).code; | ||
}); | ||
} | ||
} | ||
}, { | ||
key: 'at', | ||
/** | ||
* Returns a new collection containing only the element at position index. | ||
* | ||
* @param {number} index | ||
* @return {Collection} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"at",{writable:true,configurable:true,value:function(index) { | ||
return fromPaths(this.__paths.slice(index, index+1), this); | ||
}}); | ||
/** | ||
* Returns a new collection containing only the element at position index. | ||
* | ||
* @param {number} index | ||
* @return {Collection} | ||
*/ | ||
value: function at(index) { | ||
return fromPaths(this.__paths.slice(index, index + 1), this); | ||
} | ||
}, { | ||
key: 'get', | ||
/** | ||
* Proxies to NodePath#get of the first path. | ||
* | ||
* @param {string|number} ...fields | ||
*/ | ||
Object.defineProperty(Collection.prototype,"get",{writable:true,configurable:true,value:function() { | ||
var path = this.__paths[0]; | ||
return path.get.apply(path, arguments); | ||
}}); | ||
/** | ||
* Proxies to NodePath#get of the first path. | ||
* | ||
* @param {string|number} ...fields | ||
*/ | ||
value: function get() { | ||
var path = this.__paths[0]; | ||
return path.get.apply(path, arguments); | ||
} | ||
}, { | ||
key: 'getTypes', | ||
/** | ||
* Returns the type(s) of the collection. This is only used for unit tests, | ||
* I don't think other consumers would need it. | ||
* | ||
* @return {Array<string>} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"getTypes",{writable:true,configurable:true,value:function() { | ||
return this.$Collection_types; | ||
}}); | ||
/** | ||
* Returns the type(s) of the collection. This is only used for unit tests, | ||
* I don't think other consumers would need it. | ||
* | ||
* @return {Array<string>} | ||
*/ | ||
value: function getTypes() { | ||
return this._types; | ||
} | ||
}, { | ||
key: 'isOfType', | ||
/** | ||
* Returns true if this collection has the type 'type'. | ||
* | ||
* @param {Type} type | ||
* @return {boolean} | ||
*/ | ||
Object.defineProperty(Collection.prototype,"isOfType",{writable:true,configurable:true,value:function(type) { | ||
return !!type && this.$Collection_types.indexOf(type.toString()) > -1; | ||
}}); | ||
/** | ||
* Returns true if this collection has the type 'type'. | ||
* | ||
* @param {Type} type | ||
* @return {boolean} | ||
*/ | ||
value: function isOfType(type) { | ||
return !!type && this._types.indexOf(type.toString()) > -1; | ||
} | ||
}]); | ||
return Collection; | ||
})(); | ||
@@ -201,15 +239,13 @@ /** | ||
var nodeType = types[paths[0].node.type]; | ||
var sameType = paths.length === 1 || | ||
paths.every(function(path) {return nodeType.check(path.node);}); | ||
var sameType = paths.length === 1 || paths.every(function (path) { | ||
return nodeType.check(path.node); | ||
}); | ||
if (sameType) { | ||
_types = [nodeType.toString()].concat( | ||
astTypes.getSupertypeNames(nodeType.toString()) | ||
); | ||
_types = [nodeType.toString()].concat(astTypes.getSupertypeNames(nodeType.toString())); | ||
} else { | ||
// try to find a common type | ||
_types = _.intersection.apply( | ||
null, | ||
paths.map(function(path) {return astTypes.getSupertypeNames(path.node.type);}) | ||
); | ||
_types = _.intersection.apply(null, paths.map(function (path) { | ||
return astTypes.getSupertypeNames(path.node.type); | ||
})); | ||
} | ||
@@ -223,8 +259,9 @@ } | ||
value = !Array.isArray(value) ? [value] : value; | ||
value = value.map(function(v) {return v.toString();}); | ||
value = value.map(function (v) { | ||
return v.toString(); | ||
}); | ||
if (value.length > 1) { | ||
return _.union(value, _.intersection.apply( | ||
null, | ||
value.map(function(type) {return astTypes.getSupertypeNames(type);}) | ||
)); | ||
return _.union(value, _.intersection.apply(null, value.map(function (type) { | ||
return astTypes.getSupertypeNames(type); | ||
}))); | ||
} else { | ||
@@ -251,6 +288,5 @@ return value.concat(astTypes.getSupertypeNames(value[0])); | ||
function fromPaths(paths, parent, type) { | ||
assert.ok( | ||
paths.every(function(n) {return n instanceof NodePath;}), | ||
'Every element in the array is a NodePath' | ||
); | ||
assert.ok(paths.every(function (n) { | ||
return n instanceof NodePath; | ||
}), 'Every element in the array is a NodePath'); | ||
@@ -272,11 +308,8 @@ return new Collection(paths, parent, type); | ||
function fromNodes(nodes, parent, type) { | ||
assert.ok( | ||
nodes.every(function(n) {return Node.check(n);}), | ||
'Every element in the array is a Node' | ||
); | ||
return fromPaths( | ||
nodes.map(function(n) {return new NodePath(n);}), | ||
parent, | ||
type | ||
); | ||
assert.ok(nodes.every(function (n) { | ||
return Node.check(n); | ||
}), 'Every element in the array is a Node'); | ||
return fromPaths(nodes.map(function (n) { | ||
return new NodePath(n); | ||
}), parent, type); | ||
} | ||
@@ -297,3 +330,3 @@ | ||
if (CPt.hasOwnProperty(methodName)) { | ||
throw Error(("A method with name \"" + methodName + "\" already exists.")); | ||
throw Error('A method with name "' + methodName + '" already exists.'); | ||
} | ||
@@ -304,13 +337,10 @@ if (!type) { | ||
type = type.toString(); | ||
(function(methodName, method) { | ||
CPt[methodName] = function() { | ||
(function (methodName, method) { | ||
CPt[methodName] = function () { | ||
if (!this.isOfType(type)) { | ||
throw Error( | ||
("You have a collection of type [" + this.getTypes() + "]. ") + | ||
("\"" + methodName + "\" is is only defined for \"" + type + "\".") | ||
); | ||
throw Error('You have a collection of type [' + this.getTypes() + ']. ' + ('"' + methodName + '" is is only defined for "' + type + '".')); | ||
} | ||
return method.apply(this, arguments); | ||
}; | ||
}(methodName, methods[methodName])); | ||
})(methodName, methods[methodName]); | ||
} | ||
@@ -336,2 +366,2 @@ } | ||
exports.registerMethods = registerMethods; | ||
exports.setDefaultCollectionType = setDefaultCollectionType; | ||
exports.setDefaultCollectionType = setDefaultCollectionType; |
@@ -11,6 +11,8 @@ /* | ||
'use strict'; | ||
module.exports = { | ||
Node: require('./Node'), | ||
JSXElement: require('./JSXElement'), | ||
VariableDeclarator: require('./VariableDeclarator'), | ||
}; | ||
VariableDeclarator: require('./VariableDeclarator') | ||
}; |
@@ -13,2 +13,6 @@ /* | ||
var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; | ||
var _Object$create = require('babel-runtime/core-js/object/create')['default']; | ||
var _ = require('lodash'); | ||
@@ -37,4 +41,4 @@ var Collection = require('../Collection'); | ||
*/ | ||
findJSXElements: function(name) { | ||
var nameFilter = name && {openingElement: {name: {name: name}}}; | ||
findJSXElements: function findJSXElements(name) { | ||
var nameFilter = name && { openingElement: { name: { name: name } } }; | ||
return this.find(JSXElement, nameFilter); | ||
@@ -52,19 +56,11 @@ }, | ||
*/ | ||
findJSXElementsByModuleName: function(moduleName) { | ||
assert.ok( | ||
moduleName && typeof moduleName === 'string', | ||
'findJSXElementsByModuleName(...) needs a name to look for' | ||
); | ||
findJSXElementsByModuleName: function findJSXElementsByModuleName(moduleName) { | ||
assert.ok(moduleName && typeof moduleName === 'string', 'findJSXElementsByModuleName(...) needs a name to look for'); | ||
return this.find(types.VariableDeclarator) | ||
.filter(requiresModule(moduleName)) | ||
.map(function(path) { | ||
var id = path.value.id.name; | ||
if (id) { | ||
return Collection.fromPaths([path]) | ||
.closestScope() | ||
.findJSXElements(id) | ||
.paths(); | ||
} | ||
}); | ||
return this.find(types.VariableDeclarator).filter(requiresModule(moduleName)).map(function (path) { | ||
var id = path.value.id.name; | ||
if (id) { | ||
return Collection.fromPaths([path]).closestScope().findJSXElements(id).paths(); | ||
} | ||
}); | ||
} | ||
@@ -81,4 +77,4 @@ }; | ||
*/ | ||
hasAttributes: function(attributeFilter) { | ||
var attributeNames = Object.keys(attributeFilter); | ||
hasAttributes: function hasAttributes(attributeFilter) { | ||
var attributeNames = _Object$keys(attributeFilter); | ||
return function filter(path) { | ||
@@ -88,6 +84,5 @@ if (!JSXElement.check(path.value)) { | ||
} | ||
var elementAttributes = Object.create(null); | ||
path.value.openingElement.attributes.forEach(function(attr) { | ||
if (!JSXAttribute.check(attr) || | ||
!(attr.name.name in attributeFilter)) { | ||
var elementAttributes = _Object$create(null); | ||
path.value.openingElement.attributes.forEach(function (attr) { | ||
if (!JSXAttribute.check(attr) || !(attr.name.name in attributeFilter)) { | ||
return; | ||
@@ -98,4 +93,4 @@ } | ||
return attributeNames.every(function(name) { | ||
if (!(name in elementAttributes) ){ | ||
return attributeNames.every(function (name) { | ||
if (!(name in elementAttributes)) { | ||
return false; | ||
@@ -122,9 +117,7 @@ } | ||
*/ | ||
hasChildren: function(name) { | ||
hasChildren: function hasChildren(name) { | ||
return function filter(path) { | ||
return JSXElement.check(path.value) && | ||
path.value.children.some( | ||
function(child) {return JSXElement.check(child) && | ||
child.openingElement.name.name === name;} | ||
); | ||
return JSXElement.check(path.value) && path.value.children.some(function (child) { | ||
return JSXElement.check(child) && child.openingElement.name.name === name; | ||
}); | ||
}; | ||
@@ -141,5 +134,5 @@ } | ||
*/ | ||
childNodes: function() { | ||
childNodes: function childNodes() { | ||
var paths = []; | ||
this.forEach(function(path) { | ||
this.forEach(function (path) { | ||
var children = path.get('children'); | ||
@@ -159,5 +152,5 @@ var l = children.value.length; | ||
*/ | ||
childElements: function() { | ||
childElements: function childElements() { | ||
var paths = []; | ||
this.forEach(function(path) { | ||
this.forEach(function (path) { | ||
var children = path.get('children'); | ||
@@ -172,3 +165,3 @@ var l = children.value.length; | ||
return Collection.fromPaths(paths, this, JSXElement); | ||
}, | ||
} | ||
}; | ||
@@ -184,3 +177,3 @@ | ||
*/ | ||
getRootName: function(path) { | ||
getRootName: function getRootName(path) { | ||
var name = path.value.openingElement.name; | ||
@@ -203,2 +196,2 @@ while (types.JSXMemberExpression.check(name)) { | ||
exports.filters = filterMethods; | ||
exports.mappings = mappingMethods; | ||
exports.mappings = mappingMethods; |
@@ -13,2 +13,4 @@ /* | ||
var _toConsumableArray = require('babel-runtime/helpers/to-consumable-array')['default']; | ||
var _ = require('lodash'); | ||
@@ -24,13 +26,2 @@ var Collection = require('../Collection'); | ||
function methodNameFromType(type) { | ||
return 'visit' + type; | ||
} | ||
function functionify(value) { | ||
return typeof value === 'function' ? value : function() { | ||
return value; | ||
}; | ||
} | ||
var traversalMethods = { | ||
@@ -45,5 +36,5 @@ | ||
*/ | ||
find: function(type, filter) { | ||
find: function find(type, filter) { | ||
var paths = []; | ||
var visitorMethodName = methodNameFromType(type); | ||
var visitorMethodName = 'visit' + type; | ||
@@ -58,5 +49,5 @@ var visitor = {}; | ||
} | ||
this.__paths.forEach(function(p, i) { | ||
this.__paths.forEach(function (p, i) { | ||
var self = this; | ||
visitor[visitorMethodName] = function(path) { | ||
visitor[visitorMethodName] = function (path) { | ||
if (self.__paths[i] === path) { | ||
@@ -80,4 +71,6 @@ this.traverse(path); | ||
*/ | ||
closestScope: function() { | ||
return this.map(function(path) {return path.scope && path.scope.path;}); | ||
closestScope: function closestScope() { | ||
return this.map(function (path) { | ||
return path.scope && path.scope.path; | ||
}); | ||
}, | ||
@@ -92,10 +85,6 @@ | ||
*/ | ||
closest: function(type, filter) { | ||
return this.map(function(path) { | ||
closest: function closest(type, filter) { | ||
return this.map(function (path) { | ||
var parent = path.parent; | ||
while ( | ||
parent && | ||
!type.check(parent.value) && | ||
(!filter || matchNode(parent.value, filter)) | ||
) { | ||
while (parent && !type.check(parent.value) && (!filter || matchNode(parent.value, filter))) { | ||
parent = parent.parent; | ||
@@ -118,4 +107,4 @@ } | ||
*/ | ||
getVariableDeclarators: function(nameGetter) { | ||
return this.map(function(path) { | ||
getVariableDeclarators: function getVariableDeclarators(nameGetter) { | ||
return this.map(function (path) { | ||
/*jshint curly:false*/ | ||
@@ -130,4 +119,3 @@ var scope = path.scope; | ||
if (!bindings) return; | ||
var decl = Collection.fromPaths(bindings) | ||
.closest(types.VariableDeclarator); | ||
var decl = Collection.fromPaths(bindings).closest(types.VariableDeclarator); | ||
if (decl.size() === 1) { | ||
@@ -137,5 +125,9 @@ return decl.paths()[0]; | ||
}, types.VariableDeclarator); | ||
}, | ||
} | ||
}; | ||
function toArray(value) { | ||
return Array.isArray(value) ? value : [value]; | ||
} | ||
var mutationMethods = { | ||
@@ -147,12 +139,9 @@ /** | ||
* | ||
* @param {Node|function} replacement | ||
* @param {Node|Array<Node>|function} nodes | ||
* @return {Collection} | ||
*/ | ||
replaceWith: function(replacement) { | ||
replacement = functionify(replacement); | ||
return this.forEach(function(path, i) { | ||
var newNode = replacement.call(path, path, i); | ||
assert(Node.check(newNode), 'Replacement function returns a node'); | ||
path.replace(newNode); | ||
replaceWith: function replaceWith(nodes) { | ||
return this.forEach(function (path, i) { | ||
var newNodes = typeof nodes === 'function' ? nodes.call(path, path, i) : nodes; | ||
path.replace.apply(path, _toConsumableArray(toArray(newNodes))); | ||
}); | ||
@@ -164,12 +153,9 @@ }, | ||
* | ||
* @param {Node|function} insert | ||
* @param {Node|Array<Node>|function} insert | ||
* @return {Collection} | ||
*/ | ||
insertBefore: function(insert) { | ||
insert = functionify(insert); | ||
return this.forEach(function(path, i) { | ||
var node = insert.call(path, path, i); | ||
assert(Node.check(node), 'Insert function returns a node'); | ||
path.insertBefore(node); | ||
insertBefore: function insertBefore(insert) { | ||
return this.forEach(function (path, i) { | ||
var newNodes = typeof insert === 'function' ? insert.call(path, path, i) : insert; | ||
path.insertBefore.apply(path, _toConsumableArray(toArray(newNodes))); | ||
}); | ||
@@ -181,12 +167,9 @@ }, | ||
* | ||
* @param {Node|function} insert | ||
* @param {Node|Array<Node>|function} insert | ||
* @return {Collection} | ||
*/ | ||
insertAfter: function(insert) { | ||
insert = functionify(insert); | ||
return this.forEach(function(path, i) { | ||
var node = insert.call(path, path, i); | ||
assert(Node.check(node), 'Insert function returns a node'); | ||
path.insertAfter(node); | ||
insertAfter: function insertAfter(insert) { | ||
return this.forEach(function (path, i) { | ||
var newNodes = typeof insert === 'function' ? insert.call(path, path, i) : insert; | ||
path.insertAfter.apply(path, _toConsumableArray(toArray(newNodes))); | ||
}); | ||
@@ -203,2 +186,2 @@ } | ||
exports.register = _.once(register); | ||
exports.register = _.once(register); |
@@ -32,4 +32,4 @@ /* | ||
*/ | ||
findVariableDeclarators: function(name) { | ||
var filter = name ? {id: {name: name}} : null; | ||
findVariableDeclarators: function findVariableDeclarators(name) { | ||
var filter = name ? { id: { name: name } } : null; | ||
return this.find(VariableDeclarator, filter); | ||
@@ -39,3 +39,2 @@ } | ||
var filterMethods = { | ||
@@ -49,3 +48,3 @@ /** | ||
*/ | ||
requiresModule: function(names) { | ||
requiresModule: function requiresModule(names) { | ||
if (names && !Array.isArray(names)) { | ||
@@ -55,13 +54,10 @@ names = [names]; | ||
var requireIdentifier = b.identifier('require'); | ||
return function(path) { | ||
return function (path) { | ||
var node = path.value; | ||
if (!VariableDeclarator.check(node) || | ||
!types.CallExpression.check(node.init) || | ||
!astNodesAreEquivalent(node.init.callee, requireIdentifier)) { | ||
if (!VariableDeclarator.check(node) || !types.CallExpression.check(node.init) || !astNodesAreEquivalent(node.init.callee, requireIdentifier)) { | ||
return false; | ||
} | ||
return !names || | ||
names.some( | ||
function(n) {return astNodesAreEquivalent(node.init.arguments[0], b.literal(n));} | ||
); | ||
return !names || names.some(function (n) { | ||
return astNodesAreEquivalent(node.init.arguments[0], b.literal(n)); | ||
}); | ||
}; | ||
@@ -78,5 +74,5 @@ } | ||
*/ | ||
renameTo: function(newName) { | ||
renameTo: function renameTo(newName) { | ||
// TODO: Include JSXElements | ||
return this.forEach(function(path) { | ||
return this.forEach(function (path) { | ||
var node = path.value; | ||
@@ -86,22 +82,19 @@ var oldName = node.id.name; | ||
var rootPath = rootScope.path; | ||
Collection.fromPaths([rootPath]) | ||
.find(types.Identifier, {name: oldName}) | ||
.filter(function(path) { // ignore properties in MemberExpressions | ||
var parent = path.parent.node; | ||
return !types.MemberExpression.check(parent) || | ||
parent.property !== path.node || | ||
!parent.computed; | ||
}) | ||
.forEach(function(path) { | ||
var scope = path.scope; | ||
while (scope && scope !== rootScope) { | ||
if (scope.declares(oldName)) { | ||
return; | ||
} | ||
scope = scope.parent; | ||
Collection.fromPaths([rootPath]).find(types.Identifier, { name: oldName }).filter(function (path) { | ||
// ignore properties in MemberExpressions | ||
var parent = path.parent.node; | ||
return !types.MemberExpression.check(parent) || parent.property !== path.node || !parent.computed; | ||
}).forEach(function (path) { | ||
var scope = path.scope; | ||
while (scope && scope !== rootScope) { | ||
if (scope.declares(oldName)) { | ||
return; | ||
} | ||
if (scope) { // identifier must refer to declared variable | ||
path.get('name').replace(newName); | ||
} | ||
}); | ||
scope = scope.parent; | ||
} | ||
if (scope) { | ||
// identifier must refer to declared variable | ||
path.get('name').replace(newName); | ||
} | ||
}); | ||
}); | ||
@@ -111,3 +104,2 @@ } | ||
function register() { | ||
@@ -120,2 +112,2 @@ NodeCollection.register(); | ||
exports.register = _.once(register); | ||
exports.filters = filterMethods; | ||
exports.filters = filterMethods; |
@@ -18,2 +18,3 @@ /* | ||
var recast = require('recast'); | ||
var template = require('./template'); | ||
var _ = require('lodash'); | ||
@@ -68,9 +69,7 @@ | ||
} | ||
throw new TypeError( | ||
'Received an unexpected value ' + Object.prototype.toString.call(ast) | ||
); | ||
throw new TypeError('Received an unexpected value ' + Object.prototype.toString.call(ast)); | ||
} | ||
function fromSource(source) { | ||
return fromAST(recast.parse(source, {esprima: esprima}).program); | ||
return fromAST(recast.parse(source, { esprima: esprima }).program); | ||
} | ||
@@ -90,3 +89,3 @@ | ||
} else { | ||
path = {value: path}; | ||
path = { value: path }; | ||
} | ||
@@ -103,2 +102,3 @@ } | ||
core.match = match; | ||
core.template = template; | ||
@@ -117,2 +117,2 @@ // add mappings and filters to function | ||
module.exports = core; | ||
module.exports = core; |
@@ -13,5 +13,6 @@ /* | ||
var hasOwn = | ||
Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); | ||
var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; | ||
var hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty); | ||
/** | ||
@@ -25,10 +26,8 @@ * Checks whether needle is a strict subset of haystack. | ||
function matchNode(haystack, needle) { | ||
var props = Object.keys(needle); | ||
return props.every(function(prop) { | ||
var props = _Object$keys(needle); | ||
return props.every(function (prop) { | ||
if (!hasOwn(haystack, prop)) { | ||
return false; | ||
} | ||
if (haystack[prop] && | ||
typeof haystack[prop] === 'object' && | ||
typeof needle[prop] === 'object') { | ||
if (haystack[prop] && typeof haystack[prop] === 'object' && typeof needle[prop] === 'object') { | ||
return matchNode(haystack[prop], needle[prop]); | ||
@@ -40,2 +39,2 @@ } | ||
module.exports = matchNode; | ||
module.exports = matchNode; |
@@ -13,2 +13,4 @@ /* | ||
var _Object$keys = require('babel-runtime/core-js/object/keys')['default']; | ||
var child_process = require('child_process'); | ||
@@ -33,17 +35,11 @@ var clc = require('cli-color'); | ||
function showFileStats(fileStats) { | ||
console.log( | ||
'Results:', | ||
clc.red(fileStats.error + ' errors'), | ||
clc.yellow(fileStats.nochange + ' unmodifed'), | ||
clc.yellow(fileStats.skip + ' skipped'), | ||
clc.green(fileStats.ok + ' ok') | ||
); | ||
console.log('Results:', clc.red(fileStats.error + ' errors'), clc.yellow(fileStats.nochange + ' unmodifed'), clc.yellow(fileStats.skip + ' skipped'), clc.green(fileStats.ok + ' ok')); | ||
} | ||
function showStats(stats) { | ||
var names = Object.keys(stats).sort(); | ||
var names = _Object$keys(stats).sort(); | ||
if (names.length) { | ||
console.log(clc.blue('Stats:')); | ||
} | ||
names.forEach(function(name) { | ||
names.forEach(function (name) { | ||
console.log(name + ':', stats[name]); | ||
@@ -62,6 +58,3 @@ }); | ||
if (!fs.existsSync(transformFile)) { | ||
console.log( | ||
clc.whiteBright.bgRed('ERROR') + ' Transform file %s does not exist', | ||
transformFile | ||
); | ||
console.log(clc.whiteBright.bgRed('ERROR') + ' Transform file %s does not exist', transformFile); | ||
return; | ||
@@ -86,7 +79,3 @@ } | ||
console.log('Processing %d files...', files.length); | ||
console.log( | ||
'Spawning %d workers with %d files each...', | ||
file_chunks.length, | ||
file_chunks[0].length | ||
); | ||
console.log('Spawning %d workers with %d files each...', file_chunks.length, file_chunks[0].length); | ||
if (options.dry) { | ||
@@ -96,3 +85,3 @@ console.log(clc.green('Running in dry mode, no files be written!')); | ||
var fileCounters = {error: 0, ok: 0, nochange: 0, skip: 0}; | ||
var fileCounters = { error: 0, ok: 0, nochange: 0, skip: 0 }; | ||
var statsCounter = {}; | ||
@@ -108,7 +97,3 @@ var doneCounter = 0; | ||
showStats(statsCounter); | ||
console.log( | ||
'Time elapsed: %d.%d seconds', | ||
endTime[0], | ||
(endTime[1]/1000000).toFixed(0) | ||
); | ||
console.log('Time elapsed: %d.%d seconds', endTime[0], (endTime[1] / 1000000).toFixed(0)); | ||
} | ||
@@ -133,8 +118,5 @@ } | ||
var startTime = process.hrtime(); | ||
file_chunks.forEach(function(files) { | ||
var child = child_process.fork( | ||
require.resolve('./Worker'), | ||
[transformFile] | ||
); | ||
child.send({files: files, options: options}); | ||
file_chunks.forEach(function (files) { | ||
var child = child_process.fork(require.resolve('./Worker'), [transformFile]); | ||
child.send({ files: files, options: options }); | ||
child.on('message', onMessage); | ||
@@ -145,2 +127,2 @@ child.on('disconnect', onEnd); | ||
exports.run = run; | ||
exports.run = run; |
@@ -20,4 +20,4 @@ /* | ||
function updateStatus(status, file, msg) { | ||
msg = msg ? file + ' ' + msg : file; | ||
process.send({action: 'status', status: status, msg: msg}); | ||
msg = msg ? file + ' ' + msg : file; | ||
process.send({ action: 'status', status: status, msg: msg }); | ||
} | ||
@@ -29,3 +29,3 @@ | ||
quantity = typeof quantity !== 'number' ? 1 : quantity; | ||
process.send({action: 'update', name: name, quantity: quantity}); | ||
process.send({ action: 'update', name: name, quantity: quantity }); | ||
} | ||
@@ -37,3 +37,3 @@ | ||
var result = []; | ||
lines.every(function(line) { | ||
lines.every(function (line) { | ||
if (line.indexOf(__filename) === -1) { | ||
@@ -47,65 +47,53 @@ result.push(line); | ||
process.on('message', function(data) { | ||
process.on('message', function (data) { | ||
var files = data.files; | ||
var options = data.options; | ||
async.each( | ||
files, | ||
function(file, callback) { | ||
fs.readFile(file, function(err, source) { | ||
if (err) { | ||
updateStatus('error', file, 'File error: ' + err); | ||
async.each(files, function (file, callback) { | ||
fs.readFile(file, function (err, source) { | ||
if (err) { | ||
updateStatus('error', file, 'File error: ' + err); | ||
callback(); | ||
return; | ||
} | ||
source = source.toString(); | ||
try { | ||
var out = transform({ | ||
path: file, | ||
source: source | ||
}, { | ||
jscodeshift: jscodeshift, | ||
stats: options.dry ? stats : empty | ||
}, options); | ||
if (!out || out === source) { | ||
updateStatus(out ? 'nochange' : 'skip', file); | ||
callback(); | ||
return; | ||
} | ||
source = source.toString(); | ||
try { | ||
var out = transform( | ||
{ | ||
path: file, | ||
source: source, | ||
}, | ||
{ | ||
jscodeshift: jscodeshift, | ||
stats: options.dry ? stats : empty | ||
}, | ||
options | ||
); | ||
if (!out || out === source) { | ||
updateStatus(out ? 'nochange' : 'skip', file); | ||
if (options.print) { | ||
console.log(out); | ||
} | ||
if (!options.dry) { | ||
fs.writeFile(file, out, function (err) { | ||
if (err) { | ||
updateStatus('error', file, 'File writer error: ' + err); | ||
} else { | ||
updateStatus('ok', file); | ||
} | ||
callback(); | ||
return; | ||
} | ||
if (options.print) { | ||
console.log(out); | ||
} | ||
if (!options.dry) { | ||
fs.writeFile(file, out, function(err) { | ||
if (err) { | ||
updateStatus('error', file, 'File writer error: ' + err); | ||
} else { | ||
updateStatus('ok', file); | ||
} | ||
callback(); | ||
}); | ||
} else { | ||
updateStatus('ok', file); | ||
callback(); | ||
} | ||
} catch(err) { | ||
updateStatus( | ||
'error', | ||
file, | ||
'Transformation error\n' + trimStackTrace(err.stack) | ||
); | ||
}); | ||
} else { | ||
updateStatus('ok', file); | ||
callback(); | ||
} | ||
}); | ||
}, | ||
function(err) { | ||
if (err) { | ||
updateStatus('error', '', 'This should never be shown!'); | ||
} catch (err) { | ||
updateStatus('error', file, 'Transformation error\n' + trimStackTrace(err.stack)); | ||
callback(); | ||
} | ||
process.disconnect(); | ||
}); | ||
}, function (err) { | ||
if (err) { | ||
updateStatus('error', '', 'This should never be shown!'); | ||
} | ||
); | ||
}); | ||
process.disconnect(); | ||
}); | ||
}); |
{ | ||
"name": "jscodeshift", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "A toolkit for JavaScript codemods", | ||
@@ -12,5 +12,5 @@ "repository": { | ||
"scripts": { | ||
"build": "rm -rf dist; jsx --harmony src/ dist/", | ||
"watch": "jsx --harmony src/ dist/ -w", | ||
"test": "npm run build && jest", | ||
"build": "rm -rf dist; babel src/ --out-dir dist/", | ||
"watch": "babel src/ --out-dir dist/ --watch", | ||
"test": "jest", | ||
"prepublish": "npm run build" | ||
@@ -29,4 +29,6 @@ }, | ||
"async": "^0.9.0", | ||
"babel": "^5.6.14", | ||
"babel-runtime": "^5.6.18", | ||
"cli-color": "^0.3.2", | ||
"esprima-fb": "^14001.1.0-dev-harmony-fb", | ||
"esprima-fb": "^15001.1.0-dev-harmony-fb", | ||
"lodash": "^3.5.0", | ||
@@ -37,14 +39,19 @@ "nomnom": "^1.8.1", | ||
"devDependencies": { | ||
"babel-jest": "^5.3.0", | ||
"es6-promise": "^2.0.1", | ||
"jest-cli": "^0.4.0", | ||
"react-tools": "^0.13.1", | ||
"temp": "^0.8.1" | ||
}, | ||
"jest": { | ||
"scriptPreprocessor": "./scripts/test-preprocess.js", | ||
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest", | ||
"preprocessCachingDisabled": true, | ||
"testPathDirs": [ | ||
"src", | ||
"bin" | ||
], | ||
"unmockedModulePathPatterns": [ | ||
"babel-runtime", | ||
"babel" | ||
] | ||
} | ||
} |
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
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
54649
20
1175
8
+ Addedbabel@^5.6.14
+ Addedbabel-runtime@^5.6.18
+ Addedacorn@5.7.4(transitive)
+ Addedalign-text@0.1.4(transitive)
+ Addedalter@0.2.0(transitive)
+ Addedamdefine@1.0.1(transitive)
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedanymatch@1.3.2(transitive)
+ Addedarr-diff@2.0.04.0.0(transitive)
+ Addedarr-flatten@1.1.0(transitive)
+ Addedarr-union@3.1.0(transitive)
+ Addedarray-unique@0.2.10.3.2(transitive)
+ Addedassign-symbols@1.0.0(transitive)
+ Addedast-traverse@0.1.1(transitive)
+ Addedast-types@0.8.120.9.6(transitive)
+ Addedasync-each@1.0.6(transitive)
+ Addedatob@2.1.2(transitive)
+ Addedbabel@5.8.38(transitive)
+ Addedbabel-core@5.8.38(transitive)
+ Addedbabel-plugin-constant-folding@1.0.1(transitive)
+ Addedbabel-plugin-dead-code-elimination@1.0.2(transitive)
+ Addedbabel-plugin-eval@1.0.1(transitive)
+ Addedbabel-plugin-inline-environment-variables@1.0.1(transitive)
+ Addedbabel-plugin-jscript@1.0.4(transitive)
+ Addedbabel-plugin-member-expression-literals@1.0.1(transitive)
+ Addedbabel-plugin-property-literals@1.0.1(transitive)
+ Addedbabel-plugin-proto-to-assign@1.0.4(transitive)
+ Addedbabel-plugin-react-constant-elements@1.0.3(transitive)
+ Addedbabel-plugin-react-display-name@1.0.3(transitive)
+ Addedbabel-plugin-remove-console@1.0.1(transitive)
+ Addedbabel-plugin-remove-debugger@1.0.1(transitive)
+ Addedbabel-plugin-runtime@1.0.7(transitive)
+ Addedbabel-plugin-undeclared-variables-check@1.0.2(transitive)
+ Addedbabel-plugin-undefined-to-void@1.1.6(transitive)
+ Addedbabel-runtime@5.8.38(transitive)
+ Addedbabylon@5.8.38(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbase@0.11.2(transitive)
+ Addedbinary-extensions@1.13.1(transitive)
+ Addedbindings@1.5.0(transitive)
+ Addedbluebird@2.11.0(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedbraces@1.8.52.3.2(transitive)
+ Addedbreakable@1.0.0(transitive)
+ Addedcache-base@1.0.1(transitive)
+ Addedcamelcase@1.2.1(transitive)
+ Addedcenter-align@0.1.3(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedchokidar@1.7.0(transitive)
+ Addedclass-utils@0.3.6(transitive)
+ Addedcliui@2.1.0(transitive)
+ Addedcollection-visit@1.0.0(transitive)
+ Addedcommander@2.20.3(transitive)
+ Addedcommoner@0.10.8(transitive)
+ Addedcomponent-emitter@1.3.1(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedconvert-source-map@1.9.0(transitive)
+ Addedcopy-descriptor@0.1.1(transitive)
+ Addedcore-js@1.2.7(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addeddebug@2.6.9(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addeddecode-uri-component@0.2.2(transitive)
+ Addeddefine-property@0.2.51.0.02.0.2(transitive)
+ Addeddefined@1.0.1(transitive)
+ Addeddefs@1.1.1(transitive)
+ Addeddetect-indent@3.0.1(transitive)
+ Addeddetective@4.7.1(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedesprima@2.7.33.1.3(transitive)
+ Addedesprima-fb@15001.1.0-dev-harmony-fb(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedexpand-brackets@0.1.52.1.4(transitive)
+ Addedexpand-range@1.8.2(transitive)
+ Addedextend-shallow@2.0.13.0.2(transitive)
+ Addedextglob@0.3.22.0.4(transitive)
+ Addedfile-uri-to-path@1.0.0(transitive)
+ Addedfilename-regex@2.0.1(transitive)
+ Addedfill-range@2.2.44.0.0(transitive)
+ Addedfor-in@1.0.2(transitive)
+ Addedfor-own@0.1.5(transitive)
+ Addedfragment-cache@0.2.1(transitive)
+ Addedfs-readdir-recursive@0.1.2(transitive)
+ Addedfsevents@1.2.13(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-stdin@4.0.1(transitive)
+ Addedget-value@2.0.6(transitive)
+ Addedglob@5.0.15(transitive)
+ Addedglob-base@0.3.0(transitive)
+ Addedglob-parent@2.0.0(transitive)
+ Addedglobals@6.4.1(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedhas-value@0.3.11.0.0(transitive)
+ Addedhas-values@0.1.41.0.0(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedhome-or-tmp@1.0.0(transitive)
+ Addediconv-lite@0.4.24(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedinvert-kv@1.0.0(transitive)
+ Addedis-accessor-descriptor@1.0.1(transitive)
+ Addedis-binary-path@1.0.1(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-core-module@2.15.1(transitive)
+ Addedis-data-descriptor@1.0.1(transitive)
+ Addedis-descriptor@0.1.71.0.3(transitive)
+ Addedis-dotfile@1.0.3(transitive)
+ Addedis-equal-shallow@0.1.3(transitive)
+ Addedis-extendable@0.1.11.0.1(transitive)
+ Addedis-extglob@1.0.0(transitive)
+ Addedis-finite@1.1.0(transitive)
+ Addedis-glob@2.0.1(transitive)
+ Addedis-integer@1.0.7(transitive)
+ Addedis-number@2.1.03.0.04.0.0(transitive)
+ Addedis-plain-object@2.0.4(transitive)
+ Addedis-posix-bracket@0.1.1(transitive)
+ Addedis-primitive@2.0.0(transitive)
+ Addedis-windows@1.0.2(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedisobject@2.1.03.0.1(transitive)
+ Addedjs-tokens@1.0.1(transitive)
+ Addedjsesc@0.5.0(transitive)
+ Addedjson5@0.4.0(transitive)
+ Addedkind-of@3.2.24.0.06.0.3(transitive)
+ Addedlazy-cache@1.0.4(transitive)
+ Addedlcid@1.0.0(transitive)
+ Addedleven@1.0.2(transitive)
+ Addedlongest@1.0.1(transitive)
+ Addedmap-cache@0.2.2(transitive)
+ Addedmap-visit@1.0.0(transitive)
+ Addedmath-random@1.0.4(transitive)
+ Addedmicromatch@2.3.113.1.10(transitive)
+ Addedminimatch@2.0.10(transitive)
+ Addedminimist@1.2.8(transitive)
+ Addedmixin-deep@1.3.2(transitive)
+ Addedmkdirp@0.5.6(transitive)
+ Addedms@2.0.0(transitive)
+ Addednan@2.22.0(transitive)
+ Addednanomatch@1.2.13(transitive)
+ Addednormalize-path@2.1.1(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedobject-copy@0.1.0(transitive)
+ Addedobject-visit@1.0.1(transitive)
+ Addedobject.omit@2.0.1(transitive)
+ Addedobject.pick@1.3.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-locale@1.4.0(transitive)
+ Addedos-tmpdir@1.0.2(transitive)
+ Addedoutput-file-sync@1.1.2(transitive)
+ Addedparse-glob@3.0.4(transitive)
+ Addedpascalcase@0.1.1(transitive)
+ Addedpath-exists@1.0.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedposix-character-classes@0.1.1(transitive)
+ Addedpreserve@0.2.0(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedq@1.5.1(transitive)
+ Addedrandomatic@3.1.1(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedreaddirp@2.2.1(transitive)
+ Addedrecast@0.10.330.11.23(transitive)
+ Addedregenerate@1.4.2(transitive)
+ Addedregenerator@0.8.40(transitive)
+ Addedregex-cache@0.4.4(transitive)
+ Addedregex-not@1.0.2(transitive)
+ Addedregexpu@1.3.0(transitive)
+ Addedregjsgen@0.2.0(transitive)
+ Addedregjsparser@0.1.5(transitive)
+ Addedremove-trailing-separator@1.1.0(transitive)
+ Addedrepeat-element@1.1.4(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedrepeating@1.1.3(transitive)
+ Addedresolve@1.22.8(transitive)
+ Addedresolve-url@0.2.1(transitive)
+ Addedret@0.1.15(transitive)
+ Addedright-align@0.1.3(transitive)
+ Addedsafe-buffer@5.1.2(transitive)
+ Addedsafe-regex@1.1.0(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedset-value@2.0.1(transitive)
+ Addedshebang-regex@1.0.0(transitive)
+ Addedsimple-fmt@0.1.0(transitive)
+ Addedsimple-is@0.2.0(transitive)
+ Addedslash@1.0.0(transitive)
+ Addedsnapdragon@0.8.2(transitive)
+ Addedsnapdragon-node@2.1.1(transitive)
+ Addedsnapdragon-util@3.0.1(transitive)
+ Addedsource-map@0.1.32(transitive)
+ Addedsource-map-resolve@0.5.3(transitive)
+ Addedsource-map-support@0.2.10(transitive)
+ Addedsource-map-url@0.4.1(transitive)
+ Addedsplit-string@3.1.0(transitive)
+ Addedstable@0.1.8(transitive)
+ Addedstatic-extend@0.1.2(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedstringmap@0.2.2(transitive)
+ Addedstringset@0.2.1(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.0(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
+ Addedthrough@2.3.8(transitive)
+ Addedto-fast-properties@1.0.3(transitive)
+ Addedto-object-path@0.3.0(transitive)
+ Addedto-regex@3.0.2(transitive)
+ Addedto-regex-range@2.1.1(transitive)
+ Addedtrim-right@1.0.1(transitive)
+ Addedtry-resolve@1.0.1(transitive)
+ Addedtryor@0.1.2(transitive)
+ Addedunion-value@1.0.1(transitive)
+ Addedunset-value@1.0.0(transitive)
+ Addedurix@0.1.0(transitive)
+ Addeduse@3.1.1(transitive)
+ Addeduser-home@1.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwindow-size@0.1.4(transitive)
+ Addedwordwrap@0.0.2(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedy18n@3.2.2(transitive)
+ Addedyargs@3.27.0(transitive)
- Removedesprima-fb@14001.1.0-dev-harmony-fb(transitive)