@storybook/codemod 6.5.9 → 7.0.0-alpha.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }