-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
Expand file tree
/
Copy pathAddonConfigurationCommand.ts
More file actions
130 lines (111 loc) · 3.46 KB
/
AddonConfigurationCommand.ts
File metadata and controls
130 lines (111 loc) · 3.46 KB
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
import { AddonVitestService } from 'storybook/internal/cli';
import { type JsPackageManager } from 'storybook/internal/common';
import { CLI_COLORS, logger, prompt } from 'storybook/internal/node-logger';
import { ErrorCollector } from 'storybook/internal/telemetry';
import type { CommandOptions } from '../generators/types';
type ExecuteAddonConfigurationParams = {
packageManager: JsPackageManager;
addons: string[];
options: CommandOptions;
configDir?: string;
};
export type ExecuteAddonConfigurationResult = {
status: 'failed' | 'success';
};
/**
* Command for configuring Storybook addons
*
* Responsibilities:
*
* - Run postinstall scripts for test addons (a11y, vitest)
* - Configure addons without triggering installations
* - Handle configuration errors gracefully
*/
export class AddonConfigurationCommand {
constructor(private readonly addonVitestService = new AddonVitestService()) {}
/** Execute addon configuration */
async execute({
packageManager,
options,
addons,
configDir,
}: ExecuteAddonConfigurationParams): Promise<ExecuteAddonConfigurationResult> {
if (!configDir || addons.length === 0) {
return { status: 'success' };
}
try {
const { hasFailures, addonResults } = await this.configureAddons(
packageManager,
configDir,
addons,
options
);
if (addonResults.has('@storybook/addon-vitest')) {
await this.addonVitestService.installPlaywright(packageManager, {
yes: options.yes,
});
}
return { status: hasFailures ? 'failed' : 'success' };
} catch {
return { status: 'failed' };
}
}
/** Configure test addons (a11y and vitest) */
private async configureAddons(
packageManager: JsPackageManager,
configDir: string,
addons: string[],
options: CommandOptions
) {
// Import postinstallAddon from cli-storybook package
const { postinstallAddon } = await import('../../../cli-storybook/src/postinstallAddon');
const task = prompt.taskLog({
id: 'configure-addons',
title: 'Configuring addons...',
});
// Track failures for each addon
const addonResults = new Map<string, null | any>();
// Configure each addon
for (const addon of addons) {
try {
task.message(`Configuring ${addon}...`);
await postinstallAddon(addon, {
packageManager: packageManager.type,
configDir,
yes: options.yes,
skipInstall: true,
skipDependencyManagement: true,
logger,
prompt,
});
task.message(`${addon} configured\n`);
addonResults.set(addon, null);
} catch (e) {
ErrorCollector.addError(e);
addonResults.set(addon, e);
}
}
const hasFailures = [...addonResults.values()].some((result) => result !== null);
// Set final task status
if (hasFailures) {
task.error('Failed to configure addons');
} else {
task.success('Addons configured successfully');
}
// Log results for each addon
logger.log(
CLI_COLORS.dimmed(
addons
.map((addon) => {
const error = addonResults.get(addon);
return error ? `❌ ${addon}` : `✅ ${addon}`;
})
.join('\n')
)
);
return { hasFailures, addonResults };
}
}
export const executeAddonConfiguration = (params: ExecuteAddonConfigurationParams) => {
return new AddonConfigurationCommand().execute(params);
};