UNPKG

3.23 kBJavaScriptView Raw
1const {
2 toRequireContext,
3 ensureRelativePathHasDot,
4 getMain,
5 getPreviewExists,
6} = require('./common');
7const { normalizeStories, globToRegexp } = require('@storybook/core/common');
8const fs = require('fs');
9const prettier = require('prettier');
10const path = require('path');
11
12const cwd = process.cwd();
13
14function generate({ configPath, absolute = false, useJs = false }) {
15 const storybookRequiresLocation = path.resolve(
16 cwd,
17 configPath,
18 `storybook.requires.${useJs ? 'js' : 'ts'}`
19 );
20
21 const mainImport = getMain({ configPath });
22
23 const main = mainImport.default ?? mainImport;
24
25 // const reactNativeOptions = main.reactNativeOptions;
26
27 const storiesSpecifiers = normalizeStories(main.stories, {
28 configDir: configPath,
29 workingDir: cwd,
30 });
31
32 const normalizedStories = storiesSpecifiers.map((specifier) => {
33 // TODO why????
34 const reg = globToRegexp(`./${specifier.files}`);
35
36 const { path: p, recursive: r, match: m } = toRequireContext(specifier);
37
38 const pathToStory = ensureRelativePathHasDot(path.posix.relative(configPath, p));
39 return `{
40 titlePrefix: "${specifier.titlePrefix}",
41 directory: "${specifier.directory}",
42 files: "${specifier.files}",
43 importPathMatcher: /${reg.source}/,
44 ${useJs ? '' : '// @ts-ignore'}
45 req: require.context('${pathToStory}', ${r}, ${m})
46 }`;
47 });
48
49 const registerAddons = main.addons?.map((addon) => `import "${addon}/register";`).join('\n');
50
51 const doctools = 'require("@storybook/react-native/dist/preview")';
52
53 // TODO: implement presets or something similar
54 const enhancer = main.addons?.includes('@storybook/addon-ondevice-actions')
55 ? "require('@storybook/addon-actions/preview')"
56 : '';
57
58 let options = '';
59 let optionsVar = '';
60 const reactNativeOptions = main.reactNative;
61
62 if (reactNativeOptions && typeof reactNativeOptions === 'object') {
63 optionsVar = `const options = ${JSON.stringify(reactNativeOptions)}`;
64 options = 'options';
65 }
66
67 const previewExists = getPreviewExists({ configPath });
68
69 const annotations = `[${previewExists ? "require('./preview')," : ''}${doctools}, ${enhancer}]`;
70
71 const globalTypes = `
72 declare global {
73 var view: ReturnType<typeof start>;
74 var STORIES: typeof normalizedStories;
75 }
76 `;
77
78 const fileContent = `
79 /* do not change this file, it is auto generated by storybook. */
80
81 import { start, updateView } from '@storybook/react-native';
82
83 ${registerAddons}
84
85 const normalizedStories = [${normalizedStories.join(',')}];
86
87 ${useJs ? '' : globalTypes}
88
89 const annotations = ${annotations};
90
91 global.STORIES = normalizedStories;
92
93 ${useJs ? '' : '// @ts-ignore'}
94 module?.hot?.accept?.();
95
96 ${optionsVar}
97
98 if (!global.view) {
99 global.view = start({
100 annotations,
101 storyEntries: normalizedStories,
102 ${options}
103 });
104 } else {
105 updateView(global.view, annotations, normalizedStories, ${options});
106 }
107
108 export const view = global.view;
109`;
110
111 const formattedFileContent = prettier.format(fileContent, { parser: 'babel-ts' });
112
113 fs.writeFileSync(storybookRequiresLocation, formattedFileContent, {
114 encoding: 'utf8',
115 flag: 'w',
116 });
117}
118
119module.exports = {
120 generate,
121};