Socket
Socket
Sign inDemoInstall

espurify

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

espurify - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

lib/clone-ast.js

533

build/espurify.js

@@ -13,73 +13,14 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.espurify = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw (f.code="MODULE_NOT_FOUND", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){

var traverse = _dereq_('traverse'),
indexOf = _dereq_('indexof'),
deepCopy = _dereq_('./lib/ast-deepcopy'),
astProps = _dereq_('./lib/ast-properties'),
hasOwn = Object.prototype.hasOwnProperty;
var createWhitelist = _dereq_('./lib/create-whitelist');
var cloneWithWhitelist = _dereq_('./lib/clone-ast');
function espurify (node) {
var result = deepCopy(node);
traverse(result).forEach(function (x) {
if (this.parent &&
this.parent.node &&
this.parent.node.type &&
isSupportedNodeType(this.parent.node.type) &&
!isSupportedKey(this.parent.node.type, this.key))
{
this.remove(true);
}
});
return result;
function createCloneFunction (options) {
return cloneWithWhitelist(createWhitelist(options));
}
function isSupportedNodeType (type) {
return hasOwn.call(astProps, type);
}
function isSupportedKey (type, key) {
return indexOf(astProps[type], key) !== -1;
}
var espurify = createCloneFunction();
espurify.customize = createCloneFunction;
module.exports = espurify;
},{"./lib/ast-deepcopy":2,"./lib/ast-properties":3,"indexof":4,"traverse":5}],2:[function(_dereq_,module,exports){
/**
* Copyright (C) 2012 Yusuke Suzuki (twitter: @Constellation) and other contributors.
* Released under the BSD license.
* https://github.com/Constellation/esmangle/blob/master/LICENSE.BSD
*/
'use strict';
var isArray = Array.isArray || function isArray (array) {
return Object.prototype.toString.call(array) === '[object Array]';
};
function deepCopyInternal (obj, result) {
var key, val;
for (key in obj) {
if (key.lastIndexOf('_', 0) === 0) {
continue;
}
if (obj.hasOwnProperty(key)) {
val = obj[key];
if (typeof val === 'object' && val !== null) {
if (val instanceof RegExp) {
val = new RegExp(val);
} else {
val = deepCopyInternal(val, isArray(val) ? [] : {});
}
}
result[key] = val;
}
}
return result;
}
function deepCopy (obj) {
return deepCopyInternal(obj, isArray(obj) ? [] : {});
}
module.exports = deepCopy;
},{}],3:[function(_dereq_,module,exports){
},{"./lib/clone-ast":3,"./lib/create-whitelist":4}],2:[function(_dereq_,module,exports){
module.exports = {

@@ -153,331 +94,203 @@ ArrayExpression: ['type', 'elements'],

},{}],4:[function(_dereq_,module,exports){
},{}],3:[function(_dereq_,module,exports){
'use strict';
var indexOf = [].indexOf;
var isArray = _dereq_('isarray');
module.exports = function(arr, obj){
if (indexOf) return arr.indexOf(obj);
for (var i = 0; i < arr.length; ++i) {
if (arr[i] === obj) return i;
}
return -1;
};
},{}],5:[function(_dereq_,module,exports){
var traverse = module.exports = function (obj) {
return new Traverse(obj);
};
module.exports = function cloneWithWhitelist (whitelist) {
function Traverse (obj) {
this.value = obj;
}
function cloneRoot (ast) {
return cloneContainer({}, ast);
}
Traverse.prototype.get = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i ++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
node = undefined;
break;
function cloneContainer (collector, obj) {
if (isArray(obj)) {
return cloneArray(collector, obj);
} else if (obj.type && whitelist[obj.type]) {
return cloneNode(collector, obj);
} else {
return cloneObj(collector, obj);
}
node = node[key];
}
return node;
};
Traverse.prototype.has = function (ps) {
var node = this.value;
for (var i = 0; i < ps.length; i ++) {
var key = ps[i];
if (!node || !hasOwnProperty.call(node, key)) {
return false;
function cloneArray (collector, ary) {
var i, len;
for (i = 0, len = ary.length; i < len; i += 1) {
collector.push(cloneOf(ary[i]));
}
node = node[key];
return collector;
}
return true;
};
Traverse.prototype.set = function (ps, value) {
var node = this.value;
for (var i = 0; i < ps.length - 1; i ++) {
var key = ps[i];
if (!hasOwnProperty.call(node, key)) node[key] = {};
node = node[key];
function cloneNode (collector, obj) {
var i, len, props = whitelist[obj.type];
for (i = 0, len = props.length; i < len; i += 1) {
cloneProperty(collector, obj, props[i]);
}
return collector;
}
node[ps[i]] = value;
return value;
};
Traverse.prototype.map = function (cb) {
return walk(this.value, cb, true);
};
function cloneObj (collector, obj) {
var key;
for (key in obj) {
cloneProperty(collector, obj, key);
}
return collector;
}
Traverse.prototype.forEach = function (cb) {
this.value = walk(this.value, cb, false);
return this.value;
};
function cloneProperty (collector, obj, key) {
if (obj.hasOwnProperty(key)) {
collector[key] = cloneOf(obj[key]);
}
}
Traverse.prototype.reduce = function (cb, init) {
var skip = arguments.length === 1;
var acc = skip ? this.value : init;
this.forEach(function (x) {
if (!this.isRoot || !skip) {
acc = cb.call(this, acc, x);
function cloneOf (val) {
if (typeof val === 'object' && val !== null) {
if (val instanceof RegExp) {
return new RegExp(val);
} else {
return cloneContainer(isArray(val) ? [] : {}, val);
}
} else {
return val;
}
});
return acc;
};
}
Traverse.prototype.paths = function () {
var acc = [];
this.forEach(function (x) {
acc.push(this.path);
});
return acc;
return cloneRoot;
};
Traverse.prototype.nodes = function () {
var acc = [];
this.forEach(function (x) {
acc.push(this.node);
});
return acc;
},{"isarray":5}],4:[function(_dereq_,module,exports){
'use strict';
var defaultProps = _dereq_('./ast-properties');
var objectKeys = _dereq_('object-keys');
var extend = _dereq_('xtend');
module.exports = function createWhitelist (options) {
var opts = extend({}, options);
var typeName, i, len;
var keys = objectKeys(defaultProps);
var result = {};
for (i = 0, len = keys.length; i < len; i += 1) {
typeName = keys[i];
result[typeName] = [].concat(defaultProps[typeName]).concat(opts.extra);
}
return result;
};
Traverse.prototype.clone = function () {
var parents = [], nodes = [];
return (function clone (src) {
for (var i = 0; i < parents.length; i++) {
if (parents[i] === src) {
return nodes[i];
}
}
if (typeof src === 'object' && src !== null) {
var dst = copy(src);
parents.push(src);
nodes.push(dst);
forEach(objectKeys(src), function (key) {
dst[key] = clone(src[key]);
});
parents.pop();
nodes.pop();
return dst;
}
else {
return src;
}
})(this.value);
},{"./ast-properties":2,"object-keys":6,"xtend":8}],5:[function(_dereq_,module,exports){
module.exports = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
function walk (root, cb, immutable) {
var path = [];
var parents = [];
var alive = true;
return (function walker (node_) {
var node = immutable ? copy(node_) : node_;
var modifiers = {};
var keepGoing = true;
var state = {
node : node,
node_ : node_,
path : [].concat(path),
parent : parents[parents.length - 1],
parents : parents,
key : path.slice(-1)[0],
isRoot : path.length === 0,
level : path.length,
circular : null,
update : function (x, stopHere) {
if (!state.isRoot) {
state.parent.node[state.key] = x;
}
state.node = x;
if (stopHere) keepGoing = false;
},
'delete' : function (stopHere) {
delete state.parent.node[state.key];
if (stopHere) keepGoing = false;
},
remove : function (stopHere) {
if (isArray(state.parent.node)) {
state.parent.node.splice(state.key, 1);
}
else {
delete state.parent.node[state.key];
}
if (stopHere) keepGoing = false;
},
keys : null,
before : function (f) { modifiers.before = f },
after : function (f) { modifiers.after = f },
pre : function (f) { modifiers.pre = f },
post : function (f) { modifiers.post = f },
stop : function () { alive = false },
block : function () { keepGoing = false }
};
if (!alive) return state;
function updateState() {
if (typeof state.node === 'object' && state.node !== null) {
if (!state.keys || state.node_ !== state.node) {
state.keys = objectKeys(state.node)
}
state.isLeaf = state.keys.length == 0;
for (var i = 0; i < parents.length; i++) {
if (parents[i].node_ === node_) {
state.circular = parents[i];
break;
}
}
}
else {
state.isLeaf = true;
state.keys = null;
}
state.notLeaf = !state.isLeaf;
state.notRoot = !state.isRoot;
}
updateState();
// use return values to update if defined
var ret = cb.call(state, state.node);
if (ret !== undefined && state.update) state.update(ret);
if (modifiers.before) modifiers.before.call(state, state.node);
if (!keepGoing) return state;
if (typeof state.node == 'object'
&& state.node !== null && !state.circular) {
parents.push(state);
updateState();
forEach(state.keys, function (key, i) {
path.push(key);
if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
var child = walker(state.node[key]);
if (immutable && hasOwnProperty.call(state.node, key)) {
state.node[key] = child.node;
}
child.isLast = i == state.keys.length - 1;
child.isFirst = i == 0;
if (modifiers.post) modifiers.post.call(state, child);
path.pop();
});
parents.pop();
}
if (modifiers.after) modifiers.after.call(state, state.node);
return state;
})(root).node;
}
},{}],6:[function(_dereq_,module,exports){
'use strict';
function copy (src) {
if (typeof src === 'object' && src !== null) {
var dst;
if (isArray(src)) {
dst = [];
}
else if (isDate(src)) {
dst = new Date(src.getTime ? src.getTime() : src);
}
else if (isRegExp(src)) {
dst = new RegExp(src);
}
else if (isError(src)) {
dst = { message: src.message };
}
else if (isBoolean(src)) {
dst = new Boolean(src);
}
else if (isNumber(src)) {
dst = new Number(src);
}
else if (isString(src)) {
dst = new String(src);
}
else if (Object.create && Object.getPrototypeOf) {
dst = Object.create(Object.getPrototypeOf(src));
}
else if (src.constructor === Object) {
dst = {};
}
else {
var proto =
(src.constructor && src.constructor.prototype)
|| src.__proto__
|| {}
;
var T = function () {};
T.prototype = proto;
dst = new T;
}
forEach(objectKeys(src), function (key) {
dst[key] = src[key];
});
return dst;
}
else return src;
}
// modified from https://github.com/es-shims/es5-shim
var has = Object.prototype.hasOwnProperty;
var toStr = Object.prototype.toString;
var isArgs = _dereq_('./isArguments');
var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString');
var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype');
var dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
];
var objectKeys = Object.keys || function keys (obj) {
var res = [];
for (var key in obj) res.push(key)
return res;
};
var keysShim = function keys(object) {
var isObject = object !== null && typeof object === 'object';
var isFunction = toStr.call(object) === '[object Function]';
var isArguments = isArgs(object);
var isString = isObject && toStr.call(object) === '[object String]';
var theKeys = [];
function toS (obj) { return Object.prototype.toString.call(obj) }
function isDate (obj) { return toS(obj) === '[object Date]' }
function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
function isError (obj) { return toS(obj) === '[object Error]' }
function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
function isNumber (obj) { return toS(obj) === '[object Number]' }
function isString (obj) { return toS(obj) === '[object String]' }
if (!isObject && !isFunction && !isArguments) {
throw new TypeError('Object.keys called on a non-object');
}
var isArray = Array.isArray || function isArray (xs) {
return Object.prototype.toString.call(xs) === '[object Array]';
var skipProto = hasProtoEnumBug && isFunction;
if (isString && object.length > 0 && !has.call(object, 0)) {
for (var i = 0; i < object.length; ++i) {
theKeys.push(String(i));
}
}
if (isArguments && object.length > 0) {
for (var j = 0; j < object.length; ++j) {
theKeys.push(String(j));
}
} else {
for (var name in object) {
if (!(skipProto && name === 'prototype') && has.call(object, name)) {
theKeys.push(String(name));
}
}
}
if (hasDontEnumBug) {
var ctor = object.constructor;
var skipConstructor = ctor && ctor.prototype === object;
for (var k = 0; k < dontEnums.length; ++k) {
if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
theKeys.push(dontEnums[k]);
}
}
}
return theKeys;
};
var forEach = function (xs, fn) {
if (xs.forEach) return xs.forEach(fn)
else for (var i = 0; i < xs.length; i++) {
fn(xs[i], i, xs);
}
keysShim.shim = function shimObjectKeys() {
if (!Object.keys) {
Object.keys = keysShim;
}
return Object.keys || keysShim;
};
forEach(objectKeys(Traverse.prototype), function (key) {
traverse[key] = function (obj) {
var args = [].slice.call(arguments, 1);
var t = new Traverse(obj);
return t[key].apply(t, args);
};
});
module.exports = keysShim;
var hasOwnProperty = Object.hasOwnProperty || function (obj, key) {
return key in obj;
},{"./isArguments":7}],7:[function(_dereq_,module,exports){
'use strict';
var toStr = Object.prototype.toString;
module.exports = function isArguments(value) {
var str = toStr.call(value);
var isArgs = str === '[object Arguments]';
if (!isArgs) {
isArgs = str !== '[object Array]'
&& value !== null
&& typeof value === 'object'
&& typeof value.length === 'number'
&& value.length >= 0
&& toStr.call(value.callee) === '[object Function]';
}
return isArgs;
};
},{}],8:[function(_dereq_,module,exports){
module.exports = extend
function extend() {
var target = {}
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key]
}
}
}
return target
}
},{}]},{},[1])(1)
});

@@ -0,1 +1,9 @@

## [1.2.0](https://github.com/estools/espurify/releases/tag/v1.2.0) (2015-04-17)
#### Features
* [performance optimization](https://github.com/estools/espurify/pull/1)
## [1.1.0](https://github.com/estools/espurify/releases/tag/v1.1.0) (2015-04-12)

@@ -2,0 +10,0 @@

@@ -12,31 +12,11 @@ /**

var traverse = require('traverse'),
indexOf = require('indexof'),
deepCopy = require('./lib/ast-deepcopy'),
astProps = require('./lib/ast-properties'),
hasOwn = Object.prototype.hasOwnProperty;
var createWhitelist = require('./lib/create-whitelist');
var cloneWithWhitelist = require('./lib/clone-ast');
function espurify (node) {
var result = deepCopy(node);
traverse(result).forEach(function (x) {
if (this.parent &&
this.parent.node &&
this.parent.node.type &&
isSupportedNodeType(this.parent.node.type) &&
!isSupportedKey(this.parent.node.type, this.key))
{
this.remove(true);
}
});
return result;
function createCloneFunction (options) {
return cloneWithWhitelist(createWhitelist(options));
}
function isSupportedNodeType (type) {
return hasOwn.call(astProps, type);
}
function isSupportedKey (type, key) {
return indexOf(astProps[type], key) !== -1;
}
var espurify = createCloneFunction();
espurify.customize = createCloneFunction;
module.exports = espurify;
{
"name": "espurify",
"description": "Clone new AST without extra properties",
"version": "1.1.0",
"version": "1.2.0",
"author": {

@@ -12,4 +12,5 @@ "name": "Takuto Wada",

"dependencies": {
"indexof": "0.0.1",
"traverse": "~0.6.6"
"isarray": "^0.0.1",
"object-keys": "^1.0.3",
"xtend": "^4.0.0"
},

@@ -37,4 +38,3 @@ "devDependencies": {

"ecmascript",
"es6",
"esprima"
"es6"
],

@@ -41,0 +41,0 @@ "license": {

@@ -18,3 +18,3 @@ espurify

Leaves properties defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)) only. Also note that location informations (such as `loc` and `range`) are eliminated too.
Leaves properties defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API)) only. Also note that extra informations (such as `loc`, `range` and `raw`) are eliminated too.

@@ -24,2 +24,31 @@ `espurify` supports [ES5](https://github.com/estree/estree/blob/master/spec.md) and [ES6](https://github.com/estree/estree/blob/master/es6.md) properties.

### var customizedCloneFunction = espurify.customize(options)
Returns customized function for cloning AST, configured by custom `options`.
### var purifiedAstClone = customizedCloneFunction(originalAst)
Returns new clone of `originalAst` by customized function.
#### options
| type | default value |
|:---------|:--------------|
| `object` | `{}` |
Configuration options. If not passed, default options will be used.
#### options.extra
| type | default value |
|:--------------------|:--------------|
| `array` of `string` | null |
List of extra properties to be left in result AST. For example, functions returned by `espurify.customize({extra: ['raw']})` will preserve `raw` properties of `Literal`. Functions return by `espurify.customize({extra: ['loc', 'range']})` will preserve `loc` and `range` properties of each Node.
EXAMPLE

@@ -26,0 +55,0 @@ ---------------------------------------

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