UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

262 lines (246 loc) 11 kB
import { TypescriptOptions, StorybookConfig, PackageJson, IndexEntry } from 'storybook/internal/types'; import { BinaryLike } from 'crypto'; type Agent = 'npm' | 'yarn' | 'yarn@berry' | 'pnpm' | 'pnpm@6' | 'bun' | 'deno'; type AgentName = 'npm' | 'yarn' | 'pnpm' | 'bun' | 'deno'; interface DetectResult { /** * Agent name without the specifier. * * Can be `npm`, `yarn`, `pnpm`, `bun`, or `deno`. */ name: AgentName; /** * Agent specifier to resolve the command. * * May contain '@' to differentiate the version (e.g. 'yarn@berry'). * Use `name` for the agent name without the specifier. */ agent: Agent; /** * Specific version of the agent, read from `packageManager` field in package.json. */ version?: string; } type AgentInfo = { /** * The name of the detected AI coding agent (e.g. `claude`, `gemini`, `codex`, `cursor`). Can be * any value supported by std-env or explicitly set via the `AI_AGENT` environment variable. */ name: string; }; type AgentDetection = AgentInfo | undefined; /** Detect whether Storybook CLI is likely being invoked by an AI agent, using std-env. */ declare const detectAgent: () => AgentDetection; type PackageGroupResult = Record<string, string | null | undefined>; type KnownPackagesList = { testPackages?: PackageGroupResult; stylingPackages?: PackageGroupResult; stateManagementPackages?: PackageGroupResult; dataFetchingPackages?: PackageGroupResult; uiLibraryPackages?: PackageGroupResult; i18nPackages?: PackageGroupResult; routerPackages?: PackageGroupResult; }; declare const monorepoConfigs: { readonly Nx: "nx.json"; readonly Turborepo: "turbo.json"; readonly Lerna: "lerna.json"; readonly Rush: "rush.json"; readonly Lage: "lage.config.json"; }; type MonorepoType = keyof typeof monorepoConfigs | 'Workspaces' | undefined; type EventType = 'boot' | 'add' | 'dev' | 'build' | 'index' | 'upgrade' | 'multi-upgrade' | 'init' | 'init-step' | 'scaffolded-empty' | 'browser' | 'canceled' | 'exit' | 'error' | 'error-metadata' | 'version-update' | 'core-config' | 'remove' | 'save-story' | 'create-new-story-file' | 'create-new-story-file-search' | 'open-in-editor' | 'testing-module-watch-mode' | 'testing-module-completed-report' | 'testing-module-crash-report' | 'addon-test' | 'test-run' | 'addon-onboarding' | 'onboarding-survey' | 'onboarding-checklist-muted' | 'onboarding-checklist-status' | 'mocking' | 'automigrate' | 'migrate' | 'preview-first-load' | 'doctor' | 'share' | 'ghost-stories' | 'sidebar-filter' | 'ai-init-opt-in' | 'ai-prompt-nudge' | 'ai-setup' | 'ai-setup-final-scoring' | 'ai-setup-self-healing-scoring'; interface Dependency { version: string | undefined; versionSpecifier?: string; } interface StorybookAddon extends Dependency { options: any; } type StorybookMetadata = { storybookVersion?: string; storybookVersionSpecifier: string; generatedAt?: number; userSince?: number; /** If we can identify the agent, report it; otherwise `unknown` when detected heuristically. */ agent?: AgentInfo; language: 'typescript' | 'javascript'; framework?: { name?: string; options?: any; }; builder?: string; renderer?: string; monorepo?: MonorepoType; packageManager?: { type: DetectResult['name']; version: DetectResult['version']; agent: DetectResult['agent']; nodeLinker: 'node_modules' | 'pnp' | 'pnpm' | 'isolated' | 'hoisted'; }; typescriptOptions?: Partial<TypescriptOptions>; addons?: Record<string, StorybookAddon>; storybookPackages?: Record<string, Dependency>; metaFramework?: { name: string; packageName: string; version: string; }; packageJsonType?: 'unknown' | 'module' | 'commonjs'; knownPackages?: KnownPackagesList; hasRouterPackage?: boolean; hasStorybookEslint?: boolean; hasStaticDirs?: boolean; hasCustomWebpack?: boolean; hasCustomBabel?: boolean; features?: StorybookConfig['features']; refCount?: number; preview?: { usesGlobals?: boolean; }; portableStoriesFileCount?: number; applicationFileCount?: number; }; interface Payload { [key: string]: any; } type PayloadFactory = () => Payload | Promise<Payload>; type PayloadInput = Payload | PayloadFactory; interface Context { [key: string]: any; } interface Options { retryDelay: number; immediate: boolean; configDir?: string; enableCrashReports?: boolean; stripMetadata?: boolean; notify?: boolean; /** Override the event timestamp. Used when flushing queued events to preserve original timing. */ timestamp?: number; /** When true, bypass the disabled state. Used for error telemetry with enableCrashReports. */ force?: boolean; } interface TelemetryData { eventType: EventType; payload: Payload; metadata?: StorybookMetadata; } interface TelemetryEvent extends TelemetryData { eventId: string; sessionId: string; context: Context; } interface InitPayload { projectType: string; features: { dev: boolean; docs: boolean; test: boolean; onboarding: boolean; ai: boolean; }; newUser: boolean; versionSpecifier: string | undefined; cliIntegration: string | undefined; } declare const oneWayHash: (payload: BinaryLike) => string; declare const metaFrameworks: Record<string, string>; declare const sanitizeAddonName: (name: string) => string; declare const computeStorybookMetadata: ({ packageJsonPath, packageJson, mainConfig, configDir, }: { packageJsonPath: string; packageJson: PackageJson; mainConfig?: StorybookConfig & Record<string, any>; configDir: string; }) => Promise<StorybookMetadata>; declare const getStorybookMetadata: (_configDir?: string) => Promise<StorybookMetadata>; interface IErrorWithStdErrAndStdOut { stderr?: Buffer | string; stdout?: Buffer | string; [key: string]: unknown; } declare function removeAnsiEscapeCodes(input?: string): string; /** * Removes all user-specific file system paths from the input string, replacing them with "$SNIP". * This helps sanitize sensitive user information from output (such as error messages or logs). e.g. * `/Users/username/storybook-app/src/pages/index.js` -> `$SNIP/src/pages/index.js` */ declare function cleanPaths(str: string, separator?: string): string; declare function sanitizeError(error: Error, pathSeparator?: string): any; /** * Service for collecting errors during Storybook initialization. * * This singleton class exists to accumulate non-fatal errors that occur during the Storybook's * processes. Instead of immediately reporting errors to telemetry (which could interrupt the * process), errors are collected here and then batch-reported at the end of initialization via the * telemetry system. * * This allows Storybook to continue e.g. initialization even when non-critical errors occur, * ensuring a better user experience while still capturing all errors for telemetry and debugging * purposes. */ declare class ErrorCollector { private static instance; private errors; private constructor(); static getInstance(): ErrorCollector; static addError(error: unknown): void; static getErrors(): unknown[]; } /** * Determines whether a story index entry was authored by the `sb ai setup` flow. * Currently checks title prefix. When we migrate to a tag-based approach, * swap this to check for the tag instead — this is the single swap point. */ declare function isStoryCreatedByAISetup(entry: IndexEntry): boolean; interface UpgradeSummary { timestamp: number; eventType?: EventType; eventId?: string; sessionId?: string; } interface CacheEntry { timestamp: number; body: TelemetryEvent; } declare const getLastEvents: () => Promise<Record<EventType, CacheEntry>>; declare const getPrecedingUpgrade: (events?: Partial<Record<EventType, CacheEntry>> | undefined) => Promise<UpgradeSummary | undefined>; /** * Returns true when the current session falls within the 2-hour window opened by the most recent * occurrence of one of the given event types * * Used to gate telemetry that should only be captured during a single session window of a given event (e.g. init) */ declare function isWithinInitialSession(events: EventType | EventType[]): Promise<boolean>; declare const SESSION_TIMEOUT: number; declare const getSessionId: () => Promise<string>; declare const addToGlobalContext: (key: string, value: any) => void; /** Is this story part of the CLI generated examples, including user-created stories in those files */ declare const isExampleStoryId: (storyId: string) => boolean; /** * Resolve telemetry state. When enabled, flushes the queue. When disabled, clears it. * This should be called once presets have been evaluated and the disableTelemetry config is known. */ declare function setTelemetryEnabled(enabled: boolean): Promise<void>; /** Check whether telemetry is currently enabled. */ declare function isTelemetryModuleEnabled(): boolean; /** Check whether the telemetry state has been resolved (is no longer uninitialized). */ declare function isTelemetryStateResolved(): boolean; /** * Callback invoked when a payload factory throws or returns { error }. * Registered by withTelemetry() to delegate to sendTelemetryError with full context * (presets, cache, error levels, sub-errors). */ type PayloadErrorHandler = (error: Error, eventType: EventType) => Promise<void>; /** * Register a handler for payload factory errors. When a telemetry payload factory * throws or returns { error }, this handler is called instead of sending the normal event. * Pass undefined to clear the handler. * * This is used by withTelemetry() to wire up sendTelemetryError with full context * (cliOptions, presetOptions, error levels, sub-errors) so all commands benefit * from automatic error telemetry. */ declare function onPayloadError(handler: PayloadErrorHandler | undefined): void; declare const telemetry: (eventType: EventType, payload?: PayloadInput, options?: Partial<Options>) => Promise<void>; export { type AgentInfo, type CacheEntry, type Context, type Dependency, ErrorCollector, type EventType, type IErrorWithStdErrAndStdOut, type InitPayload, type Options, type Payload, type PayloadFactory, type PayloadInput, SESSION_TIMEOUT, type StorybookAddon, type StorybookMetadata, type TelemetryData, type TelemetryEvent, addToGlobalContext, cleanPaths, computeStorybookMetadata, detectAgent, getLastEvents, getPrecedingUpgrade, getSessionId, getStorybookMetadata, isExampleStoryId, isStoryCreatedByAISetup, isTelemetryModuleEnabled, isTelemetryStateResolved, isWithinInitialSession, metaFrameworks, onPayloadError, oneWayHash, removeAnsiEscapeCodes, sanitizeAddonName, sanitizeError, setTelemetryEnabled, telemetry };