🚀 Socket Launch Week 🚀 Day 4: Introducing Historical Analytics.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-jsx-to-handlebars

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-jsx-to-handlebars - npm Package Compare versions

Comparing version

to
0.1.4

tests/post-babel-classes/class-test.js

196

dist/plugin.dist.js

@@ -24,2 +24,17 @@ 'use strict';

},
FunctionExpression: {
enter: function enter() {
if (this.get('id').node !== null && this.get('id').get('name').node == 'render') {
findVariablesInJSX(this);
}
},
exit: function exit() {
if (this.get('id').node !== null && this.get('id').get('name').node == 'render') {
processRenderFunction(this, this.get('body').node);
this.findParent(function (path) {
return path.isVariableDeclaration();
}).dangerouslyRemove();
}
}
},
ClassDeclaration: {

@@ -32,25 +47,10 @@ exit: function exit() {

enter: function enter() {
findVariablesInJSX(this);
if (this.get('key').get('name').node == 'render') {
findVariablesInJSX(this);
}
},
exit: function exit(node) {
var methodBody = node.value.body;
// Prepend context and context.props wrapper to function body
var contextIdentifier = t.identifier('context');
methodBody.body = Array.prototype.concat([t.variableDeclaration('var', [t.variableDeclarator(localContextRef, t.objectExpression([]))]), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, 'props'), t.callExpression(createMemberExpression('Object', 'assign'), [findDefaultPropsIfAny(this), createMemberExpression('execOptions', 'hash'), createMemberExpression(t.logicalExpression('||', createMemberExpression('execOptions', 'hash'), t.objectExpression([])), '__$spread$__')]))),
// localContext.props.children = new Handlebars.SafeString(execOptions.data['partial-block'](context));
t.ifStatement(t.unaryExpression('!', createMemberExpression('execOptions', 'data', 'partial-block')), t.blockStatement([t.throwStatement(t.newExpression(t.identifier('Error'), [t.literal('Calling partials is only valid as block-partial')]))])), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, 'props', 'children'), t.newExpression(createMemberExpression('Handlebars', 'SafeString'), [t.callExpression(createMemberExpression('execOptions', 'data', 'partial-block'), [contextIdentifier])])))], methodBody.body);
var programPath = findProgramPath(this);
var classID = findClassDeclaration(this).get('id').get('name').node;
// export default function...
programPath.node.body.push(t.functionDeclaration(t.identifier(classID), // id
[], // params
t.blockStatement([t.expressionStatement(t.callExpression(createMemberExpression('Handlebars', 'registerPartial'), [t.literal(classID), t.functionExpression(undefined, // id
[// params
contextIdentifier, t.identifier('execOptions')], methodBody, false, // generator
false // async
)]))]), false, // generator
false // async
), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(t.identifier(classID), 'handlebars-partial'), t.literal(true))), t.exportDefaultDeclaration(t.identifier(classID)));
exit: function exit() {
if (this.get('key').get('name').node == 'render') {
processRenderFunction(this, this.get('value').get('body').node);
}
}

@@ -80,2 +80,30 @@ },

function processRenderFunction(path, node) {
// Prepend context and context.props wrapper to function body
var contextIdentifier = t.identifier('context');
node.body = Array.prototype.concat([t.variableDeclaration('var', [t.variableDeclarator(localContextRef, t.objectExpression([]))]), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, 'props'), t.callExpression(createMemberExpression('Object', 'assign'), [findDefaultPropsIfAny(path), createMemberExpression('execOptions', 'hash'), createMemberExpression(t.logicalExpression('||', createMemberExpression('execOptions', 'hash'), t.objectExpression([])), '__$spread$__')]))),
// localContext.props.children = new Handlebars.SafeString(execOptions.data['partial-block'](context));
t.ifStatement(t.unaryExpression('!', createMemberExpression('execOptions', 'data', 'partial-block')), t.blockStatement([t.throwStatement(t.newExpression(t.identifier('Error'), [t.literal('Calling partials is only valid as block-partial')]))])), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, 'props', 'children'), t.newExpression(createMemberExpression('Handlebars', 'SafeString'), [t.callExpression(createMemberExpression('execOptions', 'data', 'partial-block'), [contextIdentifier])])))], node.body);
var programPath = findProgramPath(path);
var decl = findClassDeclaration(path);
var classID = undefined;
if (decl) {
classID = decl.get('id').get('name').node;
} else {
decl = findBabelClassDeclaration(path);
classID = decl.get('arguments')[0].get('name').node;
}
// export default function...
programPath.node.body.push(t.functionDeclaration(t.identifier(classID), // id
[], // params
t.blockStatement([t.expressionStatement(t.callExpression(createMemberExpression('Handlebars', 'registerPartial'), [t.literal(classID), t.functionExpression(undefined, // id
[// params
contextIdentifier, t.identifier('execOptions')], node, false, // generator
false // async
)]))]), false, // generator
false // async
), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(t.identifier(classID), 'handlebars-partial'), t.literal(true))), t.exportDefaultDeclaration(t.identifier(classID)));
}
function findVariablesInJSX(path) {

@@ -191,2 +219,6 @@ path.traverse({

function processAttributesWithSpread(attributes, tagName, renderAsPartial) {
if (attributes.length == 0) {
return '';
}
var objects = [];

@@ -230,3 +262,3 @@ var _iteratorNormalCompletion = true;

var ref = attributes[0].scope.generateUidIdentifier('_' + tagName + '_attributes_');
var ref = findProgramPath(attributes[0]).scope.generateUidIdentifier('_' + tagName + '_attributes_');
findClosestStatement(attributes[0]).insertBefore([t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, ref.name), t.arrayExpression(objects))), t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, ref.name), t.callExpression(createMemberExpression('Object', 'assign'), [t.objectExpression([]), t.spreadElement(createMemberExpression(localContextRef, ref.name))])))]);

@@ -237,3 +269,3 @@

}
findClosestStatement(attributes[0]).insertBefore(t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, ref.name), t.callExpression(createMemberExpression(t.callExpression(createMemberExpression(t.callExpression(createMemberExpression('Object', 'keys'), [createMemberExpression(localContextRef, ref.name)]), 'filter'), [t.functionExpression(null, [t.identifier('key')], t.blockStatement([t.returnStatement(t.logicalExpression('&&', t.logicalExpression('!=', t.identifier('key'), t.literal('children')), t.logicalExpression('!=', t.identifier('key'), t.literal('__$spread$__'))))]))]), 'reduce'), [t.functionExpression(null, [t.identifier('props'), t.identifier('key')], t.blockStatement([t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('props'), t.identifier('key'), true), t.memberExpression(createMemberExpression(localContextRef, ref.name), t.identifier('key'), true))), t.returnStatement(t.identifier('props'))])), t.objectExpression([])]))));
createFilterSpreadAndChildrenAttributes(attributes[0], ref);
return '{{#each ' + ref.name + '}} {{@key}}="{{this}}"{{/each}}';

@@ -447,12 +479,108 @@ }

function findBabelClassDeclaration(path) {
return path.findParent(function (path) {
return path.isCallExpression() && path.get('callee').get('name').node == '_createClass';
});
}
function findDefaultPropsIfAny(path) {
path = findClassDeclaration(path);
var defaultPropsPath = path.get('body').get('body').filter(function (element) {
return element.isClassProperty();
}).filter(function (element) {
return element.get('key').get('name').node == 'defaultProps';
});
if (defaultPropsPath.length > 0) {
return defaultPropsPath[0].get('value').node;
var decl = findClassDeclaration(path);
var defaultPropsPath = undefined;
if (decl) {
defaultPropsPath = decl.get('body').get('body').filter(function (element) {
return element.isClassProperty();
}).find(function (element) {
return element.get('key').get('name').node == 'defaultProps';
});
} else {
decl = findBabelClassDeclaration(path);
if (decl) {
var args = decl.get('arguments');
if (args.length > 2) {
// Find property with key defaultProps...
var element = undefined;
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = args[2].get('elements')[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var el = _step4.value;
var _iteratorNormalCompletion6 = true;
var _didIteratorError6 = false;
var _iteratorError6 = undefined;
try {
for (var _iterator6 = el.get('properties')[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
var prop = _step6.value;
if (prop.get('key').get('name').node == 'key' && prop.get('value').get('value').node == 'defaultProps') {
element = el;
}
}
} catch (err) {
_didIteratorError6 = true;
_iteratorError6 = err;
} finally {
try {
if (!_iteratorNormalCompletion6 && _iterator6['return']) {
_iterator6['return']();
}
} finally {
if (_didIteratorError6) {
throw _iteratorError6;
}
}
}
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4['return']) {
_iterator4['return']();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
if (element) {
// ... and select value node out of it
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = element.get('properties')[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var prop = _step5.value;
if (prop.get('key').get('name').node == 'value') {
defaultPropsPath = prop;
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5['return']) {
_iterator5['return']();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
}
}
}
}
if (defaultPropsPath) {
return defaultPropsPath.get('value').node;
}
return t.objectExpression([]);

@@ -540,2 +668,6 @@ }

function createFilterSpreadAndChildrenAttributes(attribute, ref) {
findClosestStatement(attribute).insertBefore(t.expressionStatement(t.assignmentExpression('=', createMemberExpression(localContextRef, ref.name), t.callExpression(createMemberExpression(t.callExpression(createMemberExpression(t.callExpression(createMemberExpression('Object', 'keys'), [createMemberExpression(localContextRef, ref.name)]), 'filter'), [t.functionExpression(null, [t.identifier('key')], t.blockStatement([t.returnStatement(t.logicalExpression('&&', t.logicalExpression('!=', t.identifier('key'), t.literal('children')), t.logicalExpression('!=', t.identifier('key'), t.literal('__$spread$__'))))]))]), 'reduce'), [t.functionExpression(null, [t.identifier('props'), t.identifier('key')], t.blockStatement([t.expressionStatement(t.assignmentExpression('=', t.memberExpression(t.identifier('props'), t.identifier('key'), true), t.memberExpression(createMemberExpression(localContextRef, ref.name), t.identifier('key'), true))), t.returnStatement(t.identifier('props'))])), t.objectExpression([])]))));
}
function newVariableReplacement(path) {

@@ -542,0 +674,0 @@ var key = createKeyFromPath(path);

467

lib/plugin.js

@@ -43,2 +43,15 @@ module.exports = function(opts) {

},
FunctionExpression: {
enter() {
if (this.get('id').node !== null && this.get('id').get('name').node == 'render') {
findVariablesInJSX(this);
}
},
exit() {
if (this.get('id').node !== null && this.get('id').get('name').node == 'render') {
processRenderFunction(this, this.get('body').node);
this.findParent(path => path.isVariableDeclaration()).dangerouslyRemove();
}
}
},
ClassDeclaration: {

@@ -51,116 +64,10 @@ exit() {

enter() {
findVariablesInJSX(this);
if (this.get('key').get('name').node == 'render') {
findVariablesInJSX(this);
}
},
exit(node) {
let methodBody = node.value.body;
// Prepend context and context.props wrapper to function body
let contextIdentifier = t.identifier('context');
methodBody.body = Array.prototype.concat(
[
t.variableDeclaration('var', [
t.variableDeclarator(
localContextRef,
t.objectExpression([])
)
]),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, 'props'),
t.callExpression(
createMemberExpression('Object', 'assign'),
[
findDefaultPropsIfAny(this),
createMemberExpression('execOptions', 'hash'),
createMemberExpression(
t.logicalExpression(
'||',
createMemberExpression('execOptions', 'hash'),
t.objectExpression([])
),
'__$spread$__')
]
)
)
),
// localContext.props.children = new Handlebars.SafeString(execOptions.data['partial-block'](context));
t.ifStatement(
t.unaryExpression(
'!',
createMemberExpression('execOptions', 'data', 'partial-block')
),
t.blockStatement([
t.throwStatement(
t.newExpression(
t.identifier('Error'),
[
t.literal('Calling partials is only valid as block-partial')
]
)
)
])
),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, 'props', 'children'),
t.newExpression(
createMemberExpression('Handlebars', 'SafeString'),
[
t.callExpression(
createMemberExpression('execOptions', 'data', 'partial-block'),
[
contextIdentifier
]
)
]
)
)
)
],
methodBody.body
);
let programPath = findProgramPath(this);
let classID = findClassDeclaration(this).get('id').get('name').node;
// export default function...
programPath.node.body.push(
t.functionDeclaration(
t.identifier(classID), // id
[], // params
t.blockStatement([
t.expressionStatement(
t.callExpression(
createMemberExpression('Handlebars', 'registerPartial'),
[
t.literal(classID),
t.functionExpression(
undefined, // id
[ // params
contextIdentifier,
t.identifier('execOptions')
],
methodBody,
false, // generator
false // async
)
]
)
)
]),
false, // generator
false // async
),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(t.identifier(classID), 'handlebars-partial'),
t.literal(true)
)
),
t.exportDefaultDeclaration(
t.identifier(classID)
)
);
exit() {
if (this.get('key').get('name').node == 'render') {
processRenderFunction(this, this.get('value').get('body').node);
}
}

@@ -217,2 +124,121 @@ },

function processRenderFunction(path, node) {
// Prepend context and context.props wrapper to function body
let contextIdentifier = t.identifier('context');
node.body = Array.prototype.concat(
[
t.variableDeclaration('var', [
t.variableDeclarator(
localContextRef,
t.objectExpression([])
)
]),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, 'props'),
t.callExpression(
createMemberExpression('Object', 'assign'),
[
findDefaultPropsIfAny(path),
createMemberExpression('execOptions', 'hash'),
createMemberExpression(
t.logicalExpression(
'||',
createMemberExpression('execOptions', 'hash'),
t.objectExpression([])
),
'__$spread$__')
]
)
)
),
// localContext.props.children = new Handlebars.SafeString(execOptions.data['partial-block'](context));
t.ifStatement(
t.unaryExpression(
'!',
createMemberExpression('execOptions', 'data', 'partial-block')
),
t.blockStatement([
t.throwStatement(
t.newExpression(
t.identifier('Error'),
[
t.literal('Calling partials is only valid as block-partial')
]
)
)
])
),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, 'props', 'children'),
t.newExpression(
createMemberExpression('Handlebars', 'SafeString'),
[
t.callExpression(
createMemberExpression('execOptions', 'data', 'partial-block'),
[
contextIdentifier
]
)
]
)
)
)
],
node.body
);
let programPath = findProgramPath(path);
let decl = findClassDeclaration(path);
let classID;
if (decl) {
classID = decl.get('id').get('name').node;
} else {
decl = findBabelClassDeclaration(path);
classID = decl.get('arguments')[0].get('name').node;
}
// export default function...
programPath.node.body.push(
t.functionDeclaration(
t.identifier(classID), // id
[], // params
t.blockStatement([
t.expressionStatement(
t.callExpression(
createMemberExpression('Handlebars', 'registerPartial'),
[
t.literal(classID),
t.functionExpression(
undefined, // id
[ // params
contextIdentifier,
t.identifier('execOptions')
],
node,
false, // generator
false // async
)
]
)
)
]),
false, // generator
false // async
),
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(t.identifier(classID), 'handlebars-partial'),
t.literal(true)
)
),
t.exportDefaultDeclaration(
t.identifier(classID)
)
);
}
function findVariablesInJSX(path) {

@@ -352,2 +378,6 @@ path.traverse({

function processAttributesWithSpread(attributes, tagName, renderAsPartial) {
if (attributes.length == 0) {
return '';
}
let objects = [];

@@ -379,3 +409,3 @@ for (let attribute of attributes) {

}
let ref = attributes[0].scope.generateUidIdentifier('_' + tagName + '_attributes_');
let ref = findProgramPath(attributes[0]).scope.generateUidIdentifier('_' + tagName + '_attributes_');
findClosestStatement(attributes[0]).insertBefore(

@@ -411,81 +441,3 @@ [

}
findClosestStatement(attributes[0]).insertBefore(
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, ref.name),
t.callExpression(
createMemberExpression(
t.callExpression(
createMemberExpression(
t.callExpression(
createMemberExpression('Object', 'keys'),
[
createMemberExpression(localContextRef, ref.name)
]
),
'filter'
),
[
t.functionExpression(
null,
[
t.identifier('key')
],
t.blockStatement([
t.returnStatement(
t.logicalExpression(
'&&',
t.logicalExpression(
'!=',
t.identifier('key'),
t.literal('children')
),
t.logicalExpression(
'!=',
t.identifier('key'),
t.literal('__$spread$__')
)
)
)
])
)
]
),
'reduce'
),
[
t.functionExpression(
null,
[
t.identifier('props'),
t.identifier('key')
],
t.blockStatement([
t.expressionStatement(
t.assignmentExpression(
'=',
t.memberExpression(
t.identifier('props'),
t.identifier('key'),
true
),
t.memberExpression(
createMemberExpression(localContextRef, ref.name),
t.identifier('key'),
true
)
)
),
t.returnStatement(
t.identifier('props')
)
])
),
t.objectExpression([])
]
)
)
)
);
createFilterSpreadAndChildrenAttributes(attributes[0], ref);
return '{{#each ' + ref.name + '}} {{@key}}="{{this}}"{{/each}}';

@@ -730,10 +682,45 @@ }

function findBabelClassDeclaration(path) {
return path.findParent(path => {
return path.isCallExpression()
&& path.get('callee').get('name').node == '_createClass';
});
}
function findDefaultPropsIfAny(path) {
path = findClassDeclaration(path);
let defaultPropsPath = path.get('body').get('body')
.filter(element => element.isClassProperty())
.filter(element => element.get('key').get('name').node == 'defaultProps');
if (defaultPropsPath.length > 0) {
return defaultPropsPath[0].get('value').node;
let decl = findClassDeclaration(path);
let defaultPropsPath;
if (decl) {
defaultPropsPath = decl.get('body').get('body')
.filter(element => element.isClassProperty())
.find(element => element.get('key').get('name').node == 'defaultProps');
} else {
decl = findBabelClassDeclaration(path);
if (decl) {
const args = decl.get('arguments');
if (args.length > 2) {
// Find property with key defaultProps...
let element;
for (let el of args[2].get('elements')) {
for (const prop of el.get('properties')) {
if (prop.get('key').get('name').node == 'key'
&& prop.get('value').get('value').node == 'defaultProps') {
element = el;
}
}
}
if (element) {
// ... and select value node out of it
for (let prop of element.get('properties')) {
if (prop.get('key').get('name').node == 'value') {
defaultPropsPath = prop;
}
}
}
}
}
}
if (defaultPropsPath) {
return defaultPropsPath.get('value').node;
}
return t.objectExpression([]);

@@ -826,2 +813,84 @@ }

function createFilterSpreadAndChildrenAttributes(attribute, ref) {
findClosestStatement(attribute).insertBefore(
t.expressionStatement(
t.assignmentExpression(
'=',
createMemberExpression(localContextRef, ref.name),
t.callExpression(
createMemberExpression(
t.callExpression(
createMemberExpression(
t.callExpression(
createMemberExpression('Object', 'keys'),
[
createMemberExpression(localContextRef, ref.name)
]
),
'filter'
),
[
t.functionExpression(
null,
[
t.identifier('key')
],
t.blockStatement([
t.returnStatement(
t.logicalExpression(
'&&',
t.logicalExpression(
'!=',
t.identifier('key'),
t.literal('children')
),
t.logicalExpression(
'!=',
t.identifier('key'),
t.literal('__$spread$__')
)
)
)
])
)
]
),
'reduce'
),
[
t.functionExpression(
null,
[
t.identifier('props'),
t.identifier('key')
],
t.blockStatement([
t.expressionStatement(
t.assignmentExpression(
'=',
t.memberExpression(
t.identifier('props'),
t.identifier('key'),
true
),
t.memberExpression(
createMemberExpression(localContextRef, ref.name),
t.identifier('key'),
true
)
)
),
t.returnStatement(
t.identifier('props')
)
])
),
t.objectExpression([])
]
)
)
)
);
}
function newVariableReplacement(path) {

@@ -828,0 +897,0 @@ let key = createKeyFromPath(path);

{
"name": "babel-plugin-jsx-to-handlebars",
"version": "0.1.3",
"version": "0.1.4",
"description": "babel-plugin to convert simple stateless react compontents to handlebars templates",

@@ -5,0 +5,0 @@ "main": "dist/plugin.dist.js",

@@ -9,3 +9,4 @@ import * as path from 'path';

var dir = path.dirname(file);
return compileTemplate(customRequire(dir, babelTransform(file)), undefined, data)();
let source = fs.readFileSync(file);
return compileTemplate(customRequire(dir, babelTransform(source)), undefined, data)();
}

@@ -18,8 +19,8 @@

export function babelTransform(file, enablePlugin = true) {
let source = fs.readFileSync(file);
return babel.transform(source, {
export function babelTransform(source, enablePlugin = true, opts = {}) {
let localOpts = Object.assign(opts, {
stage: 0,
plugins: enablePlugin ? ['../dist/plugin.dist.js'] : []
}).code;
});
return babel.transform(source, localOpts).code;
}

@@ -35,3 +36,4 @@

id = './' + path.join(dir, id);
return commonjs(babelTransform(id));
let source = fs.readFileSync(id);
return commonjs(babelTransform(source));
} else {

@@ -38,0 +40,0 @@ return require(id);