Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

deamdify

Package Overview
Dependencies
Maintainers
2
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

deamdify - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

support.js

478

index.js

@@ -8,3 +8,5 @@ /**

, escodegen = require('escodegen')
, util = require('util');
, path = require('path')
, util = require('util')
, support = require('./support');

@@ -28,90 +30,149 @@

*/
module.exports = function (file) {
module.exports = function (file, options) {
var data = '';
var ext = path.extname(file);
options = options || {};
var stream = through(write, end);
return stream;
function write(buf) { data += buf }
function end() {
var ast = esprima.parse(data)
var ast
, tast
, isAMD = false;
//console.log('-- ORIGINAL AST --');
//console.log(util.inspect(ast, false, null));
//console.log('------------------');
// TODO: Ensure that define is a free variable.
// TODO: Implement support for amdWeb UMD modules.
estraverse.replace(ast, {
enter: function(node) {
if (isDefine(node)) {
var parents = this.parents();
// Check that this module is an AMD module, as evidenced by invoking
// `define` at the top-level. Any CommonJS or UMD modules are pass
// through unmodified.
if (parents.length == 2 && parents[0].type == 'Program' && parents[1].type == 'ExpressionStatement') {
isAMD = true;
, isAMD = false
, isUMD = false
, supportsCommonJs = false;
if (ext.toLowerCase() === '.js') {
try {
ast = esprima.parse(data)
} catch (error) {
throw new Error('Error deamdifying ' + file + ': ' + error);
}
//console.log('-- ORIGINAL AST --');
//console.log(util.inspect(ast, false, null));
//console.log('------------------');
// TODO: Ensure that define is a free variable.
estraverse.replace(ast, {
enter: function(node) {
if (isCommonJsCheck(node)) {
supportsCommonJs = true;
}
}
},
leave: function(node) {
if (isDefine(node)) {
if (node.arguments.length == 1 && node.arguments[0].type == 'FunctionExpression') {
var factory = node.arguments[0];
if (factory.params.length == 0) {
tast = createProgram(factory.body.body);
else if (!supportsCommonJs && isAMDCheck(node)) {
node.test = { type: 'Literal', value: true, raw: 'true' };
node.alternate = null;
isUMD = true;
}
else if (isDefine(node) || isAMDRequire(node)) {
if (isUMD) {
isAMD = true;
return;
}
var parents = this.parents();
// Check that this module is an AMD module, as evidenced by invoking
// `define` or `require([], fn)` at the top-level. Any CommonJS or
// UMD modules are pass through unmodified.`
if (parents.length == 2 && parents[0].type == 'Program' && parents[1].type == 'ExpressionStatement') {
isAMD = true;
}
}
},
leave: function(node) {
if (isAMD && (isDefine(node) || isAMDRequire(node))) {
//define({})
if (node.arguments.length == 1 &&
node.arguments[0].type == 'ObjectExpression') {
// object literal
var obj = node.arguments[0];
tast = generateCommonJsModuleForObject(obj);
this.break();
} else if (factory.params.length > 0) {
// simplified CommonJS wrapper
tast = createProgram(factory.body.body);
} else
//define(function(){})
if (node.arguments.length == 1 &&
node.arguments[0].type == 'FunctionExpression') {
var dependenciesIds = extractDependencyIdsFromFactory(node.arguments[0]),
factory = node.arguments[0];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} else
//define(variableName)
if (node.arguments.length == 1 &&
node.arguments[0].type == 'Identifier') {
// reference
var obj = node.arguments[0];
return generateCommonJsModuleForObject(obj).expression;
} else
//define([],function(){})
if (node.arguments.length == 2 &&
node.arguments[0].type == 'ArrayExpression' &&
node.arguments[1].type == 'FunctionExpression') {
var dependenciesIds = extractDependencyIdsFromArrayExpression(node.arguments[0], options.paths)
, factory = node.arguments[1];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} else
//define("a b c".split(' '), function(){})
if (node.arguments.length == 2 &&
node.arguments[0].type == 'CallExpression' &&
node.arguments[1].type == 'FunctionExpression') {
try {
var dependenciesCode = node.arguments[0]
, dependenciesIds = extractDependencyIdsFromCallExpression(dependenciesCode, options.paths)
, factory = node.arguments[1];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} catch(e) {
console.log("failed to evaluate dependencies:", dependenciesCode, e)
}
} else
//define('modulename',function(){})
if (node.arguments.length == 2 &&
node.arguments[0].type == 'Literal' &&
node.arguments[1].type == 'FunctionExpression') {
var dependenciesIds = extractDependencyIdsFromFactory(node.arguments[1])
, factory = node.arguments[1];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} else
//define('modulename', [], function(){})
if (node.arguments.length == 3 &&
node.arguments[0].type == 'Literal' &&
node.arguments[1].type == 'ArrayExpression' &&
node.arguments[2].type == 'FunctionExpression') {
var dependenciesIds = extractDependencyIdsFromArrayExpression(node.arguments[1], options.paths)
, factory = node.arguments[2];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} else
//define('modulename', "a b c".split(' '), function(){})
if (node.arguments.length == 3 &&
node.arguments[0].type == 'Literal' &&
node.arguments[1].type == 'CallExpression' &&
node.arguments[2].type == 'FunctionExpression') {
try {
var dependenciesCode = node.arguments[1]
, dependenciesIds = extractDependencyIdsFromCallExpression(dependenciesCode, options.paths)
, factory = node.arguments[2];
tast = generateCommonJsModuleForFactory(dependenciesIds, factory);
this.break();
} catch(e) {
console.log("failed to evaluate dependencies:", dependenciesCode, e)
}
}
} else if (node.arguments.length == 1 && node.arguments[0].type == 'ObjectExpression') {
// object literal
var obj = node.arguments[0];
tast = createModuleExport(obj);
this.break();
} else if (node.arguments.length == 2 && node.arguments[0].type == 'ArrayExpression' && node.arguments[1].type == 'FunctionExpression') {
var dependencies = node.arguments[0]
, factory = node.arguments[1];
var ids = dependencies.elements.map(function(el) { return el.value });
var vars = factory.params.map(function(el) { return el.name });
var reqs = createRequires(ids, vars);
if (reqs) {
tast = createProgram([reqs].concat(factory.body.body));
} else {
tast = createProgram(factory.body.body);
}
this.break();
} else if (node.arguments.length == 3 && node.arguments[0].type == 'Literal' && node.arguments[1].type == 'ArrayExpression' && node.arguments[2].type == 'FunctionExpression') {
var dependencies = node.arguments[1]
, factory = node.arguments[2];
var ids = dependencies.elements.map(function(el) { return el.value });
var vars = factory.params.map(function(el) { return el.name });
var reqs = createRequires(ids, vars);
if (reqs) {
tast = createProgram([reqs].concat(factory.body.body));
} else {
tast = createProgram(factory.body.body);
}
this.break();
}
} else if (isReturn(node)) {
var parents = this.parents();
if (parents.length == 5 && isDefine(parents[2]) && isAMD) {
return createModuleExport(node.argument);
}
}
}
});
});
}
if (!isAMD) {

@@ -122,9 +183,9 @@ stream.queue(data);

}
tast = tast || ast;
//console.log('-- TRANSFORMED AST --');
//console.log(util.inspect(tast, false, null));
//console.log('---------------------');
var out = escodegen.generate(tast);

@@ -136,3 +197,175 @@ stream.queue(out);

function generateCommonJsModuleForObject(obj) {
return { type: 'ExpressionStatement',
expression:
{ type: 'AssignmentExpression',
operator: '=',
left:
{ type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'module' },
property: { type: 'Identifier', name: 'exports' } },
right: obj } };
}
function extractDependencyIdsFromArrayExpression(dependencies, paths) {
return dependencies.elements.map(function(el) { return rewriteRequire(el.value, paths); });
}
function extractDependencyIdsFromCallExpression(callExpression, paths) {
var ids = eval(escodegen.generate(callExpression));
return ids.map(function(id) { return rewriteRequire(id, paths); });
}
function rewriteRequire(path, paths) {
var parts = path.split("/");
var module = parts[0];
if(paths && module in paths) {
var rest = parts.slice(1, parts.length);
var rewrittenModule = paths[module];
return [rewrittenModule].concat(rest).join("/")
} else {
return path;
}
}
function extractDependencyIdsFromFactory(factory) {
var parameters = factory.params.map(function(param){
if(param.type === 'Identifier') {
return param.name;
}
});
if(isCommonJsWrappingParameters(parameters)) {
return [];
} else {
return commonJsSpecialDependencies.slice(0, parameters.length);
}
}
function isCommonJsWrappingParameters(parameters) {
return parameters.length === commonJsSpecialDependencies.length
&& parameters[0] === commonJsSpecialDependencies[0]
&& parameters[1] === commonJsSpecialDependencies[1]
&& parameters[2] === commonJsSpecialDependencies[2];
}
function generateCommonJsModuleForFactory(dependenciesIds, factory) {
var program,
exportResult = support.doesFactoryHaveReturn(factory);
if(dependenciesIds.length === 0 && !exportResult) {
program = factory.body.body;
} else {
var importExpressions = [];
//build imports
var imports;
if(dependenciesIds.length > 0) {
buildDependencyExpressions(dependenciesIds).forEach(function(expressions){
importExpressions.push(expressions.importExpression);
});
}
var callFactoryWithImports = {
"type": "CallExpression",
"callee": factory,
"arguments": importExpressions
};
var body;
if(exportResult) {
//wrap with assignment
body = {
"type": "ExpressionStatement",
"expression":{
"type": "AssignmentExpression",
"operator": "=",
"left": {
"type": "MemberExpression",
"computed": false,
"object": {
"type": "Identifier",
"name": "module"
},
"property": {
"type": "Identifier",
"name": "exports"
}
},
"right": callFactoryWithImports
}
};
} else {
body = {
"type": "ExpressionStatement",
"expression": callFactoryWithImports
};
}
//program
program = [body];
}
return { type: 'Program',
body: program };
}
//NOTE: this is the order as specified in RequireJS docs; don't changes
var commonJsSpecialDependencies = ['require', 'exports', 'module'];
function commonJsSpecialDependencyExpressionBuilder(dependencyId) {
if(commonJsSpecialDependencies.indexOf(dependencyId) !== -1) {
return {importExpression:{
"type": "Identifier",
"name": dependencyId
}
};
}
}
function defaultRequireDependencyExpressionBuilder(dependencyId) {
return {importExpression: {
"type": "CallExpression",
"callee": {
"type": "Identifier",
"name": "require"
},
"arguments": [
{
"type": "Literal",
"value": dependencyId
}
]
}};
}
function buildDependencyExpressions(dependencyIdList) {
var dependencyExpressionBuilders = [
commonJsSpecialDependencyExpressionBuilder,
defaultRequireDependencyExpressionBuilder
];
return dependencyIdList.map(function(dependencyId){
return dependencyExpressionBuilders.reduce(function(currentExpression, builder){
return currentExpression || builder(dependencyId);
}, null);
});
}
function buildVariableDeclaration(imports, loader) {
var declarations = [];
if (imports) {
declarations.push(imports);
}
declarations.push(loader);
return {
"type": "VariableDeclaration",
"declarations": declarations,
"kind": "var"
};
}
function isDefine(node) {

@@ -147,43 +380,58 @@ var callee = node.callee;

function isReturn(node) {
return node.type == 'ReturnStatement';
}
function isCommonJsCheck(node) {
if (typeof exports === 'object')
return node.type === 'IfStatement' &&
isTypeCheck(node.test);
function createProgram(body) {
return { type: 'Program',
body: body };
function isTypeCheck(node) {
return node.type === 'BinaryExpression' &&
(node.operator === '===' || node.operator === '==') &&
isTypeof(node.left) &&
node.right.type === 'Literal' &&
node.right.value === 'object';
}
function isTypeof(node) {
return node.type === 'UnaryExpression' &&
node.operator === 'typeof' &&
node.argument.type === 'Identifier' &&
node.argument.name === 'exports';
}
}
function createRequires(ids, vars) {
var decls = [];
for (var i = 0, len = ids.length; i < len; ++i) {
if (['require', 'module', 'exports'].indexOf(ids[i]) != -1) { continue; }
decls.push({ type: 'VariableDeclarator',
id: { type: 'Identifier', name: vars[i] },
init:
{ type: 'CallExpression',
callee: { type: 'Identifier', name: 'require' },
arguments: [ { type: 'Literal', value: ids[i] } ] } });
function isAMDCheck(node) {
return node.type === 'IfStatement' &&
node.test.type === 'LogicalExpression' &&
isTypeCheck(node.test.left) &&
isAmdPropertyCheck(node.test.right);
function isTypeCheck(node) {
return node.type === 'BinaryExpression' &&
(node.operator === '===' || node.operator === '==') &&
isTypeof(node.left) &&
node.right.type === 'Literal' &&
node.right.value === 'function';
}
if (decls.length == 0) { return null; }
return { type: 'VariableDeclaration',
declarations: decls,
kind: 'var' };
function isTypeof(node) {
return node.type === 'UnaryExpression' &&
node.operator === 'typeof' &&
node.argument.type === 'Identifier' &&
node.argument.name === 'define';
}
function isAmdPropertyCheck(node) {
return node.type === 'MemberExpression' &&
node.object.name === 'define' &&
node.property.name === 'amd';
}
}
function createModuleExport(obj) {
return { type: 'ExpressionStatement',
expression:
{ type: 'AssignmentExpression',
operator: '=',
left:
{ type: 'MemberExpression',
computed: false,
object: { type: 'Identifier', name: 'module' },
property: { type: 'Identifier', name: 'exports' } },
right: obj } };
function isAMDRequire(node) {
var callee = node.callee;
return callee
&& node.type == 'CallExpression'
&& callee.type == 'Identifier'
&& callee.name == 'require'
;
}
{
"name": "deamdify",
"version": "0.1.1",
"version": "0.2.0",
"description": "Browserify transform that converts AMD to CommonJS.",

@@ -31,13 +31,18 @@ "keywords": [

"dependencies": {
"through": "2.x.x",
"esprima": "1.x.x",
"estraverse": "1.x.x",
"escodegen": "0.0.x"
"through": "^2.3.7",
"esprima": "^2.1.0",
"estraverse": "^3.1.0",
"escodegen": "^1.6.1"
},
"devDependencies": {
"mocha": "1.x.x",
"chai": "1.x.x"
"chai": "^2.2.0",
"mocha": "^2.2.4",
"test-peer-range": "^1.0.1"
},
"peerDependencies": {
"browserify": ">= 2"
},
"scripts": {
"test": "NODE_PATH=.. node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js"
"test": "test-peer-range browserify",
"test-main": "mocha --reporter spec --require test/bootstrap/node test/*.test.js"
},

@@ -44,0 +49,0 @@ "engines": {

# deAMDify
[![Build Status](https://secure.travis-ci.org/jaredhanson/deamdify.png)](http://travis-ci.org/jaredhanson/deamdify) [![David DM](https://david-dm.org/jaredhanson/deamdify.png)](http://david-dm.org/jaredhanson/deamdify)
This module is a [browserify](http://browserify.org/) plugin that will transform

@@ -11,5 +14,11 @@ [AMD](https://github.com/amdjs) modules into [Node.js](http://nodejs.org/)-style

**For when you're stuck and need help:**
[![Join the chat at https://gitter.im/jaredhanson/deamdify](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jaredhanson/deamdify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Install
$ npm install deamdify
```sh
$ npm install deamdify
```

@@ -23,3 +32,5 @@ ## Usage

browserify -t deamdify main.js -o bundle.js
```sh
browserify -t deamdify main.js -o bundle.js
```

@@ -38,9 +49,28 @@ #### API

#### package.json
For packages that are written as AMD modules, add a browserify transform field
to `package.json` and browserify will apply the transform to all modules in the
package as it builds a bundle.
```
{
"name": "anchor",
"main": "main",
"browserify": {
"transform": "deamdify"
}
}
```
## Tests
$ npm install
$ make test
```sh
$ npm install
# fast run
$ npm run test-main
# test all browserify major versions
$ npm test
```
[![Build Status](https://secure.travis-ci.org/jaredhanson/deamdify.png)](http://travis-ci.org/jaredhanson/deamdify) [![David DM](https://david-dm.org/jaredhanson/deamdify.png)](http://david-dm.org/jaredhanson/deamdify)
## Credits

@@ -54,2 +84,2 @@

Copyright (c) 2013 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>
Copyright (c) 2015 Jared Hanson <[http://jaredhanson.net/](http://jaredhanson.net/)>

Sorry, the diff of this file is not supported yet

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