@storybook/codemod 6.5.9 → 7.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,5 +36,10 @@ function jscodeshiftToPrettierParser(parser) {
36
36
  ts: 'typescript',
37
37
  tsx: 'typescript'
38
38
  };
39
+
40
+ if (!parser) {
41
+ return 'babel';
42
+ }
43
+
39
44
  return parserMap[parser] || 'babel';
40
45
  }
@@ -123,7 +123,11 @@ function transform({
123
123
 
124
124
 
125
125
  var storyFn = template && csf._templates[template];
126
- if (!storyFn) storyFn = init;
126
+
127
+ if (!storyFn) {
128
+ storyFn = init;
129
+ }
130
+
127
131
  var keyId = t.identifier(key); // @ts-ignore
128
132
 
129
133
  var typeAnnotation = id.typeAnnotation;
@@ -21,5 +21,10 @@ export function jscodeshiftToPrettierParser(parser) {
21
21
  ts: 'typescript',
22
22
  tsx: 'typescript'
23
23
  };
24
+
25
+ if (!parser) {
26
+ return 'babel';
27
+ }
28
+
24
29
  return parserMap[parser] || 'babel';
25
30
  }
@@ -107,7 +107,11 @@ function transform({
107
107
 
108
108
 
109
109
  var storyFn = template && csf._templates[template];
110
- if (!storyFn) storyFn = init;
110
+
111
+ if (!storyFn) {
112
+ storyFn = init;
113
+ }
114
+
111
115
  var keyId = t.identifier(key); // @ts-ignore
112
116
 
113
117
  var typeAnnotation = id.typeAnnotation;
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/codemod",
3
- "version": "6.5.9",
3
+ "version": "7.0.0-alpha.10",
4
4
  "description": "A collection of codemod scripts written with JSCodeshift",
5
5
  "keywords": [
6
6
  "storybook"
@@ -44,16 +44,15 @@
44
44
  "@babel/types": "^7.12.11",
45
45
  "@mdx-js/mdx": "^1.6.22",
46
46
  "@storybook/csf": "0.0.2--canary.4566f4d.1",
47
- "@storybook/csf-tools": "6.5.9",
48
- "@storybook/node-logger": "6.5.9",
47
+ "@storybook/csf-tools": "7.0.0-alpha.10",
48
+ "@storybook/node-logger": "7.0.0-alpha.10",
49
49
  "core-js": "^3.8.2",
50
50
  "cross-spawn": "^7.0.3",
51
51
  "globby": "^11.0.2",
52
52
  "jscodeshift": "^0.13.1",
53
53
  "lodash": "^4.17.21",
54
54
  "prettier": ">=2.2.1 <=2.3.0",
55
- "recast": "^0.19.0",
56
- "regenerator-runtime": "^0.13.7"
55
+ "recast": "^0.19.0"
57
56
  },
58
57
  "devDependencies": {
59
58
  "jest": "^26.6.3",
@@ -62,6 +61,5 @@
62
61
  "publishConfig": {
63
62
  "access": "public"
64
63
  },
65
- "gitHead": "e2673f765722cbb542ef1b5cf8d533c8e746a127",
66
- "sbmodern": "dist/modern/index.js"
64
+ "gitHead": "b13dd8fb52819d73d4983148af8ffc5d683e8b75"
67
65
  }
@@ -1,99 +0,0 @@
1
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
-
3
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
-
5
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
-
7
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
8
-
9
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
10
-
11
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
-
13
- import "core-js/modules/es.promise.js";
14
- import "core-js/modules/es.symbol.description.js";
15
-
16
- /* eslint import/prefer-default-export: "off" */
17
- import fs from 'fs';
18
- import path from 'path';
19
- import { promisify } from 'util';
20
- import globby from 'globby';
21
- import { sync as spawnSync } from 'cross-spawn';
22
- import { jscodeshiftToPrettierParser } from './lib/utils';
23
- export { default as updateOrganisationName, packageNames } from './transforms/update-organisation-name';
24
- export { default as updateAddonInfo } from './transforms/update-addon-info';
25
- var TRANSFORM_DIR = `${__dirname}/transforms`;
26
- export function listCodemods() {
27
- return fs.readdirSync(TRANSFORM_DIR).filter(function (fname) {
28
- return fname.endsWith('.js');
29
- }).map(function (fname) {
30
- return fname.slice(0, -3);
31
- });
32
- }
33
- var renameAsync = promisify(fs.rename);
34
-
35
- async function renameFile(file, from, to, {
36
- logger: logger
37
- }) {
38
- var newFile = file.replace(from, to);
39
- logger.log(`Rename: ${file} ${newFile}`);
40
- return renameAsync(file, newFile);
41
- }
42
-
43
- export async function runCodemod(codemod, {
44
- glob: glob,
45
- logger: logger,
46
- dryRun: dryRun,
47
- rename: rename,
48
- parser: parser
49
- }) {
50
- var codemods = listCodemods();
51
-
52
- if (!codemods.includes(codemod)) {
53
- throw new Error(`Unknown codemod ${codemod}. Run --list for options.`);
54
- }
55
-
56
- var renameParts = null;
57
-
58
- if (rename) {
59
- renameParts = rename.split(':');
60
-
61
- if (renameParts.length !== 2) {
62
- throw new Error(`Codemod rename: expected format "from:to", got "${rename}"`);
63
- }
64
- } // jscodeshift/prettier know how to handle .ts/.tsx extensions,
65
- // so if the user uses one of those globs, we can auto-infer
66
-
67
-
68
- var inferredParser = parser;
69
-
70
- if (!parser) {
71
- var extension = path.extname(glob).slice(1);
72
- var knownParser = jscodeshiftToPrettierParser(extension);
73
- if (knownParser !== 'babel') inferredParser = extension;
74
- }
75
-
76
- var files = await globby([glob, '!**/node_modules', '!**/dist']);
77
- logger.log(`=> Applying ${codemod}: ${files.length} files`);
78
-
79
- if (!dryRun) {
80
- var parserArgs = inferredParser ? ['--parser', inferredParser] : [];
81
- spawnSync('npx', ['jscodeshift', '-t', `${TRANSFORM_DIR}/${codemod}.js`, ...parserArgs, ...files], {
82
- stdio: 'inherit'
83
- });
84
- }
85
-
86
- if (renameParts) {
87
- var _renameParts = renameParts,
88
- _renameParts2 = _slicedToArray(_renameParts, 2),
89
- from = _renameParts2[0],
90
- to = _renameParts2[1];
91
-
92
- logger.log(`=> Renaming ${rename}: ${files.length} files`);
93
- await Promise.all(files.map(function (file) {
94
- return renameFile(file, new RegExp(`${from}$`), to, {
95
- logger: logger
96
- });
97
- }));
98
- }
99
- }
@@ -1,25 +0,0 @@
1
- import camelCase from 'lodash/camelCase';
2
- import upperFirst from 'lodash/upperFirst';
3
- export var sanitizeName = function (name) {
4
- var key = upperFirst(camelCase(name)); // prepend _ if name starts with a digit
5
-
6
- if (/^\d/.test(key)) {
7
- key = `_${key}`;
8
- } // prepend _ if name starts with a digit
9
-
10
-
11
- if (/^\d/.test(key)) {
12
- key = `_${key}`;
13
- }
14
-
15
- return key;
16
- };
17
- export function jscodeshiftToPrettierParser(parser) {
18
- var parserMap = {
19
- babylon: 'babel',
20
- flow: 'flow',
21
- ts: 'typescript',
22
- tsx: 'typescript'
23
- };
24
- return parserMap[parser] || 'babel';
25
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * Adds a `component` parameter for each storiesOf(...) call.
3
- *
4
- * For example:
5
- *
6
- * input { Button } from './Button';
7
- * storiesOf('Button', module).add('story', () => <Button label="The Button" />);
8
- *
9
- * Becomes:
10
- *
11
- * input { Button } from './Button';
12
- * storiesOf('Button', module)
13
- * .addParameters({ component: Button })
14
- * .add('story', () => <Button label="The Button" />);
15
- *
16
- * Heuristics:
17
- * - The storiesOf "kind" name must be Button
18
- * - Button must be imported in the file
19
- */
20
- export default function transformer(file, api) {
21
- var j = api.jscodeshift;
22
- var root = j(file.source); // Create a dictionary whose keys are all the named imports in the file.
23
- // For instance:
24
- //
25
- // import foo from 'foo';
26
- // import { bar, baz } from 'zoo';
27
- //
28
- // => { foo: true, bar: true, baz: true }
29
-
30
- var importMap = {};
31
- root.find(j.ImportDeclaration).forEach(function (imp) {
32
- return imp.node.specifiers.forEach(function (spec) {
33
- importMap[spec.local.name] = true;
34
- });
35
- });
36
-
37
- function getLeafName(string) {
38
- var parts = string.split(/\/|\.|\|/);
39
- return parts[parts.length - 1];
40
- }
41
-
42
- function addComponentParameter(call) {
43
- var node = call.node;
44
- var leafName = getLeafName(node.arguments[0].value);
45
- return j.callExpression(j.memberExpression(node, j.identifier('addParameters')), [j.objectExpression([j.property('init', j.identifier('component'), j.identifier(leafName))])]);
46
- }
47
-
48
- var storiesOfCalls = root.find(j.CallExpression).filter(function (call) {
49
- return call.node.callee.name === 'storiesOf';
50
- }).filter(function (call) {
51
- return call.node.arguments.length > 0 && call.node.arguments[0].type === 'Literal';
52
- }).filter(function (call) {
53
- var leafName = getLeafName(call.node.arguments[0].value);
54
- return importMap[leafName];
55
- }).replaceWith(addComponentParameter);
56
- return root.toSource();
57
- }
@@ -1,159 +0,0 @@
1
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
-
3
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
-
5
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
-
7
- /* eslint-disable no-underscore-dangle */
8
- import prettier from 'prettier';
9
- import * as t from '@babel/types';
10
- import { formatCsf, loadCsf } from '@storybook/csf-tools';
11
- import { jscodeshiftToPrettierParser } from '../lib/utils';
12
- var logger = console;
13
-
14
- var _rename = function (annotation) {
15
- return annotation === 'storyName' ? 'name' : annotation;
16
- };
17
-
18
- var getTemplateBindVariable = function (init) {
19
- return t.isCallExpression(init) && t.isMemberExpression(init.callee) && t.isIdentifier(init.callee.object) && t.isIdentifier(init.callee.property) && init.callee.property.name === 'bind' && (init.arguments.length === 0 || init.arguments.length === 1 && t.isObjectExpression(init.arguments[0]) && init.arguments[0].properties.length === 0) ? init.callee.object.name : null;
20
- }; // export const A = ...
21
- // A.parameters = { ... }; <===
22
-
23
-
24
- var isStoryAnnotation = function (stmt, objectExports) {
25
- return t.isExpressionStatement(stmt) && t.isAssignmentExpression(stmt.expression) && t.isMemberExpression(stmt.expression.left) && t.isIdentifier(stmt.expression.left.object) && objectExports[stmt.expression.left.object.name];
26
- };
27
-
28
- var isTemplateDeclaration = function (stmt, templates) {
29
- return t.isVariableDeclaration(stmt) && stmt.declarations.length === 1 && t.isIdentifier(stmt.declarations[0].id) && templates[stmt.declarations[0].id.name];
30
- };
31
-
32
- var getNewExport = function (stmt, objectExports) {
33
- if (t.isExportNamedDeclaration(stmt) && t.isVariableDeclaration(stmt.declaration) && stmt.declaration.declarations.length === 1) {
34
- var decl = stmt.declaration.declarations[0];
35
-
36
- if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id)) {
37
- return objectExports[decl.id.name];
38
- }
39
- }
40
-
41
- return null;
42
- }; // Remove render function when it matches the global render function in react
43
- // export default { component: Cat };
44
- // export const A = (args) => <Cat {...args} />;
45
-
46
-
47
- var isReactGlobalRenderFn = function (csf, storyFn) {
48
- var _csf$_meta;
49
-
50
- if ((_csf$_meta = csf._meta) !== null && _csf$_meta !== void 0 && _csf$_meta.component && t.isArrowFunctionExpression(storyFn) && storyFn.params.length === 1 && t.isJSXElement(storyFn.body)) {
51
- var openingElement = storyFn.body.openingElement;
52
-
53
- if (openingElement.selfClosing && t.isJSXIdentifier(openingElement.name) && openingElement.attributes.length === 1) {
54
- var attr = openingElement.attributes[0];
55
- var param = storyFn.params[0];
56
-
57
- if (t.isJSXSpreadAttribute(attr) && t.isIdentifier(attr.argument) && t.isIdentifier(param) && param.name === attr.argument.name && csf._meta.component === openingElement.name.name) {
58
- return true;
59
- }
60
- }
61
- }
62
-
63
- return false;
64
- }; // A simple CSF story is a no-arg story without any extra annotations (params, args, etc.)
65
-
66
-
67
- var isSimpleCSFStory = function (init, annotations) {
68
- return annotations.length === 0 && t.isArrowFunctionExpression(init) && init.params.length === 0;
69
- };
70
-
71
- function transform({
72
- source: source
73
- }, api, options) {
74
- var makeTitle = function (userTitle) {
75
- return userTitle || 'FIXME';
76
- };
77
-
78
- var csf = loadCsf(source, {
79
- makeTitle: makeTitle
80
- });
81
-
82
- try {
83
- csf.parse();
84
- } catch (err) {
85
- logger.log(`Error ${err}, skipping`);
86
- return source;
87
- }
88
-
89
- var objectExports = {};
90
- Object.entries(csf._storyExports).forEach(function ([key, decl]) {
91
- var annotations = Object.entries(csf._storyAnnotations[key]).map(function ([annotation, val]) {
92
- return t.objectProperty(t.identifier(_rename(annotation)), val);
93
- });
94
-
95
- if (t.isVariableDeclarator(decl)) {
96
- var init = decl.init,
97
- id = decl.id; // only replace arrow function expressions && template
98
- // ignore no-arg stories without annotations
99
-
100
- var template = getTemplateBindVariable(init);
101
-
102
- if (!t.isArrowFunctionExpression(init) && !template || isSimpleCSFStory(init, annotations)) {
103
- return;
104
- } // Remove the render function when we can hoist the template
105
- // const Template = (args) => <Cat {...args} />;
106
- // export const A = Template.bind({});
107
-
108
-
109
- var storyFn = template && csf._templates[template];
110
- if (!storyFn) storyFn = init;
111
- var keyId = t.identifier(key); // @ts-ignore
112
-
113
- var typeAnnotation = id.typeAnnotation;
114
-
115
- if (typeAnnotation) {
116
- keyId.typeAnnotation = typeAnnotation;
117
- }
118
-
119
- var renderAnnotation = isReactGlobalRenderFn(csf, storyFn) ? [] : [t.objectProperty(t.identifier('render'), storyFn)];
120
- objectExports[key] = t.exportNamedDeclaration(t.variableDeclaration('const', [t.variableDeclarator(keyId, t.objectExpression([...renderAnnotation, ...annotations]))]));
121
- }
122
- });
123
-
124
- var updatedBody = csf._ast.program.body.reduce(function (acc, stmt) {
125
- // remove story annotations & template declarations
126
- if (isStoryAnnotation(stmt, objectExports) || isTemplateDeclaration(stmt, csf._templates)) {
127
- return acc;
128
- } // replace story exports with new object exports
129
-
130
-
131
- var newExport = getNewExport(stmt, objectExports);
132
-
133
- if (newExport) {
134
- acc.push(newExport);
135
- return acc;
136
- } // include unknown statements
137
-
138
-
139
- acc.push(stmt);
140
- return acc;
141
- }, []);
142
-
143
- csf._ast.program.body = updatedBody;
144
- var output = formatCsf(csf);
145
- var prettierConfig = prettier.resolveConfig.sync('.', {
146
- editorconfig: true
147
- }) || {
148
- printWidth: 100,
149
- tabWidth: 2,
150
- bracketSpacing: true,
151
- trailingComma: 'es5',
152
- singleQuote: true
153
- };
154
- return prettier.format(output, _objectSpread(_objectSpread({}, prettierConfig), {}, {
155
- parser: jscodeshiftToPrettierParser(options === null || options === void 0 ? void 0 : options.parser)
156
- }));
157
- }
158
-
159
- export default transform;
@@ -1,86 +0,0 @@
1
- var getContainingStatement = function (n) {
2
- if (n.node.type.endsWith('Statement')) {
3
- return n;
4
- }
5
-
6
- return getContainingStatement(n.parent);
7
- };
8
- /**
9
- * Hoist CSF .story annotations
10
- *
11
- * For example:
12
- *
13
- * ```
14
- * export const Basic = () => <Button />
15
- * Basic.story = {
16
- * name: 'foo',
17
- * parameters: { ... },
18
- * decorators = [ ... ],
19
- * };
20
- * ```
21
- *
22
- * Becomes:
23
- *
24
- * ```
25
- * export const Basic = () => <Button />
26
- * Basic.storyName = 'foo';
27
- * Basic.parameters = { ... };
28
- * Basic.decorators = [ ... ];
29
- * ```
30
- */
31
-
32
-
33
- export default function transformer(file, api) {
34
- var j = api.jscodeshift;
35
- var root = j(file.source);
36
-
37
- var renameKey = function (exp) {
38
- return exp.type === 'Identifier' && exp.name === 'name' ? j.identifier('storyName') : exp;
39
- }; // 1. If the program does not have `export default { title: '....' }, skip it
40
-
41
-
42
- var defaultExportWithTitle = root.find(j.ExportDefaultDeclaration).filter(function (def) {
43
- return def.node.declaration.type === 'ObjectExpression' && def.node.declaration.properties.map(function (p) {
44
- return p.key.name;
45
- }).includes('title');
46
- });
47
-
48
- if (defaultExportWithTitle.size() === 0) {
49
- return root.toSource();
50
- } // 2. Replace each Foo.story = { x: xVal } with Foo.x = xVal;
51
-
52
-
53
- var storyAssignments = root.find(j.AssignmentExpression).filter(function (exp) {
54
- var _exp$node = exp.node,
55
- left = _exp$node.left,
56
- right = _exp$node.right;
57
- return left.type === 'MemberExpression' && left.object.type === 'Identifier' && left.property.type === 'Identifier' && left.property.name === 'story' && right.type === 'ObjectExpression';
58
- });
59
- storyAssignments.forEach(function (exp) {
60
- var _exp$node2 = exp.node,
61
- left = _exp$node2.left,
62
- right = _exp$node2.right;
63
- right.properties.forEach(function (prop) {
64
- var stmt = getContainingStatement(exp);
65
- stmt.insertBefore(j.assignmentStatement('=', j.memberExpression(left.object, renameKey(prop.key)), prop.value));
66
- });
67
- }); // 3. Remove the .story annotations
68
-
69
- storyAssignments.remove(); // 4. Replace each Foo.story.x with Foo.x;
70
-
71
- var storyOverrides = root.find(j.AssignmentExpression).filter(function (exp) {
72
- var left = exp.node.left;
73
- return left.type === 'MemberExpression' && left.object.type === 'MemberExpression' && left.object.property.type === 'Identifier' && left.object.property.name === 'story' && left.property.type === 'Identifier' // ?? ANNOTATION_FIELDS.includes(right.property.name)
74
- ;
75
- });
76
- storyOverrides.replaceWith(function (exp) {
77
- var _exp$node3 = exp.node,
78
- left = _exp$node3.left,
79
- right = _exp$node3.right;
80
- return j.assignmentExpression('=', j.memberExpression(left.object.object, renameKey(left.property)), right);
81
- }); // 4. Render the updated tree
82
-
83
- return root.toSource({
84
- quote: 'single'
85
- });
86
- }