Created
January 23, 2018 08:38
-
-
Save nathan-muir/3aa99ce7fcde32824a77975c27b7d761 to your computer and use it in GitHub Desktop.
Meteor Blaze JS CodeShift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* jscodeshift script that converts | |
* Template.xyz.{helperName} = function(){} | |
* to use | |
* Template.xyz.helpers({ helperName: function(){} }) | |
*/ | |
export default function transformer(file, api) { | |
let j = api.jscodeshift; | |
let ast = j(file.source); | |
ast.find(j.AssignmentExpression) | |
.filter(path => { | |
let { type, operator, left, right } = path.node; | |
let valid = operator === '=' | |
&& (right.type === 'FunctionExpression' || right.type === 'ArrowFunctionExpression') | |
&& left.type === 'MemberExpression' && left.object.type === 'MemberExpression' | |
&& left.object.object.type === 'Identifier' && left.object.object.name === 'Template' | |
&& left.property.name !== 'created' | |
&& left.property.name !== 'rendered' | |
&& left.property.name !== 'destroyed'; | |
return valid; | |
}) | |
.forEach(function (path) { | |
let { left, right } = path.node; | |
// console.log('left=', left, 'right=', right); | |
let prop; | |
if (right.type === 'ArrowFunctionExpression') { | |
let body; | |
if (j.BlockStatement.check(right.body)) { | |
body = right.body; | |
} else { | |
// const comments = right.init.body.comments; | |
body = j.blockStatement([ | |
j.returnStatement(right.body), | |
]); | |
} | |
prop = j.property('init', j.identifier(left.property.name), j.functionExpression( | |
right.id, right.params, body, right.generator, right.expression | |
)) | |
} else { | |
prop = j.property('init', j.identifier(left.property.name), right); | |
} | |
prop.method = true; | |
let resultNode = j.callExpression( | |
j.memberExpression(left.object, j.identifier('helpers')), | |
[ | |
j.objectExpression([ | |
prop | |
]) | |
] | |
); | |
resultNode.comments = []; | |
j(path).replaceWith(resultNode); | |
}); | |
let helperBlocks = new Map(); | |
ast.find(j.CallExpression) | |
.filter(path => { | |
let { callee } = path.node; | |
let valid = callee.type === 'MemberExpression' && | |
callee.object.type === 'MemberExpression' && | |
callee.object.object.name === 'Template' && | |
callee.property.name === 'helpers' && | |
path.node.arguments.length === 1 && | |
path.node.arguments[0].type === 'ObjectExpression'; | |
return valid; | |
}).forEach(function (path) { | |
let { callee } = path.node; | |
let templateName = callee.object.property.name; | |
let exprs = helperBlocks.get(templateName) || []; | |
helperBlocks.set(templateName, exprs.concat([path])) | |
}); | |
helperBlocks.forEach(function (paths) { | |
if (paths.length === 1) return; | |
let firstPath = paths.shift(); | |
let firstExpr = firstPath.node; | |
let properties = firstExpr.arguments[0].properties.slice(0); | |
paths.forEach(function (path) { | |
let expr = path.node; | |
properties.push(...expr.arguments[0].properties); | |
j(path).remove() | |
}); | |
j(firstPath).replaceWith( | |
j.callExpression(firstExpr.callee, [ | |
j.objectExpression(properties) | |
]) | |
) | |
}); | |
return ast.toSource(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* jscodeshift script that converts | |
* TemplateHooks(Template.xyz, {created: function(){} }); | |
* to use | |
* Template.xyz.onCreated(function(){}) | |
*/ | |
export default function transformer(file, api) { | |
let j = api.jscodeshift; | |
let ast = j(file.source); | |
ast.find(j.CallExpression) | |
.filter(path => { | |
let { callee } = path.node; | |
let valid = callee.name === 'TemplateHooks' | |
&& path.node.arguments.length === 2 | |
&& path.node.arguments[0].type === 'MemberExpression' | |
&& path.node.arguments[1].type === 'ObjectExpression' | |
; | |
return valid; | |
}) | |
.forEach(function (path) { | |
let [exp, obj] = path.node.arguments; | |
let newNodes = obj.properties.map(function ({ key, value }) { | |
let propName; | |
if (key.type === 'Literal') { | |
propName = key.value; | |
} else if (key.type === 'Identifier') { | |
propName = key.name; | |
} | |
let fnName; | |
if (propName === 'created') { | |
fnName = 'onCreated' | |
} else if (propName === 'rendered') { | |
fnName = 'onRendered' | |
} else if (propName === 'destroyed') { | |
fnName = 'onDestroyed' | |
} | |
let fn; | |
if (value.type === 'ArrowFunctionExpression') { | |
let body; | |
if (j.BlockStatement.check(value.body)) { | |
body = value.body; | |
} else { | |
// const comments = value.init.body.comments; | |
body = j.blockStatement([ | |
j.returnStatement(value.body), | |
]); | |
} | |
fn = j.functionExpression( | |
value.id, value.params, body, value.generator, value.expression | |
) | |
} else { | |
fn = value; | |
} | |
let c = j.callExpression( | |
j.memberExpression(exp, j.identifier(fnName)), | |
[ | |
fn | |
] | |
); | |
return j.expressionStatement(c) | |
}); | |
// Need to replace the parent "ExpressionStatement"'s | |
j(path.parent).replaceWith(newNodes) | |
}); | |
return ast.toSource(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* jscodeshift script that converts | |
* Template.xyz.(rendered|created|destroyed) = function(){} | |
* to use | |
* Template.xyz.(onRendered|onCreated|onDestroyed)(function(){}) | |
*/ | |
export default function transformer(file, api) { | |
let j = api.jscodeshift; | |
let ast = j(file.source); | |
ast.find(j.AssignmentExpression) | |
.filter(path => { | |
let { type, operator, left, right } = path.node; | |
let valid = operator === '=' | |
&& (right.type === 'FunctionExpression' || right.type === 'ArrowFunctionExpression') | |
&& left.type === 'MemberExpression' && left.object.type === 'MemberExpression' | |
&& left.object.object.type === 'Identifier' && left.object.object.name === 'Template' | |
&& (left.property.name === 'created' || left.property.name === 'rendered' || left.property.name === 'destroyed'); | |
return valid; | |
}) | |
.forEach(function (path) { | |
let { left, right } = path.node; | |
// console.log('left=', left, 'right=', right); | |
let fn; | |
if (right.type === 'ArrowFunctionExpression') { | |
let body; | |
if (j.BlockStatement.check(right.body)) { | |
body = right.body; | |
} else { | |
// const comments = right.init.body.comments; | |
body = j.blockStatement([ | |
j.returnStatement(right.body), | |
]); | |
} | |
fn = j.functionExpression( | |
right.id, right.params, body, right.generator, right.expression | |
) | |
} else { | |
fn = right; | |
} | |
let propName =left.property.name; | |
let fnName; | |
if (propName === 'created') { | |
fnName = 'onCreated' | |
} else if (propName === 'rendered'){ | |
fnName = 'onRendered' | |
} else if (propName === 'destroyed') { | |
fnName = 'onDestroyed' | |
} | |
let resultNode = j.callExpression( | |
j.memberExpression(left.object, j.identifier(fnName)), | |
[ | |
fn | |
] | |
); | |
resultNode.comments = []; | |
j(path).replaceWith(resultNode); | |
}); | |
return ast.toSource(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment