Parse and manipulate CSF and Storybook config files
—
Core functionality for parsing, analyzing, and manipulating Component Story Format files. This module provides the essential tools for working with Storybook story files programmatically.
Parse CSF code into a structured CsfFile object for analysis and manipulation.
/**
* Parse CSF code into a CsfFile instance
* @param code - The CSF source code as a string
* @param options - Configuration options for parsing
* @returns CsfFile instance ready for parsing
*/
function loadCsf(code: string, options: CsfOptions): CsfFile;
interface CsfOptions {
/** Optional file name for error reporting and source maps */
fileName?: string;
/** Function to generate story titles, receives user title and returns final title */
makeTitle: (userTitle: string) => string;
/** Transform inline meta exports to constant declarations for better tooling support */
transformInlineMeta?: boolean;
}Usage Examples:
import { loadCsf } from "@storybook/csf-tools";
// Basic CSF parsing
const csfCode = `
export default { title: 'Components/Button' };
export const Primary = { args: { primary: true } };
export const Secondary = { args: { primary: false } };
`;
const csfFile = loadCsf(csfCode, {
fileName: 'Button.stories.ts',
makeTitle: (userTitle) => userTitle || 'Unknown'
});
// Parse the file to extract stories and metadata
const parsed = csfFile.parse();Read and parse CSF files directly from the filesystem.
/**
* Read and parse a CSF file from the filesystem
* @param fileName - Path to the CSF file
* @param options - Configuration options for parsing
* @returns Promise resolving to parsed CsfFile
*/
function readCsf(fileName: string, options: CsfOptions): Promise<CsfFile>;Usage Examples:
import { readCsf } from "@storybook/csf-tools";
// Read and parse a story file
const csfFile = await readCsf('./src/Button.stories.ts', {
makeTitle: (userTitle) => `Components/${userTitle}`
});
console.log(csfFile.meta.title); // Access parsed metadata
console.log(csfFile.stories); // Access parsed storiesWrite CsfFile objects back to the filesystem as formatted code.
/**
* Write a CsfFile to the filesystem
* @param csf - The CsfFile instance to write
* @param fileName - Optional output file path (uses csf._options.fileName if not provided)
* @returns Promise that resolves when file is written
*/
function writeCsf(csf: CsfFile, fileName?: string): Promise<void>;Generate formatted code from CsfFile instances with various formatting options.
/**
* Generate formatted code from a CsfFile
* @param csf - The CsfFile instance to format
* @param options - Babel generator options including source map support
* @param code - Optional original code for source map generation
* @returns Generated code string or object with source maps
*/
function formatCsf(
csf: CsfFile,
options?: GeneratorOptions & { inputSourceMap?: any },
code?: string
): ReturnType<typeof generate> | string;
/**
* Generate code with style preservation using recast
* @param csf - The CsfFile instance to print
* @param options - Recast formatting options
* @returns Object with code and optional source map
*/
function printCsf(csf: CsfFile, options?: RecastOptions): PrintResultType;Usage Examples:
import { formatCsf, printCsf } from "@storybook/csf-tools";
// Generate clean formatted code
const formattedCode = formatCsf(csfFile);
// Generate code preserving original formatting
const { code } = printCsf(csfFile, {
tabWidth: 2,
useTabs: false
});
// Write to file
await writeCsf(csfFile, './output/Button.stories.ts');The core class for representing and manipulating CSF files.
class CsfFile {
/** Babel AST representation of the file */
readonly _ast: t.File;
/** Parsed metadata from default export */
readonly _meta?: StaticMeta;
/** Parsed stories keyed by export name */
readonly _stories: Record<string, StaticStory>;
/** Story export AST nodes */
readonly _storyExports: Record<string, t.VariableDeclarator | t.FunctionDeclaration>;
/** Import paths found in the file */
readonly imports: string[];
constructor(ast: t.File, options: CsfOptions, file: BabelFile);
/**
* Parse the AST to extract stories and metadata
* @returns Parsed CsfFile with IndexedCSFFile interface
*/
parse(): CsfFile & IndexedCSFFile;
/**
* Get the AST node for a specific story export
* @param key - Export name of the story
* @returns AST node for the story
*/
getStoryExport(key: string): t.Node;
/** Get parsed metadata object */
get meta(): StaticMeta | undefined;
/** Get array of parsed stories */
get stories(): StaticStory[];
/** Get index input objects for all stories */
get indexInputs(): IndexInput[];
}Helper functions for working with CSF files and AST parsing.
/**
* Check if file path matches Storybook preview file pattern
* @param filepath - File path to check
* @returns True if path is a valid preview file
*/
function isValidPreviewPath(filepath: string): boolean;
/**
* Parse JavaScript/TypeScript code into Babel AST
* Re-exported from @storybook/core/babel for convenience
* @param code - Source code to parse
* @returns Babel AST representation
*/
function babelParse(code: string): t.File;The CSF processing module defines several error types for different parsing scenarios:
class NoMetaError extends Error {
constructor(message: string, ast: t.Node, fileName?: string);
}
class MultipleMetaError extends Error {
constructor(message: string, ast: t.Node, fileName?: string);
}
class MixedFactoryError extends Error {
constructor(message: string, ast: t.Node, fileName?: string);
}
class BadMetaError extends Error {
constructor(message: string, ast: t.Node, fileName?: string);
}These errors provide detailed information about parsing failures and include source location data when available.
Install with Tessl CLI
npx tessl i tessl/npm-storybook--csf-tools