@storybook/codemod 7.0.0-alpha.39 → 7.0.0-alpha.40
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.
package/README.md
CHANGED
|
@@ -240,42 +240,6 @@ import { Meta, Story } from '@storybook/addon-docs';
|
|
|
240
240
|
</Story>
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
-
### mdx-to-csf
|
|
244
|
-
|
|
245
|
-
This converts all your MDX stories into Component Story Format.
|
|
246
|
-
|
|
247
|
-
```sh
|
|
248
|
-
./node_modules/.bin/jscodeshift -t ./node_modules/@storybook/codemod/dist/transforms/mdx-to-csf.js . --ignore-pattern "node_modules|dist" --extensions=mdx
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
For example:
|
|
252
|
-
|
|
253
|
-
```js
|
|
254
|
-
import React from 'react';
|
|
255
|
-
import Button from './Button';
|
|
256
|
-
import { Meta, Story } from '@storybook/addon-docs';
|
|
257
|
-
|
|
258
|
-
<Meta title='Button' />
|
|
259
|
-
|
|
260
|
-
<Story name='basic stories'><Button label='The Button' /></Story>
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Becomes:
|
|
264
|
-
|
|
265
|
-
```js
|
|
266
|
-
import React from 'react';
|
|
267
|
-
import Button from './Button';
|
|
268
|
-
|
|
269
|
-
export default {
|
|
270
|
-
title: 'Button',
|
|
271
|
-
};
|
|
272
|
-
|
|
273
|
-
export const basicStory = () => <Button label="The Button" />;
|
|
274
|
-
basicStory.story = {
|
|
275
|
-
name: 'basic stories',
|
|
276
|
-
};
|
|
277
|
-
```
|
|
278
|
-
|
|
279
243
|
### upgrade-hierarchy-separators
|
|
280
244
|
|
|
281
245
|
Starting in 5.3, Storybook is moving to using a single path separator, `/`, to specify the story hierarchy. It previously defaulted to `|` for story "roots" (optional) and either `/` or `.` for denoting paths. This codemod updates the old default to the new default.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/codemod",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.40",
|
|
4
4
|
"description": "A collection of codemod scripts written with JSCodeshift",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook"
|
|
@@ -38,10 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/types": "^7.12.11",
|
|
41
|
-
"@mdx-js/mdx": "^1.6.22",
|
|
42
41
|
"@storybook/csf": "0.0.2--canary.49.258942b.0",
|
|
43
|
-
"@storybook/csf-tools": "7.0.0-alpha.
|
|
44
|
-
"@storybook/node-logger": "7.0.0-alpha.
|
|
42
|
+
"@storybook/csf-tools": "7.0.0-alpha.40",
|
|
43
|
+
"@storybook/node-logger": "7.0.0-alpha.40",
|
|
45
44
|
"cross-spawn": "^7.0.3",
|
|
46
45
|
"globby": "^11.0.2",
|
|
47
46
|
"jscodeshift": "^0.13.1",
|
|
@@ -64,5 +63,5 @@
|
|
|
64
63
|
"./src/index.js"
|
|
65
64
|
]
|
|
66
65
|
},
|
|
67
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "8f6d8629f1ad7e776c39e2c7621f4a0d538aa93c"
|
|
68
67
|
}
|
|
@@ -9,6 +9,9 @@ const inputRegExp = /\.input\.js$/;
|
|
|
9
9
|
|
|
10
10
|
const fixturesDir = path.resolve(__dirname, '../__testfixtures__');
|
|
11
11
|
fs.readdirSync(fixturesDir).forEach((transformName) => {
|
|
12
|
+
// FIXME: delete after https://github.com/storybookjs/storybook/issues/19497
|
|
13
|
+
if (transformName === 'mdx-to-csf') return;
|
|
14
|
+
|
|
12
15
|
const transformFixturesDir = path.join(fixturesDir, transformName);
|
|
13
16
|
describe(transformName, () =>
|
|
14
17
|
fs
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
// import recast from 'recast';
|
|
2
|
-
import mdx from '@mdx-js/mdx';
|
|
3
|
-
import prettier from 'prettier';
|
|
4
|
-
import { sanitizeName } from '../lib/utils';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Convert a component's MDX file into module story format
|
|
8
|
-
*/
|
|
9
|
-
export default function transformer(file, api) {
|
|
10
|
-
const j = api.jscodeshift;
|
|
11
|
-
const code = mdx.sync(file.source, {});
|
|
12
|
-
const root = j(code);
|
|
13
|
-
|
|
14
|
-
function parseJsxAttributes(attributes) {
|
|
15
|
-
const result = {};
|
|
16
|
-
attributes.forEach((attr) => {
|
|
17
|
-
const key = attr.name.name;
|
|
18
|
-
const val = attr.value.type === 'JSXExpressionContainer' ? attr.value.expression : attr.value;
|
|
19
|
-
result[key] = val;
|
|
20
|
-
});
|
|
21
|
-
return result;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function genObjectExpression(attrs) {
|
|
25
|
-
return j.objectExpression(
|
|
26
|
-
Object.entries(attrs).map(([key, val]) => j.property('init', j.identifier(key), val))
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function convertToStories(path) {
|
|
31
|
-
const base = j(path);
|
|
32
|
-
|
|
33
|
-
const meta = {};
|
|
34
|
-
const includeStories = [];
|
|
35
|
-
const storyStatements = [];
|
|
36
|
-
|
|
37
|
-
// get rid of all mdxType junk
|
|
38
|
-
base
|
|
39
|
-
.find(j.JSXAttribute)
|
|
40
|
-
.filter((attr) => attr.node.name.name === 'mdxType')
|
|
41
|
-
.remove();
|
|
42
|
-
|
|
43
|
-
// parse <Meta title="..." />
|
|
44
|
-
base
|
|
45
|
-
.find(j.JSXElement)
|
|
46
|
-
.filter((elt) => elt.node.openingElement.name.name === 'Meta')
|
|
47
|
-
.forEach((elt) => {
|
|
48
|
-
const attrs = parseJsxAttributes(elt.node.openingElement.attributes);
|
|
49
|
-
Object.assign(meta, attrs);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// parse <Story name="..." />
|
|
53
|
-
base
|
|
54
|
-
.find(j.JSXElement)
|
|
55
|
-
.filter((elt) => elt.node.openingElement.name.name === 'Story')
|
|
56
|
-
.forEach((elt) => {
|
|
57
|
-
const attrs = parseJsxAttributes(elt.node.openingElement.attributes);
|
|
58
|
-
if (attrs.name) {
|
|
59
|
-
const storyKey = sanitizeName(attrs.name.value);
|
|
60
|
-
includeStories.push(storyKey);
|
|
61
|
-
if (storyKey === attrs.name.value) {
|
|
62
|
-
delete attrs.name;
|
|
63
|
-
}
|
|
64
|
-
let body =
|
|
65
|
-
elt.node.children.find((n) => n.type !== 'JSXText') ||
|
|
66
|
-
j.literal(elt.node.children[0].value);
|
|
67
|
-
|
|
68
|
-
if (body.type === 'JSXExpressionContainer') {
|
|
69
|
-
body = body.expression;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
storyStatements.push(
|
|
73
|
-
j.exportDeclaration(
|
|
74
|
-
false,
|
|
75
|
-
j.variableDeclaration('const', [
|
|
76
|
-
j.variableDeclarator(
|
|
77
|
-
j.identifier(storyKey),
|
|
78
|
-
body.type === 'ArrowFunctionExpression'
|
|
79
|
-
? body
|
|
80
|
-
: j.arrowFunctionExpression([], body)
|
|
81
|
-
),
|
|
82
|
-
])
|
|
83
|
-
)
|
|
84
|
-
);
|
|
85
|
-
if (Object.keys(attrs).length > 0) {
|
|
86
|
-
storyStatements.push(
|
|
87
|
-
j.assignmentStatement(
|
|
88
|
-
'=',
|
|
89
|
-
j.memberExpression(j.identifier(storyKey), j.identifier('story')),
|
|
90
|
-
genObjectExpression(attrs)
|
|
91
|
-
)
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
storyStatements.push(j.emptyStatement());
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
if (root.find(j.ExportNamedDeclaration).size() > 0) {
|
|
99
|
-
meta.includeStories = j.arrayExpression(includeStories.map((key) => j.literal(key)));
|
|
100
|
-
}
|
|
101
|
-
const statements = [
|
|
102
|
-
j.exportDefaultDeclaration(genObjectExpression(meta)),
|
|
103
|
-
j.emptyStatement(),
|
|
104
|
-
...storyStatements,
|
|
105
|
-
];
|
|
106
|
-
|
|
107
|
-
const lastStatement = root.find(j.Statement).at(-1);
|
|
108
|
-
statements.reverse().forEach((stmt) => {
|
|
109
|
-
lastStatement.insertAfter(stmt);
|
|
110
|
-
});
|
|
111
|
-
base.remove();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
root.find(j.ExportDefaultDeclaration).forEach(convertToStories);
|
|
115
|
-
|
|
116
|
-
// strip out Story/Meta import and MDX junk
|
|
117
|
-
|
|
118
|
-
// /* @jsx mdx */
|
|
119
|
-
root
|
|
120
|
-
.find(j.ImportDeclaration)
|
|
121
|
-
.at(0)
|
|
122
|
-
.replaceWith((exp) => j.importDeclaration(exp.node.specifiers, exp.node.source));
|
|
123
|
-
|
|
124
|
-
// import { Story, Meta } from '@storybook/addon-docs';
|
|
125
|
-
root
|
|
126
|
-
.find(j.ImportDeclaration)
|
|
127
|
-
.filter((exp) => exp.node.source.value === '@storybook/addon-docs')
|
|
128
|
-
.remove();
|
|
129
|
-
|
|
130
|
-
// const makeShortcode = ...
|
|
131
|
-
// const layoutProps = {};
|
|
132
|
-
// const MDXLayout = 'wrapper';
|
|
133
|
-
const MDX_DECLS = ['makeShortcode', 'layoutProps', 'MDXLayout'];
|
|
134
|
-
root
|
|
135
|
-
.find(j.VariableDeclaration)
|
|
136
|
-
.filter(
|
|
137
|
-
(decl) =>
|
|
138
|
-
decl.node.declarations.length === 1 && MDX_DECLS.includes(decl.node.declarations[0].id.name)
|
|
139
|
-
)
|
|
140
|
-
.remove();
|
|
141
|
-
|
|
142
|
-
// const Source = makeShortcode('Source');
|
|
143
|
-
root
|
|
144
|
-
.find(j.VariableDeclarator)
|
|
145
|
-
.filter(
|
|
146
|
-
(expr) =>
|
|
147
|
-
expr.node.init.type === 'CallExpression' &&
|
|
148
|
-
expr.node.init.callee.type === 'Identifier' &&
|
|
149
|
-
expr.node.init.callee.name === 'makeShortcode'
|
|
150
|
-
)
|
|
151
|
-
.remove();
|
|
152
|
-
|
|
153
|
-
// MDXContent.isMDXComponent = true;
|
|
154
|
-
root
|
|
155
|
-
.find(j.AssignmentExpression)
|
|
156
|
-
.filter(
|
|
157
|
-
(expr) =>
|
|
158
|
-
expr.node.left.type === 'MemberExpression' &&
|
|
159
|
-
expr.node.left.object.type === 'Identifier' &&
|
|
160
|
-
expr.node.left.object.name === 'MDXContent'
|
|
161
|
-
)
|
|
162
|
-
.remove();
|
|
163
|
-
|
|
164
|
-
// Add back `import React from 'react';` which is implicit in MDX
|
|
165
|
-
const react = root.find(j.ImportDeclaration).filter((decl) => decl.node.source.value === 'react');
|
|
166
|
-
if (react.size() === 0) {
|
|
167
|
-
root
|
|
168
|
-
.find(j.Statement)
|
|
169
|
-
.at(0)
|
|
170
|
-
.insertBefore(
|
|
171
|
-
j.importDeclaration([j.importDefaultSpecifier(j.identifier('React'))], j.literal('react'))
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const source = root.toSource({ trailingComma: true, quote: 'single', tabWidth: 2 });
|
|
176
|
-
return prettier.format(source, {
|
|
177
|
-
parser: 'babel',
|
|
178
|
-
printWidth: 100,
|
|
179
|
-
tabWidth: 2,
|
|
180
|
-
bracketSpacing: true,
|
|
181
|
-
trailingComma: 'es5',
|
|
182
|
-
singleQuote: true,
|
|
183
|
-
});
|
|
184
|
-
}
|