diff --git a/code/lib/cli-storybook/src/automigrate/index.ts b/code/lib/cli-storybook/src/automigrate/index.ts index 040f427ba5ec..c7a2a5b21a12 100644 --- a/code/lib/cli-storybook/src/automigrate/index.ts +++ b/code/lib/cli-storybook/src/automigrate/index.ts @@ -122,6 +122,7 @@ export const automigrate = async ({ isLatest, storiesPaths, hasCsfFactoryPreview, + glob, }: AutofixOptions): Promise<{ fixResults: Record; preCheckFailure?: PreCheckFailure; @@ -146,6 +147,8 @@ export const automigrate = async ({ result: null, storybookVersion, storiesPaths, + yes, + glob, }); return null; @@ -380,6 +383,7 @@ export async function runFixes({ skipInstall, storybookVersion, storiesPaths, + yes, }); logger.log(`✅ ran ${picocolors.cyan(f.id)} migration`); diff --git a/code/lib/cli-storybook/src/automigrate/multi-project.ts b/code/lib/cli-storybook/src/automigrate/multi-project.ts index 59543089404c..7c331348c63d 100644 --- a/code/lib/cli-storybook/src/automigrate/multi-project.ts +++ b/code/lib/cli-storybook/src/automigrate/multi-project.ts @@ -264,7 +264,7 @@ export async function runAutomigrationsForProjects( selectedAutomigrations: AutomigrationCheckResult[], options: MultiProjectRunAutomigrationOptions ): Promise> { - const { dryRun, skipInstall, automigrations } = options; + const { dryRun, skipInstall, automigrations, yes } = options; const projectResults: Record = {}; const applicableAutomigrations = selectedAutomigrations.filter((am) => @@ -378,6 +378,7 @@ export async function runAutomigrationsForProjects( skipInstall, storybookVersion: project.storybookVersion, storiesPaths: project.storiesPaths, + yes, }; await fix.run(runOptions); diff --git a/code/lib/cli-storybook/src/automigrate/types.ts b/code/lib/cli-storybook/src/automigrate/types.ts index 1856e53c4211..28e4dcc1d183 100644 --- a/code/lib/cli-storybook/src/automigrate/types.ts +++ b/code/lib/cli-storybook/src/automigrate/types.ts @@ -24,6 +24,10 @@ export interface RunOptions { skipInstall?: boolean; storybookVersion: string; storiesPaths: string[]; + /** Skip prompts and use defaults (from --yes flag) */ + yes?: boolean; + /** Glob pattern for story files (for csf-factories codemod) */ + glob?: string; } /** @@ -97,6 +101,8 @@ export interface AutofixOptionsFromCLI { skipInstall?: boolean; hideMigrationSummary?: boolean; skipDoctor?: boolean; + /** Glob pattern for story files (for csf-factories codemod) */ + glob?: string; } export enum FixStatus { diff --git a/code/lib/cli-storybook/src/bin/run.ts b/code/lib/cli-storybook/src/bin/run.ts index cab65aa2eedf..434c72ccc809 100644 --- a/code/lib/cli-storybook/src/bin/run.ts +++ b/code/lib/cli-storybook/src/bin/run.ts @@ -278,6 +278,7 @@ command('automigrate [fixId]') 'The renderer package for the framework Storybook is using.' ) .option('--skip-doctor', 'Skip doctor check') + .option('--glob ', 'Glob pattern for story files (for csf-factories codemod)') .action(async (fixId, options) => { withTelemetry('automigrate', { cliOptions: options }, async () => { logger.intro(fixId ? `Running ${fixId} automigration` : 'Running automigrations'); diff --git a/code/lib/cli-storybook/src/codemod/csf-factories.ts b/code/lib/cli-storybook/src/codemod/csf-factories.ts index 35e0e1a4ecea..0aad19f84efa 100644 --- a/code/lib/cli-storybook/src/codemod/csf-factories.ts +++ b/code/lib/cli-storybook/src/codemod/csf-factories.ts @@ -19,15 +19,22 @@ async function runStoriesCodemod(options: { packageManager: JsPackageManager; useSubPathImports: boolean; previewConfigPath: string; + yes: boolean | undefined; + glob: string | undefined; }) { - const { dryRun, packageManager, ...codemodOptions } = options; + const { dryRun, packageManager, yes, glob, ...codemodOptions } = options; try { - let globString = '{stories,src}/**/{Button,Header,Page,button,header,page}.stories.*'; - if (!optionalEnvToBoolean(process.env.IN_STORYBOOK_SANDBOX)) { + const inSandbox = optionalEnvToBoolean(process.env.IN_STORYBOOK_SANDBOX) ?? false; + let globString = glob ?? '**/*.{stories,story}.{js,jsx,ts,tsx,mjs,mjsx,mts,mtsx}'; + + if (!glob && inSandbox) { + // Sandbox uses limited glob for faster testing (unless glob explicitly provided) + globString = '{stories,src}/**/{Button,Header,Page,button,header,page}.stories.*'; + } else if (!glob && !yes) { logger.log('Please enter the glob for your stories to migrate'); globString = await prompt.text({ message: 'glob', - initialValue: '**/*.{stories,story}.{js,jsx,ts,tsx,mjs,mjsx,mts,mtsx}', + initialValue: globString, }); } @@ -52,10 +59,21 @@ async function runStoriesCodemod(options: { export const csfFactories: CommandFix = { id: 'csf-factories', promptType: 'command', - async run({ dryRun, mainConfig, mainConfigPath, previewConfigPath, packageManager, configDir }) { - let useSubPathImports = true; - - if (!optionalEnvToBoolean(process.env.IN_STORYBOOK_SANDBOX)) { + async run({ + dryRun, + mainConfig, + mainConfigPath, + previewConfigPath, + packageManager, + configDir, + yes, + glob, + }) { + const inSandbox = optionalEnvToBoolean(process.env.IN_STORYBOOK_SANDBOX) ?? false; + // Defaults to false for users and true in sandbox + let useSubPathImports = inSandbox; + + if (!yes && !inSandbox) { // prompt whether the user wants to use imports map logger.logBox(dedent` The CSF Factories format can benefit from using absolute imports of your ${picocolors.cyan(previewConfigPath)} file. We can configure that for you, using subpath imports (a node standard), by adjusting the imports property of your package.json. @@ -96,6 +114,8 @@ export const csfFactories: CommandFix = { packageManager, useSubPathImports, previewConfigPath: previewConfigPath!, + yes, + glob, }); logger.step('Applying codemod on your main config...');