Skip to content

Instantly share code, notes, and snippets.

@raejin
Created April 15, 2017 00:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save raejin/292eccdf683bf39d55569da940078881 to your computer and use it in GitHub Desktop.
Save raejin/292eccdf683bf39d55569da940078881 to your computer and use it in GitHub Desktop.
jscodeshift transform for making $.ajax call to adapt then callbacks
export default function transformer(file, api) {
const j = api.jscodeshift;
let isModified = false;
const codemod = j(file.source)
// find [$.ajax] looking code snippet
.find(j.MemberExpression)
.filter(path => {
const node = path.node;
return (node.object.name === '$' || node.object.name === 'jQuery') && node.property.name === 'ajax';
})
// returning the parent of [$.ajax] node
.map(path => {
return path.parent
})
// make sure it is a callExpression $.ajax(...), not like `const ajax = $.ajax;`
.filter(path => {
return path.node.type === 'CallExpression';
})
.filter(path => {
const properties = path.node.arguments[0].properties
return properties.findIndex((x) => (x.key.name === 'success')) !== -1 ||
properties.findIndex((x) => (x.key.name === 'error')) !== -1 ||
properties.findIndex((x) => (x.key.name === 'complete')) !== -1
})
// find 'success' or 'error' callbacks defined on the $.ajax(param)
// and move them to the end of $.ajax(param).then(successCallback, errorCallback)
.replaceWith(path => {
isModified = true;
let successCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'success'))
let errorCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'error'))
let completeCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'complete'))
if (successCallback !== -1 && errorCallback === -1 && completeCallback === -1) {
// only success cb is defined
const successNode = path.node.arguments[0].properties.splice(successCallback, 1)[0];
const thenVar = j.identifier('then')
return j.callExpression(j.memberExpression(path.node, thenVar), [successNode.value]);
} else if (successCallback !== -1 && errorCallback === -1 && completeCallback !== -1) {
// success & complete callbacks defined
const successNode = path.node.arguments[0].properties.splice(successCallback, 1)[0];
completeCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'complete'))
const completeNode = path.node.arguments[0].properties.splice(completeCallback, 1)[0];
const thenVar = j.identifier('then')
const callExpr = j.callExpression(j.memberExpression(path.node, thenVar), [successNode.value]);
return j.callExpression(j.memberExpression(callExpr, thenVar), [completeNode.value]);
} else if (successCallback === -1 && errorCallback !== -1 && completeCallback === -1) {
// only error callback is defined
const errorNode = path.node.arguments[0].properties.splice(errorCallback, 1)[0];
const thenVar = j.identifier('catch')
return j.callExpression(j.memberExpression(path.node, thenVar), [errorNode.value]);
} else if (completeCallback === -1 && successCallback !== -1 && errorCallback !== -1) {
// success and error callbacks both defined, not complete callback
const successNode = path.node.arguments[0].properties.splice(successCallback, 1)[0];
errorCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'error'))
const errorNode = path.node.arguments[0].properties.splice(errorCallback, 1)[0];
const thenVar = j.identifier('then')
return j.callExpression(j.memberExpression(path.node, thenVar), [successNode.value, errorNode.value]);
} else if (completeCallback !== -1 && successCallback === -1 && errorCallback === -1) {
// if only complete callback exists
const completeNode = path.node.arguments[0].properties.splice(completeCallback, 1)[0];
const alwaysVar = j.identifier('always')
return j.callExpression(j.memberExpression(path.node, alwaysVar), [completeNode.value]);
} else {
// all three defined
const successNode = path.node.arguments[0].properties.splice(successCallback, 1)[0];
errorCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'error'))
const errorNode = path.node.arguments[0].properties.splice(errorCallback, 1)[0];
completeCallback = path.node.arguments[0].properties.findIndex((x) => (x.key.name === 'complete'))
const completeNode = path.node.arguments[0].properties.splice(completeCallback, 1)[0];
const thenVar = j.identifier('then')
const callExpr = j.callExpression(j.memberExpression(path.node, thenVar), [successNode.value, errorNode.value]);
completeNode.value.id = j.identifier('complete')
return j.callExpression(j.memberExpression(callExpr, thenVar), [completeNode.value]);
}
})
if (isModified) {
return codemod.toSource();
} else {
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment