import type { CLIOption, CLIOptions } from '../../../packages/vitest/src/node/cli/cli-config.ts' import { writeFileSync } from 'node:fs' import { dirname, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { cliOptionsConfig } from '../../../packages/vitest/src/node/cli/cli-config.ts' const docsDir = resolve(dirname(fileURLToPath(import.meta.url)), '../..') const cliTablePath = resolve(docsDir, './guide/cli-generated.md') const nonNullable = (value: T): value is NonNullable => value !== null && value !== undefined const skipCli = new Set(['mergeReports', 'shard']) const skipConfig = new Set([ 'config', 'api.port', 'api.host', 'api.strictPort', 'coverage.watermarks.statements', 'coverage.watermarks.lines', 'coverage.watermarks.branches', 'coverage.watermarks.functions', 'coverage.thresholds.statements', 'coverage.thresholds.branches', 'coverage.thresholds.functions', 'coverage.thresholds.lines', 'standalone', 'clearScreen', 'configLoader', 'color', 'run', 'hideSkippedTests', 'dom', 'inspect', 'inspectBrk', 'project', 'ui', 'browser.name', 'clearCache', 'tagsFilter', 'listTags', ]) function resolveOptions(options: CLIOptions, parentName?: string) { return Object.entries(options) .flatMap(([subcommandName, subcommandConfig]) => resolveCommand( parentName ? `${parentName}.${subcommandName}` : subcommandName, subcommandConfig, ), ) .filter(nonNullable) } function resolveCommand(name: string, config: CLIOption | null): any { if (!config || skipCli.has(name)) { return null } let title = '`' if (config.shorthand) { title += `-${config.shorthand}, ` } title += `--${config.alias || name}` if ('argument' in config && config.argument) { title += ` ${config.argument}` } title += '`' if ('subcommands' in config && config.subcommands) { return resolveOptions(config.subcommands, name) } return { title: name, cli: title, description: config.description, } } const options = resolveOptions(cliOptionsConfig) const template = options .map((option) => { const title = option.title const cli = option.cli const [page, ...hash] = (title.startsWith('browser.') ? title.slice(8) : title) .toLowerCase() .split('.') const config = skipConfig.has(title) ? '' : `[${title}](${title.includes('browser.') ? '/config/browser/' : '/config/'}${page}${hash.length ? `#${[page, ...hash].join('-')}` : ''})` return `### ${title}\n\n- **CLI:** ${cli}\n${config ? `- **Config:** ${config}\n` : ''}\n${option.description.replace(/https:\/\/vitest\.dev\//g, '/')}\n` }) .join('\n') writeFileSync(cliTablePath, template, 'utf-8')