-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
Copy pathexample.ts
173 lines (157 loc) · 4.48 KB
/
example.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import path from 'path';
import { remove, pathExists } from 'fs-extra';
import prompts from 'prompts';
import { getOptionsOrPrompt } from './utils/options';
import { executeCLIStep } from './utils/cli-step';
import { exec } from '../code/lib/cli/src/repro-generators/scripts';
const frameworks = ['react', 'angular'];
const addons = ['a11y', 'storysource'];
const examplesDir = path.resolve(__dirname, '../examples');
const codeDir = path.resolve(__dirname, '../code');
async function getOptions() {
return getOptionsOrPrompt('yarn example', {
framework: {
description: 'Which framework would you like to use?',
values: frameworks,
required: true,
},
addon: {
description: 'Which extra addons (beyond the CLI defaults) would you like installed?',
values: addons,
multiple: true,
},
includeStories: {
description: "Include Storybook's own stories?",
promptType: (_, { framework }) => framework === 'react',
},
create: {
description: 'Create the example from scratch (rather than degitting it)?',
},
forceDelete: {
description: 'Always delete an existing example, even if it has the same configuration?',
promptType: false,
},
forceReuse: {
description: 'Always reuse an existing example, even if it has a different configuration?',
promptType: false,
},
link: {
description: 'Link the storybook to the local code?',
inverse: true,
},
start: {
description: 'Start the example Storybook?',
inverse: true,
},
build: {
description: 'Build the example Storybook?',
},
watch: {
description: 'Start building used packages in watch mode as well as the example Storybook?',
},
dryRun: {
description: "Don't execute commands, just list them (dry run)?",
},
});
}
const steps = {
repro: {
command: 'repro',
description: 'Bootstrapping example',
icon: '👷',
hasArgument: true,
options: {
template: { values: frameworks },
e2e: {},
},
},
add: {
command: 'add',
description: 'Adding addon',
icon: '+',
hasArgument: true,
options: {},
},
link: {
command: 'link',
description: 'Linking packages',
icon: '🔗',
hasArgument: true,
options: { local: {} },
},
build: {
command: 'build',
description: 'Building example',
icon: '🔨',
options: {},
},
dev: {
command: 'dev',
description: 'Starting example',
icon: '🖥 ',
options: {},
},
};
async function main() {
const optionValues = await getOptions();
const { framework, forceDelete, forceReuse, link, dryRun } = optionValues;
const cwd = path.join(examplesDir, framework as string);
const exists = await pathExists(cwd);
let shouldDelete = exists && !forceReuse;
if (exists && !forceDelete && !forceReuse) {
const relativePath = path.relative(process.cwd(), cwd);
({ shouldDelete } = await prompts({
type: 'toggle',
message: `${relativePath} already exists, should delete it and create a new one?`,
name: 'shouldDelete',
initial: false,
active: 'yes',
inactive: 'no',
}));
}
if (exists && shouldDelete && !dryRun) await remove(cwd);
if (!exists || shouldDelete) {
await executeCLIStep(steps.repro, {
argument: cwd,
optionValues: { template: framework },
cwd: examplesDir,
dryRun,
});
// TODO -- sb add <addon> doesn't actually work properly:
// - installs in `deps` not `devDeps`
// - does a `workspace:^` install (what does that mean?)
// - doesn't add to `main.js`
// eslint-disable-next-line no-restricted-syntax
for (const addon of optionValues.addon as string[]) {
const addonName = `@storybook/addon-${addon}`;
// eslint-disable-next-line no-await-in-loop
await executeCLIStep(steps.add, { argument: addonName, cwd, dryRun });
}
// TODO copy stories
if (link) {
await executeCLIStep(steps.link, {
argument: cwd,
cwd: codeDir,
dryRun,
optionValues: { local: true },
});
}
}
const { start } = optionValues;
if (start) {
await exec(
'yarn storybook',
{ cwd },
{
dryRun,
startMessage: `⬆️ Starting Storybook`,
errorMessage: `🚨 Starting Storybook failed`,
}
);
} else {
await executeCLIStep(steps.build, { cwd, dryRun });
// TODO serve
}
// TODO start dev
}
main().catch((err) => console.error(err));