@tpitre/story-ui 2.2.0 → 2.3.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.
- package/.env.sample +82 -11
- package/README.md +89 -0
- package/dist/cli/deploy.d.ts +17 -0
- package/dist/cli/deploy.d.ts.map +1 -0
- package/dist/cli/deploy.js +696 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +26 -2
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +437 -110
- package/dist/mcp-server/index.d.ts +2 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +120 -2
- package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
- package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
- package/dist/mcp-server/mcp-stdio-server.js +8 -1
- package/dist/mcp-server/routes/claude.d.ts +3 -0
- package/dist/mcp-server/routes/claude.d.ts.map +1 -0
- package/dist/mcp-server/routes/claude.js +60 -23
- package/dist/mcp-server/routes/components.d.ts +4 -0
- package/dist/mcp-server/routes/components.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.d.ts +38 -0
- package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
- package/dist/mcp-server/routes/frameworks.js +183 -0
- package/dist/mcp-server/routes/generateStory.d.ts +3 -0
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStory.js +160 -76
- package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
- package/dist/mcp-server/routes/generateStoryStream.js +947 -0
- package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
- package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
- package/dist/mcp-server/routes/mcpRemote.js +489 -0
- package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
- package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.d.ts +89 -0
- package/dist/mcp-server/routes/providers.d.ts.map +1 -0
- package/dist/mcp-server/routes/providers.js +369 -0
- package/dist/mcp-server/routes/storySync.d.ts +26 -0
- package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
- package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
- package/dist/mcp-server/routes/streamTypes.js +18 -0
- package/dist/mcp-server/sessionManager.d.ts +50 -0
- package/dist/mcp-server/sessionManager.d.ts.map +1 -0
- package/dist/story-generator/componentBlacklist.d.ts +21 -0
- package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
- package/dist/story-generator/componentDiscovery.d.ts +28 -0
- package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
- package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
- package/dist/story-generator/componentRegistryGenerator.js +205 -0
- package/dist/story-generator/configLoader.d.ts +33 -0
- package/dist/story-generator/configLoader.d.ts.map +1 -0
- package/dist/story-generator/considerationsLoader.d.ts +32 -0
- package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
- package/dist/story-generator/documentation-sources.d.ts +28 -0
- package/dist/story-generator/documentation-sources.d.ts.map +1 -0
- package/dist/story-generator/documentationLoader.d.ts +64 -0
- package/dist/story-generator/documentationLoader.d.ts.map +1 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
- package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
- package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
- package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
- package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
- package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
- package/dist/story-generator/framework-adapters/index.d.ts +97 -0
- package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/index.js +198 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
- package/dist/story-generator/framework-adapters/types.d.ts +182 -0
- package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/types.js +8 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
- package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
- package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
- package/dist/story-generator/generateStory.d.ts +7 -0
- package/dist/story-generator/generateStory.d.ts.map +1 -0
- package/dist/story-generator/gitignoreManager.d.ts +50 -0
- package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.d.ts +80 -0
- package/dist/story-generator/imageProcessor.d.ts.map +1 -0
- package/dist/story-generator/imageProcessor.js +391 -0
- package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
- package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
- package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/base-provider.js +135 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
- package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/claude-provider.js +414 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
- package/dist/story-generator/llm-providers/index.d.ts +63 -0
- package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/index.js +169 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
- package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/openai-provider.js +458 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
- package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/settings-manager.js +173 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
- package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
- package/dist/story-generator/llm-providers/types.d.ts +153 -0
- package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
- package/dist/story-generator/llm-providers/types.js +8 -0
- package/dist/story-generator/logger.d.ts +14 -0
- package/dist/story-generator/logger.d.ts.map +1 -0
- package/dist/story-generator/logger.js +96 -29
- package/dist/story-generator/postProcessStory.d.ts +6 -0
- package/dist/story-generator/postProcessStory.d.ts.map +1 -0
- package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
- package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.d.ts +48 -0
- package/dist/story-generator/promptGenerator.d.ts.map +1 -0
- package/dist/story-generator/promptGenerator.js +186 -1
- package/dist/story-generator/storyHistory.d.ts +44 -0
- package/dist/story-generator/storyHistory.d.ts.map +1 -0
- package/dist/story-generator/storySync.d.ts +68 -0
- package/dist/story-generator/storySync.d.ts.map +1 -0
- package/dist/story-generator/storyTracker.d.ts +48 -0
- package/dist/story-generator/storyTracker.d.ts.map +1 -0
- package/dist/story-generator/storyValidator.d.ts +6 -0
- package/dist/story-generator/storyValidator.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
- package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
- package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
- package/dist/story-generator/urlRedirectService.d.ts +21 -0
- package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
- package/dist/story-generator/validateStory.d.ts +19 -0
- package/dist/story-generator/validateStory.d.ts.map +1 -0
- package/dist/story-generator/validateStory.js +6 -2
- package/dist/story-generator/visionPrompts.d.ts +88 -0
- package/dist/story-generator/visionPrompts.d.ts.map +1 -0
- package/dist/story-generator/visionPrompts.js +462 -0
- package/dist/story-ui.config.d.ts +78 -0
- package/dist/story-ui.config.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
- package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
- package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
- package/dist/templates/StoryUI/index.d.ts +3 -0
- package/dist/templates/StoryUI/index.d.ts.map +1 -0
- package/dist/templates/StoryUI/index.js +2 -0
- package/package.json +17 -3
- package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
- package/templates/StoryUI/index.tsx +1 -1
- package/templates/StoryUI/manager.tsx +264 -0
- package/templates/production-app/.env.example +11 -0
- package/templates/production-app/index.html +66 -0
- package/templates/production-app/package.json +30 -0
- package/templates/production-app/public/favicon.svg +5 -0
- package/templates/production-app/src/App.tsx +1157 -0
- package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
- package/templates/production-app/src/componentRegistry.ts +315 -0
- package/templates/production-app/src/considerations.ts +16 -0
- package/templates/production-app/src/index.css +284 -0
- package/templates/production-app/src/main.tsx +25 -0
- package/templates/production-app/tsconfig.json +32 -0
- package/templates/production-app/tsconfig.node.json +11 -0
- package/templates/production-app/vite.config.ts +83 -0
- package/templates/react-import-rule.json +2 -2
- package/dist/index.js +0 -12
- package/dist/story-ui.config.loader.js +0 -205
|
@@ -260,17 +260,9 @@ export class EnhancedComponentDiscovery {
|
|
|
260
260
|
// Determine the project root from the generated stories path
|
|
261
261
|
const projectRoot = this.getProjectRoot();
|
|
262
262
|
const packagePath = path.join(projectRoot, 'node_modules', source.path);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
logger.log(`🔍 Dynamically discovering components from ${source.path}...`);
|
|
268
|
-
// Use dynamic discovery to get real exports
|
|
269
|
-
const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot);
|
|
270
|
-
const packageExports = await dynamicDiscovery.getRealPackageExports();
|
|
271
|
-
if (!packageExports) {
|
|
263
|
+
// Helper function to load known components as fallback
|
|
264
|
+
const loadFallbackComponents = () => {
|
|
272
265
|
logger.log(`📋 ${source.path}: Using static component list (design system detected)`);
|
|
273
|
-
// Fallback to predefined components if dynamic discovery fails
|
|
274
266
|
const knownComponents = this.getKnownDesignSystemComponents(source.path);
|
|
275
267
|
if (knownComponents.length > 0) {
|
|
276
268
|
for (const comp of knownComponents) {
|
|
@@ -281,7 +273,22 @@ export class EnhancedComponentDiscovery {
|
|
|
281
273
|
category: comp.category || this.categorizeComponent(comp.name || '', comp.description || '')
|
|
282
274
|
});
|
|
283
275
|
}
|
|
276
|
+
logger.log(`✅ Loaded ${knownComponents.length} known components for ${source.path}`);
|
|
284
277
|
}
|
|
278
|
+
};
|
|
279
|
+
if (!fs.existsSync(packagePath)) {
|
|
280
|
+
console.warn(`Package ${source.path} not found in node_modules at ${packagePath}`);
|
|
281
|
+
// Use fallback component list when package is not installed (e.g., in production)
|
|
282
|
+
loadFallbackComponents();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
logger.log(`🔍 Dynamically discovering components from ${source.path}...`);
|
|
286
|
+
// Use dynamic discovery to get real exports
|
|
287
|
+
const dynamicDiscovery = new DynamicPackageDiscovery(source.path, projectRoot);
|
|
288
|
+
const packageExports = await dynamicDiscovery.getRealPackageExports();
|
|
289
|
+
if (!packageExports) {
|
|
290
|
+
// Fallback to predefined components if dynamic discovery fails
|
|
291
|
+
loadFallbackComponents();
|
|
285
292
|
return;
|
|
286
293
|
}
|
|
287
294
|
// Process the real components found in the package
|
|
@@ -353,7 +360,100 @@ export class EnhancedComponentDiscovery {
|
|
|
353
360
|
category: this.categorizeComponent(name, '')
|
|
354
361
|
}));
|
|
355
362
|
}
|
|
356
|
-
//
|
|
363
|
+
// Mantine fallback components
|
|
364
|
+
if (packageName === '@mantine/core') {
|
|
365
|
+
const mantineComponents = [
|
|
366
|
+
// Layout
|
|
367
|
+
'Container', 'SimpleGrid', 'Grid', 'Group', 'Stack', 'Flex', 'Center', 'Space', 'Divider',
|
|
368
|
+
'AspectRatio', 'Box', 'AppShell', 'MediaQuery', 'Paper',
|
|
369
|
+
// Typography
|
|
370
|
+
'Text', 'Title', 'Anchor', 'Blockquote', 'Code', 'Highlight', 'Mark', 'List',
|
|
371
|
+
// Buttons & Actions
|
|
372
|
+
'Button', 'ActionIcon', 'CopyButton', 'FileButton', 'UnstyledButton', 'CloseButton',
|
|
373
|
+
// Inputs
|
|
374
|
+
'TextInput', 'NumberInput', 'PasswordInput', 'Textarea', 'Select', 'MultiSelect',
|
|
375
|
+
'Autocomplete', 'Checkbox', 'Switch', 'Radio', 'Slider', 'RangeSlider', 'Rating',
|
|
376
|
+
'SegmentedControl', 'ColorInput', 'ColorPicker', 'FileInput', 'JsonInput', 'PinInput',
|
|
377
|
+
'Chip', 'TransferList', 'NativeSelect',
|
|
378
|
+
// Navigation
|
|
379
|
+
'Anchor', 'Breadcrumbs', 'Burger', 'NavLink', 'Pagination', 'Stepper', 'Tabs',
|
|
380
|
+
// Data Display
|
|
381
|
+
'Accordion', 'Avatar', 'Badge', 'Card', 'Image', 'BackgroundImage', 'Indicator',
|
|
382
|
+
'Kbd', 'Spoiler', 'Table', 'ThemeIcon', 'Timeline', 'ColorSwatch',
|
|
383
|
+
// Overlays
|
|
384
|
+
'Dialog', 'Drawer', 'Modal', 'LoadingOverlay', 'Popover', 'Tooltip', 'Menu',
|
|
385
|
+
'HoverCard', 'Affix', 'Overlay',
|
|
386
|
+
// Feedback
|
|
387
|
+
'Alert', 'Loader', 'Notification', 'Progress', 'RingProgress', 'Skeleton',
|
|
388
|
+
// Misc
|
|
389
|
+
'Portal', 'Transition', 'ScrollArea', 'FocusTrap', 'Input', 'InputWrapper',
|
|
390
|
+
// Dates (from @mantine/dates)
|
|
391
|
+
'Calendar', 'DateInput', 'DatePicker', 'DateTimePicker', 'MonthPicker', 'YearPicker'
|
|
392
|
+
];
|
|
393
|
+
return mantineComponents.map(name => ({
|
|
394
|
+
name,
|
|
395
|
+
description: `${name} component from Mantine`,
|
|
396
|
+
category: this.categorizeComponent(name, '')
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
399
|
+
// Material UI fallback components
|
|
400
|
+
if (packageName === '@mui/material') {
|
|
401
|
+
const muiComponents = [
|
|
402
|
+
// Inputs
|
|
403
|
+
'Autocomplete', 'Button', 'ButtonGroup', 'Checkbox', 'Fab', 'Radio', 'RadioGroup',
|
|
404
|
+
'Rating', 'Select', 'Slider', 'Switch', 'TextField', 'ToggleButton', 'ToggleButtonGroup',
|
|
405
|
+
// Data Display
|
|
406
|
+
'Avatar', 'AvatarGroup', 'Badge', 'Chip', 'Divider', 'Icon', 'List', 'ListItem',
|
|
407
|
+
'ListItemText', 'ListItemIcon', 'ListItemButton', 'Table', 'TableBody', 'TableCell',
|
|
408
|
+
'TableContainer', 'TableHead', 'TableRow', 'Tooltip', 'Typography',
|
|
409
|
+
// Feedback
|
|
410
|
+
'Alert', 'AlertTitle', 'Backdrop', 'CircularProgress', 'Dialog', 'DialogActions',
|
|
411
|
+
'DialogContent', 'DialogContentText', 'DialogTitle', 'LinearProgress', 'Skeleton', 'Snackbar',
|
|
412
|
+
// Surfaces
|
|
413
|
+
'Accordion', 'AccordionActions', 'AccordionDetails', 'AccordionSummary', 'AppBar',
|
|
414
|
+
'Card', 'CardActions', 'CardContent', 'CardHeader', 'CardMedia', 'Paper', 'Toolbar',
|
|
415
|
+
// Navigation
|
|
416
|
+
'BottomNavigation', 'BottomNavigationAction', 'Breadcrumbs', 'Drawer', 'Link',
|
|
417
|
+
'Menu', 'MenuItem', 'MenuList', 'Pagination', 'SpeedDial', 'SpeedDialAction',
|
|
418
|
+
'SpeedDialIcon', 'Stepper', 'Step', 'StepLabel', 'Tabs', 'Tab',
|
|
419
|
+
// Layout
|
|
420
|
+
'Box', 'Container', 'Grid', 'Stack', 'ImageList', 'ImageListItem',
|
|
421
|
+
// Utils
|
|
422
|
+
'ClickAwayListener', 'Modal', 'NoSsr', 'Popover', 'Popper', 'Portal', 'Collapse', 'Fade', 'Grow', 'Slide', 'Zoom'
|
|
423
|
+
];
|
|
424
|
+
return muiComponents.map(name => ({
|
|
425
|
+
name,
|
|
426
|
+
description: `${name} component from Material UI`,
|
|
427
|
+
category: this.categorizeComponent(name, '')
|
|
428
|
+
}));
|
|
429
|
+
}
|
|
430
|
+
// Ant Design fallback components
|
|
431
|
+
if (packageName === 'antd') {
|
|
432
|
+
const antdComponents = [
|
|
433
|
+
// General
|
|
434
|
+
'Button', 'FloatButton', 'Icon', 'Typography', 'Text', 'Title', 'Paragraph', 'Link',
|
|
435
|
+
// Layout
|
|
436
|
+
'Divider', 'Flex', 'Grid', 'Row', 'Col', 'Layout', 'Header', 'Footer', 'Sider', 'Content', 'Space',
|
|
437
|
+
// Navigation
|
|
438
|
+
'Anchor', 'Breadcrumb', 'Dropdown', 'Menu', 'Pagination', 'Steps',
|
|
439
|
+
// Data Entry
|
|
440
|
+
'AutoComplete', 'Cascader', 'Checkbox', 'ColorPicker', 'DatePicker', 'Form',
|
|
441
|
+
'Input', 'InputNumber', 'Mentions', 'Radio', 'Rate', 'Select', 'Slider',
|
|
442
|
+
'Switch', 'TimePicker', 'Transfer', 'TreeSelect', 'Upload',
|
|
443
|
+
// Data Display
|
|
444
|
+
'Avatar', 'Badge', 'Calendar', 'Card', 'Carousel', 'Collapse', 'Descriptions',
|
|
445
|
+
'Empty', 'Image', 'List', 'Popover', 'QRCode', 'Segmented', 'Statistic',
|
|
446
|
+
'Table', 'Tabs', 'Tag', 'Timeline', 'Tooltip', 'Tour', 'Tree',
|
|
447
|
+
// Feedback
|
|
448
|
+
'Alert', 'Drawer', 'Message', 'Modal', 'Notification', 'Popconfirm', 'Progress',
|
|
449
|
+
'Result', 'Skeleton', 'Spin', 'Watermark'
|
|
450
|
+
];
|
|
451
|
+
return antdComponents.map(name => ({
|
|
452
|
+
name,
|
|
453
|
+
description: `${name} component from Ant Design`,
|
|
454
|
+
category: this.categorizeComponent(name, '')
|
|
455
|
+
}));
|
|
456
|
+
}
|
|
357
457
|
// Default: return empty array
|
|
358
458
|
return [];
|
|
359
459
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Angular Framework Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates Storybook stories for Angular components.
|
|
5
|
+
* Supports standalone components and module-based components.
|
|
6
|
+
*/
|
|
7
|
+
import { FrameworkType, StoryFramework, StoryGenerationOptions } from './types.js';
|
|
8
|
+
import { BaseFrameworkAdapter } from './base-adapter.js';
|
|
9
|
+
import { StoryUIConfig } from '../../story-ui.config.js';
|
|
10
|
+
import { DiscoveredComponent } from '../componentDiscovery.js';
|
|
11
|
+
export declare class AngularAdapter extends BaseFrameworkAdapter {
|
|
12
|
+
readonly type: FrameworkType;
|
|
13
|
+
readonly name = "Angular";
|
|
14
|
+
readonly supportedStoryFrameworks: StoryFramework[];
|
|
15
|
+
readonly defaultExtension = ".stories.ts";
|
|
16
|
+
generateSystemPrompt(config: StoryUIConfig, options?: StoryGenerationOptions): string;
|
|
17
|
+
generateExamples(config: StoryUIConfig): string;
|
|
18
|
+
generateSampleStory(config: StoryUIConfig, components: DiscoveredComponent[]): string;
|
|
19
|
+
getStoryTemplate(options?: StoryGenerationOptions): string;
|
|
20
|
+
/**
|
|
21
|
+
* Convert PascalCase to kebab-case for selectors
|
|
22
|
+
*/
|
|
23
|
+
private toKebabCase;
|
|
24
|
+
/**
|
|
25
|
+
* Post-process Angular stories
|
|
26
|
+
*/
|
|
27
|
+
postProcess(storyContent: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Validate Angular story
|
|
30
|
+
*/
|
|
31
|
+
validate(storyContent: string): {
|
|
32
|
+
valid: boolean;
|
|
33
|
+
errors: string[];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Factory function
|
|
38
|
+
*/
|
|
39
|
+
export declare function createAngularAdapter(): AngularAdapter;
|
|
40
|
+
//# sourceMappingURL=angular-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular-adapter.d.ts","sourceRoot":"","sources":["../../../story-generator/framework-adapters/angular-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,cAAc,EACd,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,qBAAa,cAAe,SAAQ,oBAAoB;IACtD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAa;IACzC,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,cAAc,EAAE,CAGjD;IACF,QAAQ,CAAC,gBAAgB,iBAAiB;IAE1C,oBAAoB,CAClB,MAAM,EAAE,aAAa,EACrB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,MAAM;IA0HT,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IA+J/C,mBAAmB,CACjB,MAAM,EAAE,aAAa,EACrB,UAAU,EAAE,mBAAmB,EAAE,GAChC,MAAM;IAqDT,gBAAgB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM;IA4B1D;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAkBzC;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;CA2BrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAErD"}
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Angular Framework Adapter
|
|
3
|
+
*
|
|
4
|
+
* Generates Storybook stories for Angular components.
|
|
5
|
+
* Supports standalone components and module-based components.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseFrameworkAdapter } from './base-adapter.js';
|
|
8
|
+
export class AngularAdapter extends BaseFrameworkAdapter {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.type = 'angular';
|
|
12
|
+
this.name = 'Angular';
|
|
13
|
+
this.supportedStoryFrameworks = [
|
|
14
|
+
'storybook-angular',
|
|
15
|
+
'chromatic',
|
|
16
|
+
];
|
|
17
|
+
this.defaultExtension = '.stories.ts';
|
|
18
|
+
}
|
|
19
|
+
generateSystemPrompt(config, options) {
|
|
20
|
+
if (config.systemPrompt) {
|
|
21
|
+
return config.systemPrompt;
|
|
22
|
+
}
|
|
23
|
+
const componentSystemName = config.componentPrefix
|
|
24
|
+
? `${config.componentPrefix.replace(/^[A-Z]+/, '')} design system`
|
|
25
|
+
: 'component library';
|
|
26
|
+
return `You are an expert Angular developer creating Storybook stories using CSF 3.0 format.
|
|
27
|
+
Use ONLY the Angular components from the ${componentSystemName} listed below.
|
|
28
|
+
|
|
29
|
+
MANDATORY IMPORTS - First lines of every story file:
|
|
30
|
+
1. import type { Meta, StoryObj } from '@storybook/angular';
|
|
31
|
+
2. import { ComponentName } from '${config.importPath || 'your-library'}';
|
|
32
|
+
|
|
33
|
+
ANGULAR STORY FORMAT:
|
|
34
|
+
- Use moduleMetadata for imports and providers
|
|
35
|
+
- Components can be standalone or module-based
|
|
36
|
+
- Use applicationConfig for standalone components
|
|
37
|
+
|
|
38
|
+
STORY STRUCTURE (CSF 3.0):
|
|
39
|
+
- Meta object with component, title, and decorators
|
|
40
|
+
- Use render function for template customization
|
|
41
|
+
- Export named stories as StoryObj
|
|
42
|
+
|
|
43
|
+
CRITICAL RULES:
|
|
44
|
+
- Import modules/components in moduleMetadata or applicationConfig
|
|
45
|
+
- Use Angular template syntax in render functions
|
|
46
|
+
- Event bindings use (event) syntax
|
|
47
|
+
|
|
48
|
+
Example structure (Standalone Components):
|
|
49
|
+
\`\`\`typescript
|
|
50
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
51
|
+
import { applicationConfig, argsToTemplate } from '@storybook/angular';
|
|
52
|
+
import { ButtonComponent } from 'your-library';
|
|
53
|
+
|
|
54
|
+
const meta: Meta<ButtonComponent> = {
|
|
55
|
+
title: 'Components/Button',
|
|
56
|
+
component: ButtonComponent,
|
|
57
|
+
tags: ['autodocs'],
|
|
58
|
+
decorators: [
|
|
59
|
+
applicationConfig({
|
|
60
|
+
providers: [],
|
|
61
|
+
}),
|
|
62
|
+
],
|
|
63
|
+
argTypes: {
|
|
64
|
+
variant: {
|
|
65
|
+
control: 'select',
|
|
66
|
+
options: ['primary', 'secondary', 'ghost'],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default meta;
|
|
72
|
+
type Story = StoryObj<ButtonComponent>;
|
|
73
|
+
|
|
74
|
+
export const Primary: Story = {
|
|
75
|
+
args: {
|
|
76
|
+
variant: 'primary',
|
|
77
|
+
label: 'Click me',
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const WithContent: Story = {
|
|
82
|
+
render: (args) => ({
|
|
83
|
+
props: args,
|
|
84
|
+
template: \`
|
|
85
|
+
<app-button [variant]="variant">
|
|
86
|
+
<span class="icon">★</span>
|
|
87
|
+
Click me
|
|
88
|
+
</app-button>
|
|
89
|
+
\`,
|
|
90
|
+
}),
|
|
91
|
+
};
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
Example structure (Module-based Components):
|
|
95
|
+
\`\`\`typescript
|
|
96
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
97
|
+
import { moduleMetadata } from '@storybook/angular';
|
|
98
|
+
import { ButtonModule } from 'your-library';
|
|
99
|
+
|
|
100
|
+
const meta: Meta = {
|
|
101
|
+
title: 'Components/Button',
|
|
102
|
+
decorators: [
|
|
103
|
+
moduleMetadata({
|
|
104
|
+
imports: [ButtonModule],
|
|
105
|
+
}),
|
|
106
|
+
],
|
|
107
|
+
argTypes: {
|
|
108
|
+
variant: {
|
|
109
|
+
control: 'select',
|
|
110
|
+
options: ['primary', 'secondary', 'ghost'],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export default meta;
|
|
116
|
+
type Story = StoryObj;
|
|
117
|
+
|
|
118
|
+
export const Primary: Story = {
|
|
119
|
+
render: (args) => ({
|
|
120
|
+
props: args,
|
|
121
|
+
template: \`<app-button [variant]="variant">Click me</app-button>\`,
|
|
122
|
+
}),
|
|
123
|
+
};
|
|
124
|
+
\`\`\`
|
|
125
|
+
|
|
126
|
+
ANGULAR TEMPLATE SYNTAX:
|
|
127
|
+
- Property binding: [property]="value"
|
|
128
|
+
- Event binding: (event)="handler($event)"
|
|
129
|
+
- Two-way binding: [(ngModel)]="value"
|
|
130
|
+
- Structural directives: *ngIf, *ngFor, *ngSwitch
|
|
131
|
+
|
|
132
|
+
CONTENT PROJECTION (ng-content):
|
|
133
|
+
- Default slot: Content between tags
|
|
134
|
+
- Named slots: Use ngProjectAs or select attribute
|
|
135
|
+
|
|
136
|
+
${this.getCommonRules()}`;
|
|
137
|
+
}
|
|
138
|
+
generateExamples(config) {
|
|
139
|
+
const lib = config.importPath || 'your-library';
|
|
140
|
+
return `
|
|
141
|
+
## Example Stories for Angular
|
|
142
|
+
|
|
143
|
+
### Standalone Component
|
|
144
|
+
\`\`\`typescript
|
|
145
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
146
|
+
import { applicationConfig } from '@storybook/angular';
|
|
147
|
+
import { ButtonComponent } from 'your-library';
|
|
148
|
+
|
|
149
|
+
const meta: Meta<ButtonComponent> = {
|
|
150
|
+
title: 'Components/Button',
|
|
151
|
+
component: ButtonComponent,
|
|
152
|
+
tags: ['autodocs'],
|
|
153
|
+
decorators: [
|
|
154
|
+
applicationConfig({
|
|
155
|
+
providers: [],
|
|
156
|
+
}),
|
|
157
|
+
],
|
|
158
|
+
argTypes: {
|
|
159
|
+
variant: {
|
|
160
|
+
control: 'select',
|
|
161
|
+
options: ['primary', 'secondary', 'ghost'],
|
|
162
|
+
},
|
|
163
|
+
size: {
|
|
164
|
+
control: 'select',
|
|
165
|
+
options: ['small', 'medium', 'large'],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export default meta;
|
|
171
|
+
type Story = StoryObj<ButtonComponent>;
|
|
172
|
+
|
|
173
|
+
export const Default: Story = {
|
|
174
|
+
args: {
|
|
175
|
+
variant: 'primary',
|
|
176
|
+
size: 'medium',
|
|
177
|
+
label: 'Button',
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const AllVariants: Story = {
|
|
182
|
+
render: () => ({
|
|
183
|
+
template: \`
|
|
184
|
+
<div style="display: flex; gap: 8px;">
|
|
185
|
+
<app-button variant="primary">Primary</app-button>
|
|
186
|
+
<app-button variant="secondary">Secondary</app-button>
|
|
187
|
+
<app-button variant="ghost">Ghost</app-button>
|
|
188
|
+
</div>
|
|
189
|
+
\`,
|
|
190
|
+
}),
|
|
191
|
+
};
|
|
192
|
+
\`\`\`
|
|
193
|
+
|
|
194
|
+
### Module-based Component
|
|
195
|
+
\`\`\`typescript
|
|
196
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
197
|
+
import { moduleMetadata } from '@storybook/angular';
|
|
198
|
+
import { CardModule, ButtonModule } from '${lib}';
|
|
199
|
+
|
|
200
|
+
const meta: Meta = {
|
|
201
|
+
title: 'Components/Card',
|
|
202
|
+
decorators: [
|
|
203
|
+
moduleMetadata({
|
|
204
|
+
imports: [CardModule, ButtonModule],
|
|
205
|
+
}),
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export default meta;
|
|
210
|
+
type Story = StoryObj;
|
|
211
|
+
|
|
212
|
+
export const ProductCard: Story = {
|
|
213
|
+
render: () => ({
|
|
214
|
+
template: \`
|
|
215
|
+
<app-card style="width: 300px">
|
|
216
|
+
<img appCardImage src="https://picsum.photos/300/200" alt="Product">
|
|
217
|
+
<h3 appCardTitle>Product Name</h3>
|
|
218
|
+
<p appCardContent>$99.00</p>
|
|
219
|
+
<app-button appCardAction variant="primary">Add to Cart</app-button>
|
|
220
|
+
</app-card>
|
|
221
|
+
\`,
|
|
222
|
+
}),
|
|
223
|
+
};
|
|
224
|
+
\`\`\`
|
|
225
|
+
|
|
226
|
+
### With Event Handling
|
|
227
|
+
\`\`\`typescript
|
|
228
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
229
|
+
import { applicationConfig } from '@storybook/angular';
|
|
230
|
+
import { action } from '@storybook/addon-actions';
|
|
231
|
+
import { ButtonComponent } from 'your-library';
|
|
232
|
+
|
|
233
|
+
const meta: Meta<ButtonComponent> = {
|
|
234
|
+
title: 'Components/Button',
|
|
235
|
+
component: ButtonComponent,
|
|
236
|
+
decorators: [
|
|
237
|
+
applicationConfig({
|
|
238
|
+
providers: [],
|
|
239
|
+
}),
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
export default meta;
|
|
244
|
+
type Story = StoryObj<ButtonComponent>;
|
|
245
|
+
|
|
246
|
+
export const WithClick: Story = {
|
|
247
|
+
render: () => ({
|
|
248
|
+
props: {
|
|
249
|
+
onClick: action('button-click'),
|
|
250
|
+
},
|
|
251
|
+
template: \`
|
|
252
|
+
<app-button (click)="onClick($event)" variant="primary">
|
|
253
|
+
Click me
|
|
254
|
+
</app-button>
|
|
255
|
+
\`,
|
|
256
|
+
}),
|
|
257
|
+
};
|
|
258
|
+
\`\`\`
|
|
259
|
+
|
|
260
|
+
### With Forms
|
|
261
|
+
\`\`\`typescript
|
|
262
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
263
|
+
import { moduleMetadata } from '@storybook/angular';
|
|
264
|
+
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
265
|
+
import { InputModule } from '${lib}';
|
|
266
|
+
|
|
267
|
+
const meta: Meta = {
|
|
268
|
+
title: 'Components/Input',
|
|
269
|
+
decorators: [
|
|
270
|
+
moduleMetadata({
|
|
271
|
+
imports: [FormsModule, ReactiveFormsModule, InputModule],
|
|
272
|
+
}),
|
|
273
|
+
],
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export default meta;
|
|
277
|
+
type Story = StoryObj;
|
|
278
|
+
|
|
279
|
+
export const WithNgModel: Story = {
|
|
280
|
+
render: () => ({
|
|
281
|
+
props: {
|
|
282
|
+
value: '',
|
|
283
|
+
},
|
|
284
|
+
template: \`
|
|
285
|
+
<div>
|
|
286
|
+
<app-input [(ngModel)]="value" placeholder="Type here..."></app-input>
|
|
287
|
+
<p>Value: {{ value }}</p>
|
|
288
|
+
</div>
|
|
289
|
+
\`,
|
|
290
|
+
}),
|
|
291
|
+
};
|
|
292
|
+
\`\`\`
|
|
293
|
+
`;
|
|
294
|
+
}
|
|
295
|
+
generateSampleStory(config, components) {
|
|
296
|
+
const lib = config.importPath || 'your-library';
|
|
297
|
+
const firstComponent = components[0];
|
|
298
|
+
if (!firstComponent) {
|
|
299
|
+
return `
|
|
300
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
301
|
+
|
|
302
|
+
const meta: Meta = {
|
|
303
|
+
title: 'Examples/Sample',
|
|
304
|
+
parameters: { layout: 'centered' },
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export default meta;
|
|
308
|
+
type Story = StoryObj;
|
|
309
|
+
|
|
310
|
+
export const Default: Story = {
|
|
311
|
+
render: () => ({
|
|
312
|
+
template: '<div>Sample story content</div>',
|
|
313
|
+
}),
|
|
314
|
+
};
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
// Convert PascalCase to kebab-case for selector
|
|
318
|
+
const selector = this.toKebabCase(firstComponent.name);
|
|
319
|
+
return `
|
|
320
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
321
|
+
import { applicationConfig } from '@storybook/angular';
|
|
322
|
+
import { ${firstComponent.name}Component } from '${lib}';
|
|
323
|
+
|
|
324
|
+
const meta: Meta<${firstComponent.name}Component> = {
|
|
325
|
+
title: 'Components/${firstComponent.name}',
|
|
326
|
+
component: ${firstComponent.name}Component,
|
|
327
|
+
tags: ['autodocs'],
|
|
328
|
+
decorators: [
|
|
329
|
+
applicationConfig({
|
|
330
|
+
providers: [],
|
|
331
|
+
}),
|
|
332
|
+
],
|
|
333
|
+
parameters: { layout: 'centered' },
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
export default meta;
|
|
337
|
+
type Story = StoryObj<${firstComponent.name}Component>;
|
|
338
|
+
|
|
339
|
+
export const Default: Story = {
|
|
340
|
+
args: {},
|
|
341
|
+
};
|
|
342
|
+
`;
|
|
343
|
+
}
|
|
344
|
+
getStoryTemplate(options) {
|
|
345
|
+
return `
|
|
346
|
+
// {{componentName}}.stories.ts
|
|
347
|
+
import type { Meta, StoryObj } from '@storybook/angular';
|
|
348
|
+
import { applicationConfig } from '@storybook/angular';
|
|
349
|
+
import { {{componentName}}Component } from '{{importPath}}';
|
|
350
|
+
|
|
351
|
+
const meta: Meta<{{componentName}}Component> = {
|
|
352
|
+
title: '{{category}}/{{componentName}}',
|
|
353
|
+
component: {{componentName}}Component,
|
|
354
|
+
tags: ['autodocs'],
|
|
355
|
+
decorators: [
|
|
356
|
+
applicationConfig({
|
|
357
|
+
providers: [],
|
|
358
|
+
}),
|
|
359
|
+
],
|
|
360
|
+
parameters: { layout: 'centered' },
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
export default meta;
|
|
364
|
+
type Story = StoryObj<{{componentName}}Component>;
|
|
365
|
+
|
|
366
|
+
export const Default: Story = {
|
|
367
|
+
args: {},
|
|
368
|
+
};
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Convert PascalCase to kebab-case for selectors
|
|
373
|
+
*/
|
|
374
|
+
toKebabCase(str) {
|
|
375
|
+
return str
|
|
376
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
377
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
378
|
+
.toLowerCase();
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Post-process Angular stories
|
|
382
|
+
*/
|
|
383
|
+
postProcess(storyContent) {
|
|
384
|
+
let processed = super.postProcess(storyContent);
|
|
385
|
+
// Remove React imports if present
|
|
386
|
+
processed = processed.replace(/import React from ['"]react['"];?\n?/g, '');
|
|
387
|
+
// Fix JSX to Angular template syntax
|
|
388
|
+
processed = processed
|
|
389
|
+
// Fix className to class
|
|
390
|
+
.replace(/className=/g, 'class=')
|
|
391
|
+
// Fix onClick to (click)
|
|
392
|
+
.replace(/onClick=/g, '(click)=')
|
|
393
|
+
.replace(/onChange=/g, '(change)=')
|
|
394
|
+
.replace(/onInput=/g, '(input)=');
|
|
395
|
+
return processed;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Validate Angular story
|
|
399
|
+
*/
|
|
400
|
+
validate(storyContent) {
|
|
401
|
+
const baseValidation = super.validate(storyContent);
|
|
402
|
+
const errors = [...baseValidation.errors];
|
|
403
|
+
// Angular-specific validations
|
|
404
|
+
if (!storyContent.includes('@storybook/angular')) {
|
|
405
|
+
errors.push("Missing '@storybook/angular' import");
|
|
406
|
+
}
|
|
407
|
+
if (storyContent.includes("import React from 'react'")) {
|
|
408
|
+
errors.push('React import found in Angular story');
|
|
409
|
+
}
|
|
410
|
+
// Check for neither moduleMetadata nor applicationConfig
|
|
411
|
+
if (!storyContent.includes('moduleMetadata') &&
|
|
412
|
+
!storyContent.includes('applicationConfig') &&
|
|
413
|
+
!storyContent.includes('component:')) {
|
|
414
|
+
errors.push('Missing moduleMetadata or applicationConfig decorator');
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
valid: errors.length === 0,
|
|
418
|
+
errors,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Factory function
|
|
424
|
+
*/
|
|
425
|
+
export function createAngularAdapter() {
|
|
426
|
+
return new AngularAdapter();
|
|
427
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Framework Adapter
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class that provides common functionality for all
|
|
5
|
+
* framework-specific adapters. Subclasses implement framework-specific
|
|
6
|
+
* prompt generation and story templates.
|
|
7
|
+
*/
|
|
8
|
+
import { FrameworkType, StoryFramework, FrameworkAdapter, StoryGenerationOptions } from './types.js';
|
|
9
|
+
import { StoryUIConfig } from '../../story-ui.config.js';
|
|
10
|
+
import { DiscoveredComponent } from '../componentDiscovery.js';
|
|
11
|
+
/**
|
|
12
|
+
* Abstract Base Framework Adapter
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class BaseFrameworkAdapter implements FrameworkAdapter {
|
|
15
|
+
abstract readonly type: FrameworkType;
|
|
16
|
+
abstract readonly name: string;
|
|
17
|
+
abstract readonly supportedStoryFrameworks: StoryFramework[];
|
|
18
|
+
abstract readonly defaultExtension: string;
|
|
19
|
+
/**
|
|
20
|
+
* Generate the system prompt for this framework
|
|
21
|
+
*/
|
|
22
|
+
abstract generateSystemPrompt(config: StoryUIConfig, options?: StoryGenerationOptions): string;
|
|
23
|
+
/**
|
|
24
|
+
* Generate component reference documentation
|
|
25
|
+
*/
|
|
26
|
+
generateComponentReference(components: DiscoveredComponent[], config: StoryUIConfig): string;
|
|
27
|
+
/**
|
|
28
|
+
* Format a single component entry
|
|
29
|
+
*/
|
|
30
|
+
protected formatComponentEntry(component: DiscoveredComponent, config: StoryUIConfig): string;
|
|
31
|
+
/**
|
|
32
|
+
* Get the import path for a component
|
|
33
|
+
*/
|
|
34
|
+
protected getImportPath(component: DiscoveredComponent, config: StoryUIConfig): string;
|
|
35
|
+
/**
|
|
36
|
+
* Group components by their category
|
|
37
|
+
*/
|
|
38
|
+
protected groupComponentsByPackage(components: DiscoveredComponent[]): Record<string, DiscoveredComponent[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Generate example stories - framework specific
|
|
41
|
+
*/
|
|
42
|
+
abstract generateExamples(config: StoryUIConfig): string;
|
|
43
|
+
/**
|
|
44
|
+
* Generate a sample story template - framework specific
|
|
45
|
+
*/
|
|
46
|
+
abstract generateSampleStory(config: StoryUIConfig, components: DiscoveredComponent[]): string;
|
|
47
|
+
/**
|
|
48
|
+
* Generate import statements for components
|
|
49
|
+
*/
|
|
50
|
+
generateImports(components: DiscoveredComponent[], config: StoryUIConfig): string;
|
|
51
|
+
/**
|
|
52
|
+
* Post-process generated story content
|
|
53
|
+
*/
|
|
54
|
+
postProcess(storyContent: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Validate generated story syntax
|
|
57
|
+
*/
|
|
58
|
+
validate(storyContent: string): {
|
|
59
|
+
valid: boolean;
|
|
60
|
+
errors: string[];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Get the story file template - framework specific
|
|
64
|
+
*/
|
|
65
|
+
abstract getStoryTemplate(options?: StoryGenerationOptions): string;
|
|
66
|
+
/**
|
|
67
|
+
* Log adapter activity
|
|
68
|
+
*/
|
|
69
|
+
protected log(message: string, data?: Record<string, unknown>): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get common story structure rules
|
|
72
|
+
*/
|
|
73
|
+
protected getCommonRules(): string;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=base-adapter.d.ts.map
|