Last active
February 9, 2022 11:54
-
-
Save busticated/7dddf6eebd17c94e9870095ad246daa9 to your computer and use it in GitHub Desktop.
whitepace + jscodeshift
This file contains hidden or 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
'use strict'; | |
/////////////////////////////////////////////////////////////////////////////// | |
// USAGE: jscodeshift ./lib/ -t ./scripts/codemod-react-proptypes.js | |
/////////////////////////////////////////////////////////////////////////////// | |
module.exports = function(file, api){ | |
var js = api.jscodeshift, | |
root = js(file.source), | |
shouldFixWhitespace, | |
collection; | |
/////////////////////////////////////////////////////////////////////////// | |
// FROM: require('react').PropTypes | |
// TO: require('prop-types') | |
/////////////////////////////////////////////////////////////////////////// | |
getReactRequiresWithPropTypesProperty(root, js) | |
.replaceWith(requireCallExpression(js, 'prop-types')); | |
/////////////////////////////////////////////////////////////////////////// | |
// FROM: React.PropTypes | |
// TO: PropTypes | |
/////////////////////////////////////////////////////////////////////////// | |
collection = getReactPropTypesRefs(root, js) | |
.replaceWith(js.identifier('PropTypes')); | |
if (collection.length){ | |
/////////////////////////////////////////////////////////////////////// | |
// FROM: React = require('react'), | |
// TO: React = require('react'), | |
// PropTypes = require('prop-types'), | |
/////////////////////////////////////////////////////////////////////// | |
getVarDeclarationsWhichIncludeReact(root, js) | |
.forEach(function(path){ | |
var atIndex = findIndexOfFirstDeclaration(path, 'React'); | |
if (atIndex < 0){ return; } | |
insertVarDeclarationWithRequire(path, js, { | |
start: atIndex + 1, | |
name: 'PropTypes', | |
module: 'prop-types' | |
}); | |
}); | |
shouldFixWhitespace = true; | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// FROM: React.createClass | |
// TO: createClass | |
/////////////////////////////////////////////////////////////////////////// | |
collection = getReactCreateClassRefs(root, js) | |
.replaceWith(js.identifier('createReactClass')); | |
if (collection.length){ | |
/////////////////////////////////////////////////////////////////////// | |
// FROM: React = require('react'), | |
// TO: React = require('react'), | |
// createReactClass = require('create-react-class'), | |
/////////////////////////////////////////////////////////////////////// | |
getVarDeclarationsWhichIncludeReact(root, js) | |
.forEach(function(path){ | |
var atIndex = findIndexOfFirstDeclaration(path, 'PropTypes', 'React'); | |
if (atIndex < 0){ return; } | |
insertVarDeclarationWithRequire(path, js, { | |
start: atIndex + 1, | |
name: 'createReactClass', | |
module: 'create-react-class' | |
}); | |
}); | |
shouldFixWhitespace = shouldFixWhitespace || true; | |
} | |
if (shouldFixWhitespace){ | |
/////////////////////////////////////////////////////////////////////// | |
// FROM: Foo = require('foo'), Bar = require('bar'), Baz = require('baz'); | |
// TO: Foo = require('foo'), | |
// Bar = require('bar'), | |
// Baz = require('baz'); | |
/////////////////////////////////////////////////////////////////////// | |
// TODO (mirande): hack! figure out how to do this properly? | |
getVarDeclarationsWhichIncludeReact(root, js) | |
.forEach(function(path){ | |
path.replace(js(path) | |
.toSource({ quote: 'single' }) | |
.split(',') | |
.join(',\n ')); | |
}); | |
} | |
return root.toSource({ quote: 'single' }); | |
}; | |
// utilities ////////////////////////////////////////////////////////////////// | |
function findIndexOfFirstDeclaration(path){ | |
var index = -1, | |
i = 1; | |
while (i < arguments.length){ | |
index = findIndexOfDeclaration(path, arguments[i]); | |
if (index >= 0){ return index; } | |
i += 1; | |
} | |
return index; | |
} | |
function findIndexOfDeclaration(path, name){ | |
return path.value.declarations.findIndex(function(arg){ | |
return arg.id.name === name; | |
}); | |
} | |
function getVarDeclarationsWhichIncludeReact(root, js){ | |
return root.find(js.VariableDeclaration) | |
.filter(function(path){ | |
return path.value.declarations.find(function(dec){ | |
return dec.id.name === 'React'; | |
}); | |
}); | |
} | |
function getReactRequiresWithPropTypesProperty(root, js){ | |
return root.find(js.MemberExpression, { | |
object: { | |
type: 'CallExpression', | |
callee: { type: 'Identifier', name: 'require' }, | |
arguments: [ | |
{ type: 'Literal', value: 'react' } | |
] | |
}, | |
property: { | |
type: 'Identifier', | |
name: 'PropTypes' | |
} | |
}); | |
} | |
function getReactPropTypesRefs(root, js){ | |
return root.find(js.MemberExpression, { | |
object: { | |
type: 'Identifier', | |
name: 'React' | |
}, | |
property: { | |
type: 'Identifier', | |
name: 'PropTypes' | |
} | |
}); | |
} | |
function getReactCreateClassRefs(root, js){ | |
return root.find(js.MemberExpression, { | |
object: { | |
type: 'Identifier', | |
name: 'React' | |
}, | |
property: { | |
type: 'Identifier', | |
name: 'createClass' | |
} | |
}); | |
} | |
function insertVarDeclarationWithRequire(path, js, options){ | |
path.value.declarations.splice( | |
options.start, | |
options.end || 0, | |
js.variableDeclarator( | |
js.identifier(options.name), | |
requireCallExpression(js, options.module) | |
) | |
); | |
} | |
function requireCallExpression(js, name){ | |
return js.callExpression( | |
js.identifier('require'), | |
[js.literal(name)] | |
); | |
} |
This file contains hidden or 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
'use strict'; | |
var React = require('react'), | |
omit = require('lodash/omit'), | |
glyphBtn = React.createFactory(require('./glyph')); | |
module.exports = React.createClass({ | |
displayName: 'AppendElementButton', | |
propTypes: { | |
className: React.PropTypes.string, | |
onAppend: React.PropTypes.func.isRequired, | |
}, | |
getDefaultProps: function(){ | |
return { className: 'btn-append-element' }; | |
}, | |
onAppend: function(event){ | |
event.preventDefault(); | |
this.props.onAppend(); | |
}, | |
render: function(){ | |
var props = omit(this.props, ['onAppend']); | |
props.onClick = this.onAppend; | |
props.text = 'append element'; | |
return glyphBtn(props); | |
} | |
}); |
This file contains hidden or 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
'use strict'; | |
var React = require('react'), | |
PropTypes = require('prop-types'), | |
createReactClass = require('create-react-class'), | |
omit = require('lodash/omit'), | |
glyphBtn = React.createFactory(require('./glyph')); | |
module.exports = createReactClass({ | |
displayName: 'AppendElementButton', | |
propTypes: { | |
className: PropTypes.string, | |
onAppend: PropTypes.func.isRequired, | |
}, | |
getDefaultProps: function(){ | |
return { className: 'btn-append-element' }; | |
}, | |
onAppend: function(event){ | |
event.preventDefault(); | |
this.props.onAppend(); | |
}, | |
render: function(){ | |
var props = omit(this.props, ['onAppend']); | |
props.onClick = this.onAppend; | |
props.text = 'append element'; | |
return glyphBtn(props); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment