@@ -2,13 +2,14 @@ import { logConfig } from 'storybook/internal/common';
22import { logger } from 'storybook/internal/node-logger' ;
33import { MissingBuilderError } from 'storybook/internal/server-errors' ;
44import type { Options } from 'storybook/internal/types' ;
5+ import { type ComponentManifestGenerator } from 'storybook/internal/types' ;
56
67import compression from '@polka/compression' ;
78import polka from 'polka' ;
89import invariant from 'tiny-invariant' ;
910
1011import { telemetry } from '../telemetry' ;
11- import type { StoryIndexGenerator } from './utils/StoryIndexGenerator' ;
12+ import { type StoryIndexGenerator } from './utils/StoryIndexGenerator' ;
1213import { doTelemetry } from './utils/doTelemetry' ;
1314import { getManagerBuilder , getPreviewBuilder } from './utils/get-builders' ;
1415import { getCachingMiddleware } from './utils/get-caching-middleware' ;
@@ -138,8 +139,35 @@ export async function storybookDevServer(options: Options) {
138139 throw indexError ;
139140 }
140141
142+ const features = await options . presets . apply ( 'features' ) ;
143+ if ( features ?. experimentalComponentsManifest ) {
144+ app . use ( '/manifests/components.json' , async ( req , res ) => {
145+ try {
146+ const componentManifestGenerator : ComponentManifestGenerator = await options . presets . apply (
147+ 'experimental_componentManifestGenerator'
148+ ) ;
149+ const indexGenerator = await initializedStoryIndexGenerator ;
150+ if ( componentManifestGenerator && indexGenerator ) {
151+ const manifest = await componentManifestGenerator (
152+ indexGenerator as unknown as import ( 'storybook/internal/core-server' ) . StoryIndexGenerator
153+ ) ;
154+ res . setHeader ( 'Content-Type' , 'application/json' ) ;
155+ res . end ( JSON . stringify ( manifest ) ) ;
156+ return ;
157+ }
158+ res . statusCode = 400 ;
159+ res . end ( 'No component manifest generator configured.' ) ;
160+ return ;
161+ } catch ( e ) {
162+ logger . error ( e instanceof Error ? e : String ( e ) ) ;
163+ res . statusCode = 500 ;
164+ res . end ( e instanceof Error ? e . toString ( ) : String ( e ) ) ;
165+ return ;
166+ }
167+ } ) ;
168+ }
141169 // Now the preview has successfully started, we can count this as a 'dev' event.
142- doTelemetry ( app , core , initializedStoryIndexGenerator , options ) ;
170+ doTelemetry ( app , core , initializedStoryIndexGenerator as Promise < StoryIndexGenerator > , options ) ;
143171
144172 async function cancelTelemetry ( ) {
145173 const payload = { eventType : 'dev' } ;
0 commit comments