@storybook/codemod 7.0.0-beta.9 → 7.0.0-rc.0

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.
Files changed (55) hide show
  1. package/README.md +0 -39
  2. package/dist/index.js +1 -1
  3. package/dist/transforms/csf-2-to-3.d.ts +5 -4
  4. package/dist/transforms/csf-2-to-3.js +3 -1
  5. package/dist/transforms/mdx-to-csf.d.ts +7 -0
  6. package/dist/transforms/mdx-to-csf.js +55 -0
  7. package/dist/transforms/storiesof-to-csf.js +1 -1
  8. package/dist/transforms/upgrade-deprecated-types.d.ts +10 -0
  9. package/dist/transforms/upgrade-deprecated-types.js +2 -0
  10. package/jest.config.js +2 -0
  11. package/package.json +31 -16
  12. package/project.json +6 -0
  13. package/src/index.js +30 -4
  14. package/src/lib/utils.ts +2 -2
  15. package/src/transforms/__testfixtures__/storiesof-to-csf/decorators.input.js +1 -1
  16. package/src/transforms/__testfixtures__/storiesof-to-csf/export-function.input.js +1 -1
  17. package/src/transforms/__testfixtures__/storiesof-to-csf/story-decorators.input.js +1 -1
  18. package/src/transforms/__testfixtures__/update-addon-info/update-addon-info.input.js +34 -48
  19. package/src/transforms/__testfixtures__/update-addon-info/update-addon-info.output.snapshot +33 -47
  20. package/src/transforms/__tests__/csf-2-to-3.test.ts +170 -57
  21. package/src/transforms/__tests__/mdx-to-csf.test.ts +611 -0
  22. package/src/transforms/__tests__/upgrade-deprecated-types.test.ts +170 -0
  23. package/src/transforms/csf-2-to-3.ts +173 -37
  24. package/src/transforms/mdx-to-csf.ts +342 -0
  25. package/src/transforms/upgrade-deprecated-types.ts +142 -0
  26. package/dist/chunk-3OPQTROG.mjs +0 -1
  27. package/dist/chunk-B5FMQ3BX.mjs +0 -1
  28. package/dist/chunk-CO6EPEMB.mjs +0 -1
  29. package/dist/index.mjs +0 -1
  30. package/dist/transforms/add-component-parameters.mjs +0 -1
  31. package/dist/transforms/csf-2-to-3.mjs +0 -1
  32. package/dist/transforms/csf-hoist-story-annotations.mjs +0 -1
  33. package/dist/transforms/csf-to-mdx.d.ts +0 -29
  34. package/dist/transforms/csf-to-mdx.js +0 -3
  35. package/dist/transforms/csf-to-mdx.mjs +0 -3
  36. package/dist/transforms/move-builtin-addons.mjs +0 -1
  37. package/dist/transforms/storiesof-to-csf.mjs +0 -1
  38. package/dist/transforms/update-addon-info.mjs +0 -1
  39. package/dist/transforms/update-organisation-name.mjs +0 -1
  40. package/dist/transforms/upgrade-hierarchy-separators.mjs +0 -1
  41. package/src/transforms/__testfixtures__/csf-to-mdx/basic.input.js +0 -20
  42. package/src/transforms/__testfixtures__/csf-to-mdx/basic.output.snapshot +0 -18
  43. package/src/transforms/__testfixtures__/csf-to-mdx/component-id.input.js +0 -9
  44. package/src/transforms/__testfixtures__/csf-to-mdx/component-id.output.snapshot +0 -10
  45. package/src/transforms/__testfixtures__/csf-to-mdx/decorators.input.js +0 -13
  46. package/src/transforms/__testfixtures__/csf-to-mdx/decorators.output.snapshot +0 -12
  47. package/src/transforms/__testfixtures__/csf-to-mdx/exclude-stories.input.js +0 -23
  48. package/src/transforms/__testfixtures__/csf-to-mdx/exclude-stories.output.snapshot +0 -22
  49. package/src/transforms/__testfixtures__/csf-to-mdx/parameters.input.js +0 -16
  50. package/src/transforms/__testfixtures__/csf-to-mdx/parameters.output.snapshot +0 -17
  51. package/src/transforms/__testfixtures__/csf-to-mdx/story-function.input.js +0 -19
  52. package/src/transforms/__testfixtures__/csf-to-mdx/story-function.output.snapshot +0 -18
  53. package/src/transforms/__testfixtures__/csf-to-mdx/story-parameters.input.js +0 -24
  54. package/src/transforms/__testfixtures__/csf-to-mdx/story-parameters.output.snapshot +0 -22
  55. package/src/transforms/csf-to-mdx.js +0 -190
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- import Button from './Button';
3
-
4
- export default {
5
- title: 'Button',
6
- id: 'button-id',
7
- };
8
-
9
- export const someStory = () => <Button label="Story 1" />;
@@ -1,10 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "component-id.input.js" data 1`] = `
4
- "import Button from './Button';
5
- import { Meta, Story } from '@storybook/addon-docs';
6
-
7
- <Meta title='Button' id='button-id' />
8
-
9
- <Story name='someStory'><Button label='Story 1' /></Story>"
10
- `;
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import Button from './Button';
3
-
4
- export default {
5
- title: 'Some.Button',
6
- decorators: [withKnobs, storyFn => <div className="foo">{storyFn}</div>],
7
- };
8
-
9
- export const story1 = () => <Button label="The Button" />;
10
- story1.story = {
11
- name: 'with decorator',
12
- decorators: [withKnobs],
13
- };
@@ -1,12 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "decorators.input.js" data 1`] = `
4
- "import Button from './Button';
5
- import { Meta, Story } from '@storybook/addon-docs';
6
-
7
- <Meta
8
- title='Some.Button'
9
- decorators={[withKnobs, storyFn => <div className='foo'>{storyFn}</div>]} />
10
-
11
- <Story name='with decorator' decorators={[withKnobs]}><Button label='The Button' /></Story>"
12
- `;
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
- import Button from './Button';
3
- import { action } from '@storybook/addon-actions';
4
-
5
- export default {
6
- title: 'Button',
7
- excludeStories: /.*Data$/,
8
- };
9
-
10
- export const rowData = { col1: 'a', col2: 2 };
11
-
12
- export const story1 = () => <Button label="Story 1" />;
13
-
14
- export const story2 = () => <Button label="Story 2" onClick={action('click')} />;
15
- story2.story = { name: 'second story' };
16
-
17
- export const story3 = () => (
18
- <div>
19
- <Button label="The Button" onClick={action('onClick')} />
20
- <br />
21
- </div>
22
- );
23
- story3.story = { name: 'complex story' };
@@ -1,22 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "exclude-stories.input.js" data 1`] = `
4
- "import Button from './Button';
5
- import { action } from '@storybook/addon-actions';
6
- import { Meta, Story } from '@storybook/addon-docs';
7
-
8
- <Meta title='Button' />
9
-
10
- export const rowData = {
11
- col1: 'a',
12
- col2: 2,
13
- };
14
- <Story name='story1'><Button label='Story 1' /></Story>
15
-
16
- <Story name='second story'><Button label='Story 2' onClick={action('click')} /></Story>
17
-
18
- <Story name='complex story'><div>
19
- <Button label='The Button' onClick={action('onClick')} />
20
- <br />
21
- </div></Story>"
22
- `;
@@ -1,16 +0,0 @@
1
- import React from 'react';
2
- import Button from './Button';
3
-
4
- import { storiesOf } from '@storybook/react';
5
-
6
- export default {
7
- title: 'Button',
8
- component: Button,
9
- parameters: {
10
- foo: 1,
11
- bar: 2,
12
- },
13
- };
14
-
15
- export const story1 = () => <Button label="The Button" />;
16
- story1.story = { name: 'with kind parameters' };
@@ -1,17 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "parameters.input.js" data 1`] = `
4
- "import Button from './Button';
5
- import { storiesOf } from '@storybook/react';
6
- import { Meta, Story } from '@storybook/addon-docs';
7
-
8
- <Meta
9
- title='Button'
10
- component={Button}
11
- parameters={{
12
- foo: 1,
13
- bar: 2,
14
- }} />
15
-
16
- <Story name='with kind parameters'><Button label='The Button' /></Story>"
17
- `;
@@ -1,19 +0,0 @@
1
- import global from 'global';
2
-
3
- const { document } = global;
4
-
5
- export default {
6
- title: 'Function',
7
- };
8
-
9
- export const functionStory = () => {
10
- const btn = document.createElement('button');
11
- btn.innerHTML = 'Hello Button';
12
- btn.addEventListener('click', action('Click'));
13
- return btn;
14
- };
15
-
16
- functionStory.story = {
17
- name: 'function',
18
- height: '100px',
19
- };
@@ -1,18 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "story-function.input.js" data 1`] = `
4
- "import global from 'global';
5
- import { Meta, Story } from '@storybook/addon-docs';
6
-
7
- const {
8
- document,
9
- } = global;
10
- <Meta title='Function' />
11
-
12
- <Story name='function' height='100px'>{() => {
13
- const btn = document.createElement('button');
14
- btn.innerHTML = 'Hello Button';
15
- btn.addEventListener('click', action('Click'));
16
- return btn;
17
- }}</Story>"
18
- `;
@@ -1,24 +0,0 @@
1
- import React from 'react';
2
- import Button from './Button';
3
-
4
- import { storiesOf } from '@storybook/react';
5
-
6
- export default {
7
- title: 'Button',
8
- };
9
-
10
- export const story1 = () => <Button label="The Button" />;
11
- story1.story = {
12
- name: 'with story parameters',
13
- parameters: {
14
- header: false,
15
- inline: true,
16
- },
17
- };
18
-
19
- export const foo = () => <Button label="Foo" />;
20
- foo.story = {
21
- parameters: {
22
- bar: 1,
23
- },
24
- };
@@ -1,22 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`csf-to-mdx transforms correctly using "story-parameters.input.js" data 1`] = `
4
- "import Button from './Button';
5
- import { storiesOf } from '@storybook/react';
6
- import { Meta, Story } from '@storybook/addon-docs';
7
-
8
- <Meta title='Button' />
9
-
10
- <Story
11
- name='with story parameters'
12
- parameters={{
13
- header: false,
14
- inline: true,
15
- }}><Button label='The Button' /></Story>
16
-
17
- <Story
18
- name='foo'
19
- parameters={{
20
- bar: 1,
21
- }}><Button label='Foo' /></Story>"
22
- `;
@@ -1,190 +0,0 @@
1
- import { prettyPrint } from 'recast';
2
- import { isExportStory } from '@storybook/csf';
3
-
4
- function exportMdx(root, options) {
5
- // eslint-disable-next-line no-underscore-dangle
6
- const path = root.__paths[0];
7
-
8
- // FIXME: insert the title as markdown after all of the imports
9
- return path.node.program.body
10
- .map((n) => {
11
- const { code } = prettyPrint(n, options);
12
- if (n.type === 'JSXElement') {
13
- return `${code}\n`;
14
- }
15
- return code;
16
- })
17
- .join('\n');
18
- }
19
-
20
- function parseIncludeExclude(prop) {
21
- const { code } = prettyPrint(prop, {});
22
- // eslint-disable-next-line no-eval
23
- return (0, eval)(code);
24
- }
25
-
26
- /**
27
- * Convert a component's module story file into an MDX file
28
- *
29
- * For example:
30
- *
31
- * ```
32
- * input { Button } from './Button';
33
- * export default {
34
- * title: 'Button'
35
- * }
36
- * export const story = () => <Button label="The Button" />;
37
- * ```
38
- *
39
- * Becomes:
40
- *
41
- * ```
42
- * import { Meta, Story } from '@storybook/addon-docs';
43
- * input { Button } from './Button';
44
- *
45
- * <Meta title='Button' />
46
- *
47
- * <Story name='story'>
48
- * <Button label="The Button" />
49
- * </Story>
50
- * ```
51
- */
52
- export default function transformer(file, api) {
53
- const j = api.jscodeshift;
54
- const root = j(file.source);
55
-
56
- // FIXME: save out all the storyFn.story = { ... }
57
- const storyKeyToStory = {};
58
- // save out includeStories / excludeStories
59
- const meta = {};
60
-
61
- function makeAttr(key, val) {
62
- return j.jsxAttribute(
63
- j.jsxIdentifier(key),
64
- val.type === 'Literal' ? val : j.jsxExpressionContainer(val)
65
- );
66
- }
67
-
68
- function getStoryContents(node) {
69
- return node.type === 'ArrowFunctionExpression' && node.body.type === 'JSXElement'
70
- ? node.body
71
- : j.jsxExpressionContainer(node);
72
- }
73
-
74
- function getName(storyKey) {
75
- const story = storyKeyToStory[storyKey];
76
- if (story) {
77
- const name = story.properties.find((prop) => prop.key.name === 'name');
78
- if (name && name.value.type === 'Literal') {
79
- return name.value.value;
80
- }
81
- }
82
- return storyKey;
83
- }
84
-
85
- function getStoryAttrs(storyKey) {
86
- const attrs = [];
87
- const story = storyKeyToStory[storyKey];
88
- if (story) {
89
- story.properties.forEach((prop) => {
90
- const { key, value } = prop;
91
- if (key.name !== 'name') {
92
- attrs.push(makeAttr(key.name, value));
93
- }
94
- });
95
- }
96
- return attrs;
97
- }
98
-
99
- // 1. If the program does not have `export default { title: '....' }, skip it
100
- const defaultExportWithTitle = root
101
- .find(j.ExportDefaultDeclaration)
102
- .filter((def) => def.node.declaration.properties.map((p) => p.key.name).includes('title'));
103
- if (defaultExportWithTitle.size() === 0) {
104
- return root.toSource();
105
- }
106
-
107
- // 2a. Add imports from '@storybook/addon-docs'
108
- root
109
- .find(j.ImportDeclaration)
110
- .at(-1)
111
- .insertAfter(j.emptyStatement())
112
- .insertAfter(
113
- j.importDeclaration(
114
- [j.importSpecifier(j.identifier('Meta')), j.importSpecifier(j.identifier('Story'))],
115
- j.literal('@storybook/addon-docs')
116
- )
117
- );
118
- // 2b. Remove react import which is implicit
119
- root
120
- .find(j.ImportDeclaration)
121
- .filter((decl) => decl.node.source.value === 'react')
122
- .remove();
123
-
124
- // 3. Save out all the excluded stories
125
- defaultExportWithTitle.forEach((exp) => {
126
- exp.node.declaration.properties.forEach((p) => {
127
- if (['includeStories', 'excludeStories'].includes(p.key.name)) {
128
- meta[p.key.name] = parseIncludeExclude(p.value);
129
- }
130
- });
131
- });
132
-
133
- // 4. Collect all the story exports in storyKeyToStory[key] = null;
134
- const namedExports = root.find(j.ExportNamedDeclaration);
135
- namedExports.forEach((exp) => {
136
- const storyKey = exp.node.declaration.declarations[0].id.name;
137
- if (isExportStory(storyKey, meta)) {
138
- storyKeyToStory[storyKey] = null;
139
- }
140
- });
141
-
142
- // 5. Collect all the storyKey.story in storyKeyToStory and also remove them
143
- const storyAssignments = root.find(j.AssignmentExpression).filter((exp) => {
144
- const { left } = exp.node;
145
- return (
146
- left.type === 'MemberExpression' &&
147
- left.object.type === 'Identifier' &&
148
- left.object.name in storyKeyToStory &&
149
- left.property.type === 'Identifier' &&
150
- left.property.name === 'story'
151
- );
152
- });
153
- storyAssignments.forEach((exp) => {
154
- const { left, right } = exp.node;
155
- storyKeyToStory[left.object.name] = right;
156
- });
157
- storyAssignments.remove();
158
-
159
- // 6. Convert the default export to <Meta />
160
- defaultExportWithTitle.replaceWith((exp) => {
161
- const jsxId = j.jsxIdentifier('Meta');
162
- const attrs = [];
163
- exp.node.declaration.properties.forEach((prop) => {
164
- const { key, value } = prop;
165
- if (!['includeStories', 'excludeStories'].includes(key.name)) {
166
- attrs.push(makeAttr(key.name, value));
167
- }
168
- });
169
- const opening = j.jsxOpeningElement(jsxId, attrs);
170
- opening.selfClosing = true;
171
- return j.jsxElement(opening);
172
- });
173
-
174
- // 7. Convert all the named exports to <Story>...</Story>
175
- namedExports.replaceWith((exp) => {
176
- const storyKey = exp.node.declaration.declarations[0].id.name;
177
- if (!isExportStory(storyKey, meta)) {
178
- return exp.node;
179
- }
180
- const jsxId = j.jsxIdentifier('Story');
181
- const name = getName(storyKey);
182
- const attributes = [makeAttr('name', j.literal(name)), ...getStoryAttrs(storyKey)];
183
- const opening = j.jsxOpeningElement(jsxId, attributes);
184
- const closing = j.jsxClosingElement(jsxId);
185
- const children = [getStoryContents(exp.node.declaration.declarations[0].init)];
186
- return j.jsxElement(opening, closing, children);
187
- });
188
-
189
- return exportMdx(root, { quote: 'single', trailingComma: 'true', tabWidth: 2 });
190
- }