@storybook/codemod
Version:
A collection of codemod scripts written with JSCodeshift
109 lines (92 loc) • 3.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
exports.default = transformer;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Takes the deprecated addon-info API, addWithInfo, and
* converts to the new withInfo API.
*
* Example of deprecated addWithInfo API:
*
* storiesOf('Button')
* .addWithInfo(
* 'story name',
* 'Story description.',
* () => (
* <Button label="The Button" />
* )
* )
*
* Converts to the new withInfo API:
*
* storiesOf('Button')
* .add('story name', withInfo(
* 'Story description.'
* )(() => (
* <Button label="The Button" />
* )))
*/
function transformer(file, api) {
var j = api.jscodeshift;
var root = j(file.source);
/**
* Returns a list of parameters for the withInfo function. The contents
* of this list is either the second argument from the original
* addWithInfo function, if no additional options were used, or a
* combined object of all the options from the original function.
* @param {list} args - original addWithInfo function parameters
* @return {list} the modified list of parameters for the new function
*/
var getOptions = function getOptions(args) {
if (args[3] === undefined) {
if (args[2] === undefined) {
// when the optional description string is not supplied for addWithInfo, just use story name
return [args[0]];
}
return [args[1]];
}
return [j.objectExpression([j.property('init', j.identifier('text'), args[1])].concat((0, _toConsumableArray3.default)(args[3].properties)))];
};
/**
* Constructs the new withInfo function from the parameters of the
* original addWithInfo function.
* @param {CallExpression} addWithInfoExpression - original function
* @returns {CallExpression} the new withInfo function
*/
var withInfo = function withInfo(addWithInfoExpression) {
var node = addWithInfoExpression.node;
var args = node.arguments;
// if optional description string is not supplied, the story component becomes second arg
var storyComponent = args[2] ? args[2] : args[1];
node.callee.property.name = 'add';
node.arguments = [args[0], j.callExpression(j.callExpression(j.identifier('withInfo'), getOptions(args)), [storyComponent])];
return node;
};
/**
* Checks for - import { withInfo } from "@storybook/addon-info";
* Adds the import if necessary.
*/
var checkWithInfoImport = function checkWithInfoImport() {
var importExists = root.find(j.ImportDeclaration).filter(function (imp) {
return imp.node.source.value === '@storybook/addon-info';
}).size();
if (importExists) return;
root.find(j.ImportDeclaration).at(-1).insertAfter(j.importDeclaration([j.importSpecifier(j.identifier('withInfo'))], j.literal('@storybook/addon-info')));
};
var addWithInfoExpressions = root.find(j.CallExpression, {
callee: {
property: {
name: 'addWithInfo'
}
}
});
if (addWithInfoExpressions.size()) {
checkWithInfoImport();
addWithInfoExpressions.replaceWith(withInfo);
}
return root.toSource();
}