Skip to content

Instantly share code, notes, and snippets.

@JamieMason
Created April 4, 2019 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamieMason/05538897f18bbec90960c7d065aa1767 to your computer and use it in GitHub Desktop.
Save JamieMason/05538897f18bbec90960c7d065aa1767 to your computer and use it in GitHub Desktop.
export default function transformer(file, api) {
const j = api.jscodeshift;
const toPascalCase = str =>
`${str}`
.replace(new RegExp(/[-_]+/, 'g'), ' ')
.replace(new RegExp(/[^\w\s]/, 'g'), '')
.replace(
new RegExp(/\s+(.)(\w+)/, 'g'),
($1, $2, $3) => `${$2.toUpperCase() + $3.toLowerCase()}`
)
.replace(new RegExp(/\s/, 'g'), '')
.replace(new RegExp(/\w/), s => s.toUpperCase());
const toTitleCase = str =>
str.replace(/\w\S*/g, txt => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
return j(file.source)
.find(j.MemberExpression)
.forEach(path => {
if (path.node.property.name !== 'addWithJSX') {
return;
}
const addWithJSX = path.parentPath;
const storyName = addWithJSX.node.arguments[0].value;
const storyRender = addWithJSX.node.arguments[1];
const storyComponentName = `${toPascalCase(storyName)}Story`;
const storyNameInTitleCase = toTitleCase(storyName);
const storyDefinition = j(path)
.closest(j.ExpressionStatement)
.at(0)
.get();
// copy the anonymous render function and assign it a variable called eg DefaultStory
j(storyDefinition).insertBefore(
j.variableDeclaration('const', [
j.variableDeclarator(j.identifier(storyComponentName), storyRender)
])
);
// format the original title in title case
addWithJSX.node.arguments[0] = j.literal(storyNameInTitleCase);
// replace the anonymous render function with () => <DefaultStory />
addWithJSX.node.arguments[1] = j.arrowFunctionExpression(
[],
j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(storyComponentName), [], true)),
false
);
})
.toSource();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment