@fragments-sdk/cli 0.2.2
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/LICENSE +21 -0
- package/README.md +106 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +4783 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-4FDQSGKX.js +786 -0
- package/dist/chunk-4FDQSGKX.js.map +1 -0
- package/dist/chunk-7H2MMGYG.js +369 -0
- package/dist/chunk-7H2MMGYG.js.map +1 -0
- package/dist/chunk-BSCG3IP7.js +619 -0
- package/dist/chunk-BSCG3IP7.js.map +1 -0
- package/dist/chunk-LY2CFFPY.js +898 -0
- package/dist/chunk-LY2CFFPY.js.map +1 -0
- package/dist/chunk-MUZ6CM66.js +6636 -0
- package/dist/chunk-MUZ6CM66.js.map +1 -0
- package/dist/chunk-OAENNG3G.js +1489 -0
- package/dist/chunk-OAENNG3G.js.map +1 -0
- package/dist/chunk-XHNKNI6J.js +235 -0
- package/dist/chunk-XHNKNI6J.js.map +1 -0
- package/dist/core-DWKLGY4N.js +68 -0
- package/dist/core-DWKLGY4N.js.map +1 -0
- package/dist/generate-4LQNJ7SX.js +249 -0
- package/dist/generate-4LQNJ7SX.js.map +1 -0
- package/dist/index.d.ts +775 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/init-EMVI47QG.js +416 -0
- package/dist/init-EMVI47QG.js.map +1 -0
- package/dist/mcp-bin.d.ts +1 -0
- package/dist/mcp-bin.js +1117 -0
- package/dist/mcp-bin.js.map +1 -0
- package/dist/scan-4YPRF7FV.js +12 -0
- package/dist/scan-4YPRF7FV.js.map +1 -0
- package/dist/service-QSZMZJBJ.js +208 -0
- package/dist/service-QSZMZJBJ.js.map +1 -0
- package/dist/static-viewer-MIPGZ4Z7.js +12 -0
- package/dist/static-viewer-MIPGZ4Z7.js.map +1 -0
- package/dist/test-SQ5ZHXWU.js +1067 -0
- package/dist/test-SQ5ZHXWU.js.map +1 -0
- package/dist/tokens-HSGMYK64.js +173 -0
- package/dist/tokens-HSGMYK64.js.map +1 -0
- package/dist/viewer-YRF4SQE4.js +11101 -0
- package/dist/viewer-YRF4SQE4.js.map +1 -0
- package/package.json +107 -0
- package/src/ai.ts +266 -0
- package/src/analyze.ts +265 -0
- package/src/bin.ts +916 -0
- package/src/build.ts +248 -0
- package/src/commands/a11y.ts +302 -0
- package/src/commands/add.ts +313 -0
- package/src/commands/audit.ts +195 -0
- package/src/commands/baseline.ts +221 -0
- package/src/commands/build.ts +144 -0
- package/src/commands/compare.ts +337 -0
- package/src/commands/context.ts +107 -0
- package/src/commands/dev.ts +107 -0
- package/src/commands/enhance.ts +858 -0
- package/src/commands/generate.ts +391 -0
- package/src/commands/init.ts +531 -0
- package/src/commands/link/figma.ts +645 -0
- package/src/commands/link/index.ts +10 -0
- package/src/commands/link/storybook.ts +267 -0
- package/src/commands/list.ts +49 -0
- package/src/commands/metrics.ts +114 -0
- package/src/commands/reset.ts +242 -0
- package/src/commands/scan.ts +537 -0
- package/src/commands/storygen.ts +207 -0
- package/src/commands/tokens.ts +251 -0
- package/src/commands/validate.ts +93 -0
- package/src/commands/verify.ts +215 -0
- package/src/core/composition.test.ts +262 -0
- package/src/core/composition.ts +255 -0
- package/src/core/config.ts +84 -0
- package/src/core/constants.ts +111 -0
- package/src/core/context.ts +380 -0
- package/src/core/defineSegment.ts +137 -0
- package/src/core/discovery.ts +337 -0
- package/src/core/figma.ts +263 -0
- package/src/core/fragment-types.ts +214 -0
- package/src/core/generators/context.ts +389 -0
- package/src/core/generators/index.ts +23 -0
- package/src/core/generators/registry.ts +364 -0
- package/src/core/generators/typescript-extractor.ts +374 -0
- package/src/core/importAnalyzer.ts +217 -0
- package/src/core/index.ts +149 -0
- package/src/core/loader.ts +155 -0
- package/src/core/node.ts +63 -0
- package/src/core/parser.ts +551 -0
- package/src/core/previewLoader.ts +172 -0
- package/src/core/schema/fragment.schema.json +189 -0
- package/src/core/schema/registry.schema.json +137 -0
- package/src/core/schema.ts +182 -0
- package/src/core/storyAdapter.test.ts +571 -0
- package/src/core/storyAdapter.ts +761 -0
- package/src/core/token-types.ts +287 -0
- package/src/core/types.ts +754 -0
- package/src/diff.ts +323 -0
- package/src/index.ts +43 -0
- package/src/mcp/__tests__/projectFields.test.ts +130 -0
- package/src/mcp/bin.ts +36 -0
- package/src/mcp/index.ts +8 -0
- package/src/mcp/server.ts +1310 -0
- package/src/mcp/utils.ts +54 -0
- package/src/mcp-bin.ts +36 -0
- package/src/migrate/__tests__/argTypes/argTypes.test.ts +189 -0
- package/src/migrate/__tests__/args/args.test.ts +452 -0
- package/src/migrate/__tests__/meta/meta.test.ts +198 -0
- package/src/migrate/__tests__/stories/stories.test.ts +278 -0
- package/src/migrate/__tests__/utils/utils.test.ts +371 -0
- package/src/migrate/__tests__/values/values.test.ts +303 -0
- package/src/migrate/bin.ts +108 -0
- package/src/migrate/converter.ts +658 -0
- package/src/migrate/detect.ts +196 -0
- package/src/migrate/index.ts +45 -0
- package/src/migrate/migrate.ts +163 -0
- package/src/migrate/parser.ts +1136 -0
- package/src/migrate/report.ts +624 -0
- package/src/migrate/types.ts +169 -0
- package/src/screenshot.ts +249 -0
- package/src/service/__tests__/ast-utils.test.ts +426 -0
- package/src/service/__tests__/enhance-scanner.test.ts +200 -0
- package/src/service/__tests__/figma/figma.test.ts +652 -0
- package/src/service/__tests__/metrics-store.test.ts +409 -0
- package/src/service/__tests__/patch-generator.test.ts +186 -0
- package/src/service/__tests__/props-extractor.test.ts +365 -0
- package/src/service/__tests__/token-registry.test.ts +267 -0
- package/src/service/analytics.ts +659 -0
- package/src/service/ast-utils.ts +444 -0
- package/src/service/browser-pool.ts +339 -0
- package/src/service/capture.ts +267 -0
- package/src/service/diff.ts +279 -0
- package/src/service/enhance/aggregator.ts +489 -0
- package/src/service/enhance/cache.ts +275 -0
- package/src/service/enhance/codebase-scanner.ts +357 -0
- package/src/service/enhance/context-generator.ts +529 -0
- package/src/service/enhance/doc-extractor.ts +523 -0
- package/src/service/enhance/index.ts +131 -0
- package/src/service/enhance/props-extractor.ts +665 -0
- package/src/service/enhance/scanner.ts +445 -0
- package/src/service/enhance/storybook-parser.ts +552 -0
- package/src/service/enhance/types.ts +346 -0
- package/src/service/enhance/variant-renderer.ts +479 -0
- package/src/service/figma.ts +1008 -0
- package/src/service/index.ts +249 -0
- package/src/service/metrics-store.ts +333 -0
- package/src/service/patch-generator.ts +349 -0
- package/src/service/report.ts +854 -0
- package/src/service/storage.ts +401 -0
- package/src/service/token-fixes.ts +281 -0
- package/src/service/token-parser.ts +504 -0
- package/src/service/token-registry.ts +721 -0
- package/src/service/utils.ts +172 -0
- package/src/setup.ts +241 -0
- package/src/shared/command-wrapper.ts +81 -0
- package/src/shared/dev-server-client.ts +199 -0
- package/src/shared/index.ts +8 -0
- package/src/shared/segment-loader.ts +59 -0
- package/src/shared/types.ts +147 -0
- package/src/static-viewer.ts +715 -0
- package/src/test/discovery.ts +172 -0
- package/src/test/index.ts +281 -0
- package/src/test/reporters/console.ts +194 -0
- package/src/test/reporters/json.ts +190 -0
- package/src/test/reporters/junit.ts +186 -0
- package/src/test/runner.ts +598 -0
- package/src/test/types.ts +245 -0
- package/src/test/watch.ts +200 -0
- package/src/validators.ts +152 -0
- package/src/viewer/__tests__/jsx-parser.test.ts +502 -0
- package/src/viewer/__tests__/render-utils.test.ts +232 -0
- package/src/viewer/__tests__/style-utils.test.ts +404 -0
- package/src/viewer/bin.ts +86 -0
- package/src/viewer/cli/health.ts +256 -0
- package/src/viewer/cli/index.ts +33 -0
- package/src/viewer/cli/scan.ts +124 -0
- package/src/viewer/cli/utils.ts +174 -0
- package/src/viewer/components/AccessibilityPanel.tsx +1404 -0
- package/src/viewer/components/ActionCapture.tsx +172 -0
- package/src/viewer/components/ActionsPanel.tsx +371 -0
- package/src/viewer/components/App.tsx +638 -0
- package/src/viewer/components/BottomPanel.tsx +224 -0
- package/src/viewer/components/CodePanel.tsx +589 -0
- package/src/viewer/components/CommandPalette.tsx +336 -0
- package/src/viewer/components/ComponentGraph.tsx +394 -0
- package/src/viewer/components/ComponentHeader.tsx +85 -0
- package/src/viewer/components/ContractPanel.tsx +234 -0
- package/src/viewer/components/ErrorBoundary.tsx +85 -0
- package/src/viewer/components/FigmaEmbed.tsx +231 -0
- package/src/viewer/components/FragmentEditor.tsx +485 -0
- package/src/viewer/components/HealthDashboard.tsx +452 -0
- package/src/viewer/components/HmrStatusIndicator.tsx +71 -0
- package/src/viewer/components/Icons.tsx +417 -0
- package/src/viewer/components/InteractionsPanel.tsx +720 -0
- package/src/viewer/components/IsolatedPreviewFrame.tsx +321 -0
- package/src/viewer/components/IsolatedRender.tsx +111 -0
- package/src/viewer/components/KeyboardShortcutsHelp.tsx +89 -0
- package/src/viewer/components/LandingPage.tsx +441 -0
- package/src/viewer/components/Layout.tsx +22 -0
- package/src/viewer/components/LeftSidebar.tsx +391 -0
- package/src/viewer/components/MultiViewportPreview.tsx +429 -0
- package/src/viewer/components/PreviewArea.tsx +404 -0
- package/src/viewer/components/PreviewFrameHost.tsx +310 -0
- package/src/viewer/components/PreviewPane.tsx +150 -0
- package/src/viewer/components/PreviewToolbar.tsx +176 -0
- package/src/viewer/components/PropsEditor.tsx +512 -0
- package/src/viewer/components/PropsTable.tsx +98 -0
- package/src/viewer/components/RelationsSection.tsx +57 -0
- package/src/viewer/components/ResizablePanel.tsx +328 -0
- package/src/viewer/components/RightSidebar.tsx +118 -0
- package/src/viewer/components/ScreenshotButton.tsx +90 -0
- package/src/viewer/components/Sidebar.tsx +169 -0
- package/src/viewer/components/SkeletonLoader.tsx +156 -0
- package/src/viewer/components/StoryRenderer.tsx +128 -0
- package/src/viewer/components/ThemeProvider.tsx +96 -0
- package/src/viewer/components/Toast.tsx +67 -0
- package/src/viewer/components/TokenStylePanel.tsx +708 -0
- package/src/viewer/components/UsageSection.tsx +95 -0
- package/src/viewer/components/VariantMatrix.tsx +350 -0
- package/src/viewer/components/VariantRenderer.tsx +131 -0
- package/src/viewer/components/VariantTabs.tsx +84 -0
- package/src/viewer/components/ViewportSelector.tsx +165 -0
- package/src/viewer/components/_future/CreatePage.tsx +836 -0
- package/src/viewer/composition-renderer.ts +381 -0
- package/src/viewer/constants/index.ts +1 -0
- package/src/viewer/constants/ui.ts +185 -0
- package/src/viewer/entry.tsx +299 -0
- package/src/viewer/hooks/index.ts +2 -0
- package/src/viewer/hooks/useA11yCache.ts +383 -0
- package/src/viewer/hooks/useA11yService.ts +498 -0
- package/src/viewer/hooks/useActions.ts +138 -0
- package/src/viewer/hooks/useAppState.ts +124 -0
- package/src/viewer/hooks/useFigmaIntegration.ts +132 -0
- package/src/viewer/hooks/useHmrStatus.ts +109 -0
- package/src/viewer/hooks/useKeyboardShortcuts.ts +222 -0
- package/src/viewer/hooks/usePreviewBridge.ts +347 -0
- package/src/viewer/hooks/useScrollSpy.ts +78 -0
- package/src/viewer/hooks/useUrlState.ts +330 -0
- package/src/viewer/hooks/useViewSettings.ts +125 -0
- package/src/viewer/index.html +28 -0
- package/src/viewer/index.ts +14 -0
- package/src/viewer/intelligence/healthReport.ts +505 -0
- package/src/viewer/intelligence/styleDrift.ts +340 -0
- package/src/viewer/intelligence/usageScanner.ts +309 -0
- package/src/viewer/jsx-parser.ts +485 -0
- package/src/viewer/postcss.config.js +6 -0
- package/src/viewer/preview-frame-entry.tsx +25 -0
- package/src/viewer/preview-frame.html +109 -0
- package/src/viewer/render-template.html +68 -0
- package/src/viewer/render-utils.ts +170 -0
- package/src/viewer/server.ts +276 -0
- package/src/viewer/style-utils.ts +414 -0
- package/src/viewer/styles/globals.css +355 -0
- package/src/viewer/tailwind.config.js +37 -0
- package/src/viewer/types/a11y.ts +197 -0
- package/src/viewer/utils/a11y-fixes.ts +471 -0
- package/src/viewer/utils/actionExport.ts +372 -0
- package/src/viewer/utils/colorSchemes.ts +201 -0
- package/src/viewer/utils/detectRelationships.ts +256 -0
- package/src/viewer/vite-plugin.ts +2143 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/test/index.ts","../src/test/discovery.ts","../src/test/runner.ts","../src/test/reporters/console.ts","../src/test/reporters/junit.ts","../src/test/reporters/json.ts","../src/test/watch.ts"],"sourcesContent":["/**\n * Main test command - orchestrates test discovery, execution, and reporting\n */\n\nimport { resolve, join } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport pc from 'picocolors';\nimport type { SegmentsConfig } from '../core/index.js';\nimport type {\n TestConfig,\n DiscoveryOptions,\n RunnerOptions,\n TestReporter,\n TestRunResult,\n} from './types.js';\nimport { discoverTests, getUniqueComponents, getUniqueTags } from './discovery.js';\nimport { runTests } from './runner.js';\nimport { createConsoleReporter } from './reporters/console.js';\nimport { createJUnitReporter } from './reporters/junit.js';\nimport { createJsonReporter } from './reporters/json.js';\nimport { startWatchMode } from './watch.js';\n\nexport interface TestCommandOptions {\n // Discovery options\n component?: string;\n tags?: string;\n grep?: string;\n exclude?: string;\n\n // Execution options\n parallel?: number;\n timeout?: number;\n retries?: number;\n bail?: boolean;\n browser?: 'chromium' | 'firefox' | 'webkit';\n headless?: boolean;\n\n // Feature flags\n a11y?: boolean;\n visual?: boolean;\n updateSnapshots?: boolean;\n watch?: boolean;\n\n // Output options\n reporters?: string;\n output?: string;\n\n // Server options\n serverUrl?: string;\n port?: number;\n\n // CI mode\n ci?: boolean;\n}\n\n/**\n * Default options\n */\nconst DEFAULT_OPTIONS = {\n parallel: 4,\n timeout: 30000,\n retries: 0,\n bail: false,\n browser: 'chromium' as const,\n headless: true,\n a11y: false,\n visual: false,\n updateSnapshots: false,\n watch: false,\n reporters: 'console',\n output: './test-results',\n port: 6006,\n ci: false,\n};\n\n/**\n * Run the test command\n */\nexport async function runTestCommand(\n config: SegmentsConfig,\n configDir: string,\n options: TestCommandOptions\n): Promise<number> {\n // Merge with defaults\n const opts = {\n ...DEFAULT_OPTIONS,\n ...options,\n };\n\n // Parse discovery options\n const discoveryOptions: DiscoveryOptions = {\n component: opts.component,\n tags: opts.tags ? opts.tags.split(',').map((t) => t.trim()) : undefined,\n grep: opts.grep,\n exclude: opts.exclude,\n };\n\n // Parse runner options\n const runnerOptions: RunnerOptions = {\n parallel: opts.parallel,\n timeout: opts.timeout,\n retries: opts.retries,\n bail: opts.bail,\n a11y: opts.a11y,\n visual: opts.visual,\n updateSnapshots: opts.updateSnapshots,\n outputDir: resolve(configDir, opts.output),\n browser: opts.browser,\n headless: opts.headless,\n serverUrl: opts.serverUrl,\n port: opts.port,\n };\n\n // In CI mode, adjust settings\n if (opts.ci) {\n runnerOptions.headless = true;\n }\n\n // Discover tests\n console.log(pc.cyan('\\nDiscovering tests...'));\n const testCases = await discoverTests(config, configDir, discoveryOptions);\n\n if (testCases.length === 0) {\n console.log(pc.yellow('No tests with play functions found'));\n\n // Show helpful info about what was searched\n const components = getUniqueComponents(testCases);\n const tags = getUniqueTags(testCases);\n\n if (discoveryOptions.component) {\n console.log(pc.dim(` Filtered by component: ${discoveryOptions.component}`));\n }\n if (discoveryOptions.tags?.length) {\n console.log(pc.dim(` Filtered by tags: ${discoveryOptions.tags.join(', ')}`));\n }\n if (discoveryOptions.grep) {\n console.log(pc.dim(` Filtered by pattern: ${discoveryOptions.grep}`));\n }\n\n console.log();\n console.log(pc.dim('Add play functions to your segment variants to enable testing.'));\n console.log();\n\n return opts.ci ? 0 : 0; // Not a failure if no tests\n }\n\n console.log(pc.dim(`Found ${testCases.length} test(s)`));\n\n // Create output directory\n await mkdir(runnerOptions.outputDir, { recursive: true });\n\n // Create reporters\n const reporters = createReporters(opts.reporters, runnerOptions.outputDir, opts.ci);\n\n // Watch mode\n if (opts.watch && !opts.ci) {\n await startWatchMode(config, configDir, runnerOptions, reporters);\n return 0;\n }\n\n // Run tests\n let result: TestRunResult;\n try {\n result = await runTests(testCases, runnerOptions, reporters);\n } catch (error) {\n console.error(pc.red('Error running tests:'), error);\n return 1;\n }\n\n // Return exit code based on results\n if (opts.ci && result.totalFailed > 0) {\n return 1;\n }\n\n return result.totalFailed > 0 ? 1 : 0;\n}\n\n/**\n * Create reporters based on configuration\n */\nfunction createReporters(\n reporterNames: string,\n outputDir: string,\n ci: boolean\n): TestReporter[] {\n const reporters: TestReporter[] = [];\n const names = reporterNames.split(',').map((n) => n.trim().toLowerCase());\n\n for (const name of names) {\n switch (name) {\n case 'console':\n reporters.push(\n createConsoleReporter({\n verbose: !ci,\n showTiming: true,\n })\n );\n break;\n\n case 'junit':\n reporters.push(\n createJUnitReporter({\n outputPath: join(outputDir, 'junit.xml'),\n suiteName: 'Segments Tests',\n })\n );\n break;\n\n case 'json':\n reporters.push(\n createJsonReporter({\n outputPath: join(outputDir, 'results.json'),\n pretty: true,\n includeSteps: true,\n includeStacks: !ci,\n })\n );\n break;\n\n default:\n console.warn(pc.yellow(`Unknown reporter: ${name}`));\n }\n }\n\n // Always include console reporter if not explicitly specified\n if (!names.includes('console') && reporters.length === 0) {\n reporters.push(createConsoleReporter({ verbose: !ci }));\n }\n\n return reporters;\n}\n\n/**\n * List available tests without running them\n */\nexport async function listTests(\n config: SegmentsConfig,\n configDir: string,\n options: Pick<TestCommandOptions, 'component' | 'tags' | 'grep' | 'exclude'>\n): Promise<void> {\n const discoveryOptions: DiscoveryOptions = {\n component: options.component,\n tags: options.tags ? options.tags.split(',').map((t) => t.trim()) : undefined,\n grep: options.grep,\n exclude: options.exclude,\n };\n\n const testCases = await discoverTests(config, configDir, discoveryOptions);\n\n console.log();\n console.log(pc.cyan(pc.bold('Available Tests')));\n console.log();\n\n if (testCases.length === 0) {\n console.log(pc.yellow('No tests with play functions found'));\n return;\n }\n\n // Group by component\n const byComponent = new Map<string, typeof testCases>();\n for (const test of testCases) {\n const existing = byComponent.get(test.component) || [];\n existing.push(test);\n byComponent.set(test.component, existing);\n }\n\n for (const [component, tests] of byComponent) {\n console.log(pc.bold(component));\n for (const test of tests) {\n const tags = test.tags.length > 0 ? pc.dim(` [${test.tags.join(', ')}]`) : '';\n console.log(` ${pc.green('›')} ${test.variant}${tags}`);\n }\n console.log();\n }\n\n console.log(pc.dim(`Total: ${testCases.length} test(s) in ${byComponent.size} component(s)`));\n console.log();\n}\n\n// Re-export types\nexport type { TestCase, TestResult, TestRunResult, TestSuite, TestReporter } from './types.js';\n","/**\n * Test discovery - finds variants with play functions\n */\n\nimport { readFile } from 'node:fs/promises';\nimport type { SegmentsConfig } from '../core/index.js';\nimport { discoverSegmentFiles, parseSegmentFile } from '../core/node.js';\nimport type { TestCase, DiscoveryOptions } from './types.js';\n\n/**\n * Discovered segment with play function metadata\n */\ninterface DiscoveredVariant {\n component: string;\n variant: string;\n tags: string[];\n hasPlayFunction: boolean;\n storyId?: string;\n sourceFile: string;\n}\n\n/**\n * Discover all variants with play functions\n */\nexport async function discoverTests(\n config: SegmentsConfig,\n configDir: string,\n options: DiscoveryOptions = {}\n): Promise<TestCase[]> {\n const files = await discoverSegmentFiles(config, configDir);\n const variants: DiscoveredVariant[] = [];\n\n for (const file of files) {\n try {\n const content = await readFile(file.absolutePath, 'utf-8');\n const parsed = parseSegmentFile(content, file.relativePath);\n\n if (!parsed.meta.name) continue;\n\n // Filter by component name if specified\n if (options.component) {\n const componentMatch = parsed.meta.name.toLowerCase().includes(options.component.toLowerCase());\n if (!componentMatch) continue;\n }\n\n // Extract tags from meta for the component\n const componentTags = parsed.meta.tags || [];\n\n for (const variant of parsed.variants) {\n // Check if variant has play function by scanning source code\n const hasPlay = hasPlayFunctionInSource(content, variant.name);\n\n if (!hasPlay) continue;\n\n // Filter by tags if specified (use component-level tags since variant tags aren't in parsed data)\n if (options.tags && options.tags.length > 0) {\n const hasMatchingTag = options.tags.some((tag: string) =>\n componentTags.some((ct: string) => ct.toLowerCase().includes(tag.toLowerCase()))\n );\n if (!hasMatchingTag) continue;\n }\n\n // Filter by grep pattern if specified\n if (options.grep) {\n const pattern = new RegExp(options.grep, 'i');\n const matchesName = pattern.test(variant.name);\n const matchesComponent = pattern.test(parsed.meta.name);\n if (!matchesName && !matchesComponent) continue;\n }\n\n // Exclude pattern\n if (options.exclude) {\n const pattern = new RegExp(options.exclude, 'i');\n const excludeName = pattern.test(variant.name);\n const excludeComponent = pattern.test(parsed.meta.name);\n if (excludeName || excludeComponent) continue;\n }\n\n variants.push({\n component: parsed.meta.name,\n variant: variant.name,\n tags: componentTags,\n hasPlayFunction: true,\n storyId: undefined, // Not available from static parsing\n sourceFile: file.relativePath,\n });\n }\n } catch {\n // Skip files that can't be parsed\n continue;\n }\n }\n\n // Convert to test cases\n return variants.map((v) => ({\n id: `${v.component}--${v.variant}`.replace(/\\s+/g, '-').toLowerCase(),\n component: v.component,\n variant: v.variant,\n tags: v.tags,\n play: null as unknown as TestCase['play'], // Play function loaded at runtime in browser\n sourceFile: v.sourceFile,\n storyId: v.storyId,\n }));\n}\n\n/**\n * Check if a variant has a play function by scanning the source code\n */\nfunction hasPlayFunctionInSource(content: string, variantName: string): boolean {\n // Look for play function patterns in the source\n // Pattern 1: play: async ({ ... }) => { ... }\n // Pattern 2: play: async function ({ ... }) { ... }\n // Pattern 3: play: playFunction (reference)\n\n // Normalize variant name for matching (handle Default, Primary, etc.)\n const patterns = [\n // Export const VariantName = { ... play: ... }\n new RegExp(`export\\\\s+const\\\\s+${escapeRegExp(variantName)}\\\\s*=\\\\s*\\\\{[^}]*\\\\bplay\\\\s*:`, 's'),\n // variants: [{ name: 'VariantName', ... play: ... }]\n new RegExp(`name\\\\s*:\\\\s*['\"\\`]${escapeRegExp(variantName)}['\"\\`][^}]*\\\\bplay\\\\s*:`, 's'),\n // In case the variant has play in its definition object\n new RegExp(`['\"\\`]${escapeRegExp(variantName)}['\"\\`]\\\\s*:\\\\s*\\\\{[^}]*\\\\bplay\\\\s*:`, 's'),\n ];\n\n return patterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Escape special regex characters\n */\nfunction escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Group test cases by component\n */\nexport function groupTestsByComponent(testCases: TestCase[]): Map<string, TestCase[]> {\n const groups = new Map<string, TestCase[]>();\n\n for (const test of testCases) {\n const existing = groups.get(test.component) || [];\n existing.push(test);\n groups.set(test.component, existing);\n }\n\n return groups;\n}\n\n/**\n * Get unique tags from all test cases\n */\nexport function getUniqueTags(testCases: TestCase[]): string[] {\n const tags = new Set<string>();\n for (const test of testCases) {\n for (const tag of test.tags) {\n tags.add(tag);\n }\n }\n return Array.from(tags).sort();\n}\n\n/**\n * Get unique components from all test cases\n */\nexport function getUniqueComponents(testCases: TestCase[]): string[] {\n const components = new Set<string>();\n for (const test of testCases) {\n components.add(test.component);\n }\n return Array.from(components).sort();\n}\n","/**\n * Test runner - executes play functions in browser via Playwright\n *\n * Playwright is an optional dependency. If not installed, the test command\n * will prompt the user to install it.\n */\n\nimport type {\n TestCase,\n TestResult,\n TestSuite,\n TestRunResult,\n TestError,\n StepResult,\n A11yResult,\n A11yViolation,\n RunnerOptions,\n TestReporter,\n} from './types.js';\nimport { groupTestsByComponent } from './discovery.js';\n\n// Dynamic playwright types (since it's optional)\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Browser = any;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype BrowserContext = any;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Page = any;\n\n/**\n * Browser pool for parallel test execution\n */\ninterface BrowserPool {\n browser: Browser;\n contexts: BrowserContextEntry[];\n}\n\ninterface BrowserContextEntry {\n id: number;\n context: BrowserContext;\n page: Page;\n busy: boolean;\n}\n\n/**\n * Run tests with the given configuration\n */\nexport async function runTests(\n testCases: TestCase[],\n options: RunnerOptions,\n reporters: TestReporter[] = []\n): Promise<TestRunResult> {\n const startTime = new Date();\n const results: TestResult[] = [];\n\n // Notify reporters of run start\n for (const reporter of reporters) {\n reporter.onRunStart?.(testCases.length);\n }\n\n // Import Playwright dynamically (optional dependency)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let playwright: any;\n try {\n playwright = await import('playwright');\n } catch {\n throw new Error(\n 'Playwright is required for running tests. Install it with: npm install -D playwright'\n );\n }\n\n // Launch browser\n const browserType = playwright[options.browser];\n const browser = await browserType.launch({\n headless: options.headless,\n });\n\n // Create browser pool for parallel execution\n const pool = await createBrowserPool(browser, options.parallel);\n\n try {\n // Determine server URL\n const serverUrl = options.serverUrl || `http://localhost:${options.port}`;\n\n // Run tests with parallelism\n if (options.parallel > 1) {\n await runTestsParallel(\n testCases,\n pool,\n serverUrl,\n options,\n reporters,\n results\n );\n } else {\n await runTestsSequential(\n testCases,\n pool.contexts[0],\n serverUrl,\n options,\n reporters,\n results\n );\n }\n } finally {\n // Cleanup browser pool\n await cleanupBrowserPool(pool);\n }\n\n const endTime = new Date();\n\n // Aggregate results into suites\n const suites = aggregateResults(results);\n\n const runResult: TestRunResult = {\n suites,\n totalTests: results.length,\n totalPassed: results.filter((r) => r.status === 'passed').length,\n totalFailed: results.filter((r) => r.status === 'failed').length,\n totalSkipped: results.filter((r) => r.status === 'skipped').length,\n totalDuration: endTime.getTime() - startTime.getTime(),\n startTime,\n endTime,\n totalA11yViolations: options.a11y\n ? results.reduce((sum, r) => sum + (r.accessibility?.violations.length || 0), 0)\n : undefined,\n };\n\n // Notify reporters of run completion\n for (const reporter of reporters) {\n await reporter.onRunComplete(runResult);\n }\n\n return runResult;\n}\n\n/**\n * Create a browser pool for parallel execution\n */\nasync function createBrowserPool(\n browser: Browser,\n parallelism: number\n): Promise<BrowserPool> {\n const contexts: BrowserContextEntry[] = [];\n\n for (let i = 0; i < parallelism; i++) {\n const context = await browser.newContext({\n viewport: { width: 1280, height: 720 },\n });\n const page = await context.newPage();\n contexts.push({ id: i, context, page, busy: false });\n }\n\n return { browser, contexts };\n}\n\n/**\n * Cleanup browser pool\n */\nasync function cleanupBrowserPool(pool: BrowserPool): Promise<void> {\n for (const entry of pool.contexts) {\n await entry.page.close();\n await entry.context.close();\n }\n await pool.browser.close();\n}\n\n/**\n * Run tests sequentially\n */\nasync function runTestsSequential(\n testCases: TestCase[],\n ctx: BrowserContextEntry,\n serverUrl: string,\n options: RunnerOptions,\n reporters: TestReporter[],\n results: TestResult[]\n): Promise<void> {\n for (const testCase of testCases) {\n // Notify reporters of test start\n for (const reporter of reporters) {\n reporter.onTestStart?.(testCase);\n }\n\n const result = await runSingleTest(testCase, ctx, serverUrl, options);\n results.push(result);\n\n // Notify reporters of test completion\n for (const reporter of reporters) {\n reporter.onTestComplete?.(result);\n }\n\n // Bail on first failure if configured\n if (options.bail && result.status === 'failed') {\n break;\n }\n }\n}\n\n/**\n * Run tests in parallel\n */\nasync function runTestsParallel(\n testCases: TestCase[],\n pool: BrowserPool,\n serverUrl: string,\n options: RunnerOptions,\n reporters: TestReporter[],\n results: TestResult[]\n): Promise<void> {\n const queue = [...testCases];\n const inFlight: Promise<void>[] = [];\n let bailTriggered = false;\n\n const acquireContext = (): BrowserContextEntry | null => {\n const available = pool.contexts.find((c) => !c.busy);\n if (available) {\n available.busy = true;\n return available;\n }\n return null;\n };\n\n const releaseContext = (ctx: BrowserContextEntry): void => {\n ctx.busy = false;\n };\n\n const runNext = async (): Promise<void> => {\n if (bailTriggered || queue.length === 0) return;\n\n const ctx = acquireContext();\n if (!ctx) return;\n\n const testCase = queue.shift()!;\n\n // Notify reporters of test start\n for (const reporter of reporters) {\n reporter.onTestStart?.(testCase);\n }\n\n try {\n const result = await runSingleTest(testCase, ctx, serverUrl, options);\n results.push(result);\n\n // Notify reporters of test completion\n for (const reporter of reporters) {\n reporter.onTestComplete?.(result);\n }\n\n // Check bail condition\n if (options.bail && result.status === 'failed') {\n bailTriggered = true;\n }\n } finally {\n releaseContext(ctx);\n // Start next test if not bailing\n if (!bailTriggered && queue.length > 0) {\n const nextPromise = runNext();\n inFlight.push(nextPromise);\n }\n }\n };\n\n // Start initial batch\n const initialBatch = Math.min(pool.contexts.length, queue.length);\n for (let i = 0; i < initialBatch; i++) {\n inFlight.push(runNext());\n }\n\n // Wait for all to complete\n await Promise.all(inFlight);\n}\n\n/**\n * Run a single test case\n */\nasync function runSingleTest(\n testCase: TestCase,\n ctx: BrowserContextEntry,\n serverUrl: string,\n options: RunnerOptions\n): Promise<TestResult> {\n const { page } = ctx;\n const startTime = performance.now();\n const steps: StepResult[] = [];\n let error: TestError | undefined;\n let status: TestResult['status'] = 'passed';\n let retryAttempt = 0;\n\n // Retry logic\n const maxAttempts = options.retries + 1;\n\n while (retryAttempt < maxAttempts) {\n try {\n // Navigate to the variant\n const url = buildVariantUrl(serverUrl, testCase);\n await page.goto(url, { waitUntil: 'networkidle' });\n\n // Wait for preview container\n await page.waitForSelector('[data-preview-container=\"true\"]', {\n timeout: options.timeout,\n });\n\n // Execute play function in browser context\n const playResult = await executePlayFunction(page, testCase, options.timeout);\n\n if (playResult.error) {\n error = playResult.error;\n status = 'failed';\n steps.push(...playResult.steps);\n\n // Retry if not last attempt\n if (retryAttempt < maxAttempts - 1) {\n retryAttempt++;\n continue;\n }\n } else {\n status = 'passed';\n steps.push(...playResult.steps);\n }\n\n break; // Success, no retry needed\n } catch (e) {\n error = {\n message: e instanceof Error ? e.message : String(e),\n stack: e instanceof Error ? e.stack : undefined,\n };\n status = 'failed';\n\n if (retryAttempt < maxAttempts - 1) {\n retryAttempt++;\n continue;\n }\n break;\n }\n }\n\n const duration = performance.now() - startTime;\n\n // Run accessibility checks if enabled\n let accessibility: A11yResult | undefined;\n if (options.a11y && status === 'passed') {\n accessibility = await runA11yChecks(page);\n }\n\n // Capture screenshot for visual regression if enabled\n let screenshotPath: string | undefined;\n if (options.visual) {\n screenshotPath = await captureScreenshot(page, testCase, options.outputDir);\n }\n\n return {\n testCase,\n status,\n duration,\n steps,\n error,\n accessibility,\n screenshotPath,\n retryAttempt: retryAttempt > 0 ? retryAttempt : undefined,\n };\n}\n\n/**\n * Build URL for a variant\n */\nfunction buildVariantUrl(serverUrl: string, testCase: TestCase): string {\n const params = new URLSearchParams({\n component: testCase.component,\n variant: testCase.variant,\n isolated: 'true',\n });\n return `${serverUrl}?${params.toString()}`;\n}\n\n/**\n * Execute play function in browser context\n */\nasync function executePlayFunction(\n page: Page,\n testCase: TestCase,\n timeout: number\n): Promise<{ steps: StepResult[]; error?: TestError }> {\n const result = await page.evaluate(\n async ({ component, variant, timeout }: { component: string; variant: string; timeout: number }) => {\n // Find the segment definition in the global registry\n const registry = (window as unknown as { __SEGMENTS_REGISTRY__?: Map<string, unknown> })\n .__SEGMENTS_REGISTRY__;\n\n if (!registry) {\n return {\n steps: [],\n error: { message: 'Segments registry not found. Make sure the viewer is loaded.' },\n };\n }\n\n const segment = registry.get(component) as {\n variants?: Array<{\n name: string;\n play?: (ctx: {\n canvasElement: HTMLElement;\n args: Record<string, unknown>;\n step: (name: string, fn: () => Promise<void>) => Promise<void>;\n }) => Promise<void>;\n }>;\n } | undefined;\n\n if (!segment) {\n return {\n steps: [],\n error: { message: `Component \"${component}\" not found in registry` },\n };\n }\n\n const variantDef = segment.variants?.find((v) => v.name === variant);\n if (!variantDef || !variantDef.play) {\n return {\n steps: [],\n error: { message: `Variant \"${variant}\" not found or has no play function` },\n };\n }\n\n // Find the preview container\n const canvasElement = document.querySelector('[data-preview-container=\"true\"]') as HTMLElement;\n if (!canvasElement) {\n return {\n steps: [],\n error: { message: 'Preview container not found' },\n };\n }\n\n // Track steps\n const steps: Array<{\n name: string;\n status: 'passed' | 'failed';\n duration: number;\n error?: { message: string };\n }> = [];\n\n const step = async (name: string, fn: () => Promise<void>): Promise<void> => {\n const stepStart = performance.now();\n try {\n await fn();\n steps.push({\n name,\n status: 'passed',\n duration: performance.now() - stepStart,\n });\n } catch (e) {\n steps.push({\n name,\n status: 'failed',\n duration: performance.now() - stepStart,\n error: { message: e instanceof Error ? e.message : String(e) },\n });\n throw e;\n }\n };\n\n // Execute with timeout\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => reject(new Error(`Test timed out after ${timeout}ms`)), timeout);\n });\n\n try {\n await Promise.race([\n variantDef.play({\n canvasElement,\n args: {},\n step,\n }),\n timeoutPromise,\n ]);\n\n // If no explicit steps, add one for the whole play function\n if (steps.length === 0) {\n steps.push({\n name: 'Play function',\n status: 'passed',\n duration: 0,\n });\n }\n\n return { steps, error: undefined };\n } catch (e) {\n // If no steps failed explicitly, add one\n if (!steps.some((s) => s.status === 'failed')) {\n steps.push({\n name: 'Play function',\n status: 'failed',\n duration: 0,\n error: { message: e instanceof Error ? e.message : String(e) },\n });\n }\n\n return {\n steps,\n error: { message: e instanceof Error ? e.message : String(e) },\n };\n }\n },\n { component: testCase.component, variant: testCase.variant, timeout }\n );\n\n return result as { steps: StepResult[]; error?: TestError };\n}\n\n/**\n * Run accessibility checks using axe-core\n */\nasync function runA11yChecks(page: Page): Promise<A11yResult> {\n try {\n // Inject axe-core if not already present\n await page.evaluate(() => {\n if ((window as unknown as { axe?: unknown }).axe) return;\n\n return new Promise<void>((resolve, reject) => {\n const script = document.createElement('script');\n script.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.8.2/axe.min.js';\n script.onload = () => resolve();\n script.onerror = () => reject(new Error('Failed to load axe-core'));\n document.head.appendChild(script);\n });\n });\n\n // Run axe-core analysis\n const results = await page.evaluate(async () => {\n const axe = (window as unknown as { axe: { run: (el: HTMLElement) => Promise<{ violations: unknown[]; passes: unknown[] }> } }).axe;\n const container = document.querySelector('[data-preview-container=\"true\"]') as HTMLElement;\n if (!container) {\n return { violations: [], passes: 0 };\n }\n const axeResults = await axe.run(container);\n return {\n violations: axeResults.violations,\n passes: axeResults.passes.length,\n };\n });\n\n return {\n violations: results.violations as A11yViolation[],\n passes: results.passes,\n };\n } catch {\n return { violations: [], passes: 0 };\n }\n}\n\n/**\n * Capture screenshot for visual regression\n */\nasync function captureScreenshot(\n page: Page,\n testCase: TestCase,\n outputDir: string\n): Promise<string> {\n const { mkdir, writeFile } = await import('node:fs/promises');\n const { join } = await import('node:path');\n\n const screenshotsDir = join(outputDir, 'screenshots');\n await mkdir(screenshotsDir, { recursive: true });\n\n const filename = `${testCase.component}--${testCase.variant}.png`\n .replace(/\\s+/g, '-')\n .toLowerCase();\n const filepath = join(screenshotsDir, filename);\n\n const container = await page.$('[data-preview-container=\"true\"]');\n if (container) {\n const screenshot = await container.screenshot();\n await writeFile(filepath, screenshot);\n }\n\n return filepath;\n}\n\n/**\n * Aggregate test results into suites by component\n */\nfunction aggregateResults(results: TestResult[]): TestSuite[] {\n const grouped = groupTestsByComponent(results.map((r) => r.testCase));\n const suites: TestSuite[] = [];\n\n for (const [componentName, testCases] of grouped) {\n const componentResults = results.filter((r) => r.testCase.component === componentName);\n\n suites.push({\n name: componentName,\n tests: componentResults,\n duration: componentResults.reduce((sum, r) => sum + r.duration, 0),\n passed: componentResults.filter((r) => r.status === 'passed').length,\n failed: componentResults.filter((r) => r.status === 'failed').length,\n skipped: componentResults.filter((r) => r.status === 'skipped').length,\n });\n }\n\n return suites;\n}\n","/**\n * Console reporter - pretty terminal output\n */\n\nimport pc from 'picocolors';\nimport type { TestCase, TestResult, TestRunResult, TestReporter } from '../types.js';\n\nexport interface ConsoleReporterOptions {\n /** Show verbose output including all steps */\n verbose?: boolean;\n /** Show timing for each test */\n showTiming?: boolean;\n}\n\n/**\n * Create a console reporter\n */\nexport function createConsoleReporter(options: ConsoleReporterOptions = {}): TestReporter {\n const { verbose = false, showTiming = true } = options;\n\n let startTime: number;\n let testCount: number;\n let currentIndex: number;\n\n return {\n onRunStart(count: number) {\n testCount = count;\n currentIndex = 0;\n startTime = Date.now();\n\n console.log();\n console.log(pc.cyan(pc.bold('Segments Test Runner')));\n console.log(pc.dim(`Running ${count} test${count === 1 ? '' : 's'}...`));\n console.log();\n },\n\n onTestStart(testCase: TestCase) {\n currentIndex++;\n if (verbose) {\n const progress = pc.dim(`[${currentIndex}/${testCount}]`);\n console.log(`${progress} ${pc.dim('Running')} ${testCase.component} › ${testCase.variant}`);\n }\n },\n\n onTestComplete(result: TestResult) {\n const { testCase, status, duration, steps, error, accessibility } = result;\n const timing = showTiming ? pc.dim(` (${formatDuration(duration)})`) : '';\n\n const statusIcon = getStatusIcon(status);\n const testName = `${testCase.component} › ${testCase.variant}`;\n\n if (status === 'passed') {\n console.log(` ${statusIcon} ${testName}${timing}`);\n\n // Show a11y results if present\n if (accessibility && accessibility.violations.length > 0) {\n console.log(\n pc.yellow(` ⚠ ${accessibility.violations.length} accessibility violation(s)`)\n );\n }\n } else if (status === 'failed') {\n console.log(` ${statusIcon} ${pc.red(testName)}${timing}`);\n\n // Show error message\n if (error) {\n console.log(pc.red(` ${error.message}`));\n if (verbose && error.stack) {\n console.log(pc.dim(` ${error.stack.split('\\n').slice(1, 4).join('\\n ')}`));\n }\n }\n\n // Show failed steps\n if (verbose || steps.some((s) => s.status === 'failed')) {\n for (const step of steps) {\n if (step.status === 'failed') {\n console.log(pc.red(` ✗ ${step.name}`));\n if (step.error) {\n console.log(pc.red(` ${step.error.message}`));\n }\n } else if (verbose && step.status === 'passed') {\n console.log(pc.dim(` ✓ ${step.name}`));\n }\n }\n }\n\n // Show retry info\n if (result.retryAttempt) {\n console.log(pc.dim(` (failed after ${result.retryAttempt + 1} attempts)`));\n }\n } else if (status === 'skipped') {\n console.log(` ${statusIcon} ${pc.dim(testName)} ${pc.dim('(skipped)')}`);\n }\n\n // Show all steps in verbose mode\n if (verbose && status === 'passed' && steps.length > 0) {\n for (const step of steps) {\n const stepTiming = showTiming ? pc.dim(` ${formatDuration(step.duration)}`) : '';\n console.log(pc.dim(` ✓ ${step.name}${stepTiming}`));\n }\n }\n },\n\n onRunComplete(result: TestRunResult) {\n const { totalTests, totalPassed, totalFailed, totalSkipped, totalDuration, suites } = result;\n\n console.log();\n console.log(pc.dim('─'.repeat(50)));\n console.log();\n\n // Summary by suite\n if (suites.length > 1) {\n console.log(pc.bold('Test Suites:'));\n for (const suite of suites) {\n const statusIcon = suite.failed > 0 ? pc.red('✗') : pc.green('✓');\n const failedText = suite.failed > 0 ? pc.red(`${suite.failed} failed, `) : '';\n const passedText = suite.passed > 0 ? pc.green(`${suite.passed} passed`) : '';\n const skippedText = suite.skipped > 0 ? pc.dim(`, ${suite.skipped} skipped`) : '';\n console.log(` ${statusIcon} ${suite.name} (${failedText}${passedText}${skippedText})`);\n }\n console.log();\n }\n\n // Overall summary\n console.log(pc.bold('Tests:'));\n const parts: string[] = [];\n\n if (totalFailed > 0) {\n parts.push(pc.red(`${totalFailed} failed`));\n }\n if (totalPassed > 0) {\n parts.push(pc.green(`${totalPassed} passed`));\n }\n if (totalSkipped > 0) {\n parts.push(pc.dim(`${totalSkipped} skipped`));\n }\n parts.push(`${totalTests} total`);\n\n console.log(` ${parts.join(', ')}`);\n console.log(` ${pc.dim('Time:')} ${formatDuration(totalDuration)}`);\n\n // A11y summary if applicable\n if (result.totalA11yViolations !== undefined) {\n if (result.totalA11yViolations > 0) {\n console.log(\n ` ${pc.yellow('Accessibility:')} ${result.totalA11yViolations} violation(s)`\n );\n } else {\n console.log(` ${pc.green('Accessibility:')} All checks passed`);\n }\n }\n\n console.log();\n\n // Final status\n if (totalFailed > 0) {\n console.log(pc.red(pc.bold('Test run failed')));\n } else {\n console.log(pc.green(pc.bold('Test run passed')));\n }\n console.log();\n },\n };\n}\n\n/**\n * Get status icon with color\n */\nfunction getStatusIcon(status: TestResult['status']): string {\n switch (status) {\n case 'passed':\n return pc.green('✓');\n case 'failed':\n return pc.red('✗');\n case 'skipped':\n return pc.dim('○');\n default:\n return ' ';\n }\n}\n\n/**\n * Format duration in human-readable form\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`;\n }\n if (ms < 60000) {\n return `${(ms / 1000).toFixed(2)}s`;\n }\n const minutes = Math.floor(ms / 60000);\n const seconds = ((ms % 60000) / 1000).toFixed(1);\n return `${minutes}m ${seconds}s`;\n}\n","/**\n * JUnit XML reporter - CI/CD integration\n *\n * Generates JUnit XML format compatible with:\n * - GitHub Actions (mikepenz/action-junit-report)\n * - Jenkins\n * - GitLab CI\n * - CircleCI\n * - Azure DevOps\n */\n\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport type { TestRunResult, TestReporter, TestResult, TestSuite } from '../types.js';\n\nexport interface JUnitReporterOptions {\n /** Output file path */\n outputPath: string;\n /** Suite name for the root element */\n suiteName?: string;\n /** Include properties in the XML */\n includeProperties?: boolean;\n}\n\n/**\n * Create a JUnit XML reporter\n */\nexport function createJUnitReporter(options: JUnitReporterOptions): TestReporter {\n const { outputPath, suiteName = 'Segments Tests', includeProperties = true } = options;\n\n return {\n async onRunComplete(result: TestRunResult) {\n const xml = generateJUnitXml(result, suiteName, includeProperties);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n // Write the XML file\n await writeFile(outputPath, xml, 'utf-8');\n },\n };\n}\n\n/**\n * Generate JUnit XML from test results\n */\nfunction generateJUnitXml(\n result: TestRunResult,\n suiteName: string,\n includeProperties: boolean\n): string {\n const lines: string[] = [];\n\n // XML declaration\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n\n // Root testsuites element\n lines.push(\n `<testsuites name=\"${escapeXml(suiteName)}\" tests=\"${result.totalTests}\" failures=\"${result.totalFailed}\" skipped=\"${result.totalSkipped}\" time=\"${(result.totalDuration / 1000).toFixed(3)}\">`\n );\n\n // Generate each test suite\n for (const suite of result.suites) {\n lines.push(generateTestSuiteXml(suite, includeProperties));\n }\n\n lines.push('</testsuites>');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate XML for a single test suite\n */\nfunction generateTestSuiteXml(suite: TestSuite, includeProperties: boolean): string {\n const lines: string[] = [];\n\n // Testsuite element\n lines.push(\n ` <testsuite name=\"${escapeXml(suite.name)}\" tests=\"${suite.tests.length}\" failures=\"${suite.failed}\" skipped=\"${suite.skipped}\" time=\"${(suite.duration / 1000).toFixed(3)}\">`\n );\n\n // Properties (optional)\n if (includeProperties) {\n lines.push(' <properties>');\n lines.push(` <property name=\"component\" value=\"${escapeXml(suite.name)}\"/>`);\n lines.push(' </properties>');\n }\n\n // Test cases\n for (const test of suite.tests) {\n lines.push(generateTestCaseXml(test));\n }\n\n lines.push(' </testsuite>');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate XML for a single test case\n */\nfunction generateTestCaseXml(result: TestResult): string {\n const { testCase, status, duration, error, steps, accessibility } = result;\n const lines: string[] = [];\n\n const testName = testCase.variant;\n const className = testCase.component;\n const time = (duration / 1000).toFixed(3);\n\n // Opening tag\n if (status === 'passed' && !accessibility?.violations.length) {\n // Simple passed test - self-closing tag\n lines.push(` <testcase name=\"${escapeXml(testName)}\" classname=\"${escapeXml(className)}\" time=\"${time}\"/>`);\n } else {\n // Test with failure, skip, or a11y info\n lines.push(` <testcase name=\"${escapeXml(testName)}\" classname=\"${escapeXml(className)}\" time=\"${time}\">`);\n\n if (status === 'failed') {\n // Failure element\n const message = error?.message || 'Test failed';\n lines.push(` <failure message=\"${escapeXml(message)}\" type=\"AssertionError\">`);\n\n // Add detailed failure info\n const details: string[] = [];\n\n // Add step failures\n const failedSteps = steps.filter((s) => s.status === 'failed');\n if (failedSteps.length > 0) {\n details.push('Failed steps:');\n for (const step of failedSteps) {\n details.push(` - ${step.name}: ${step.error?.message || 'Failed'}`);\n }\n }\n\n // Add stack trace if available\n if (error?.stack) {\n details.push('');\n details.push('Stack trace:');\n details.push(error.stack);\n }\n\n if (details.length > 0) {\n lines.push(escapeXml(details.join('\\n')));\n }\n\n lines.push(' </failure>');\n } else if (status === 'skipped') {\n lines.push(' <skipped/>');\n }\n\n // Add system-out for accessibility violations\n if (accessibility?.violations.length) {\n lines.push(' <system-out>');\n lines.push(`Accessibility violations (${accessibility.violations.length}):`);\n for (const violation of accessibility.violations) {\n lines.push(` [${violation.impact}] ${violation.id}: ${violation.description}`);\n lines.push(` Help: ${violation.help}`);\n for (const node of violation.nodes.slice(0, 3)) {\n lines.push(` Element: ${node.html.substring(0, 100)}`);\n }\n if (violation.nodes.length > 3) {\n lines.push(` ... and ${violation.nodes.length - 3} more elements`);\n }\n }\n lines.push(' </system-out>');\n }\n\n lines.push(' </testcase>');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Escape special XML characters\n */\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/g, ''); // Remove invalid XML characters\n}\n","/**\n * JSON reporter - machine-readable output\n *\n * Outputs structured JSON for:\n * - AI analysis and processing\n * - Custom dashboards\n * - Integration with other tools\n */\n\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport type { TestRunResult, TestReporter } from '../types.js';\n\nexport interface JsonReporterOptions {\n /** Output file path */\n outputPath: string;\n /** Pretty print the JSON */\n pretty?: boolean;\n /** Include full step details */\n includeSteps?: boolean;\n /** Include stack traces in errors */\n includeStacks?: boolean;\n}\n\n/**\n * JSON report structure\n */\nexport interface JsonReport {\n /** Report metadata */\n meta: {\n /** Report version */\n version: string;\n /** Test run start time */\n startTime: string;\n /** Test run end time */\n endTime: string;\n /** Total duration in milliseconds */\n duration: number;\n };\n /** Summary statistics */\n summary: {\n total: number;\n passed: number;\n failed: number;\n skipped: number;\n passRate: number;\n a11yViolations?: number;\n };\n /** Test suites with results */\n suites: Array<{\n name: string;\n tests: number;\n passed: number;\n failed: number;\n skipped: number;\n duration: number;\n results: Array<{\n id: string;\n component: string;\n variant: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n steps?: Array<{\n name: string;\n status: 'passed' | 'failed' | 'skipped';\n duration: number;\n error?: string;\n }>;\n error?: {\n message: string;\n stack?: string;\n };\n accessibility?: {\n violations: number;\n passes: number;\n details?: Array<{\n id: string;\n impact: string;\n description: string;\n elements: number;\n }>;\n };\n retryAttempt?: number;\n }>;\n }>;\n}\n\n/**\n * Create a JSON reporter\n */\nexport function createJsonReporter(options: JsonReporterOptions): TestReporter {\n const { outputPath, pretty = true, includeSteps = true, includeStacks = false } = options;\n\n return {\n async onRunComplete(result: TestRunResult) {\n const report = generateJsonReport(result, includeSteps, includeStacks);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n // Write the JSON file\n const json = pretty ? JSON.stringify(report, null, 2) : JSON.stringify(report);\n await writeFile(outputPath, json, 'utf-8');\n },\n };\n}\n\n/**\n * Generate JSON report from test results\n */\nfunction generateJsonReport(\n result: TestRunResult,\n includeSteps: boolean,\n includeStacks: boolean\n): JsonReport {\n const { suites, totalTests, totalPassed, totalFailed, totalSkipped, totalDuration, startTime, endTime } = result;\n\n return {\n meta: {\n version: '1.0.0',\n startTime: startTime.toISOString(),\n endTime: endTime.toISOString(),\n duration: totalDuration,\n },\n summary: {\n total: totalTests,\n passed: totalPassed,\n failed: totalFailed,\n skipped: totalSkipped,\n passRate: totalTests > 0 ? Math.round((totalPassed / totalTests) * 100) : 0,\n a11yViolations: result.totalA11yViolations,\n },\n suites: suites.map((suite) => ({\n name: suite.name,\n tests: suite.tests.length,\n passed: suite.passed,\n failed: suite.failed,\n skipped: suite.skipped,\n duration: suite.duration,\n results: suite.tests.map((test) => {\n const resultObj: JsonReport['suites'][0]['results'][0] = {\n id: test.testCase.id,\n component: test.testCase.component,\n variant: test.testCase.variant,\n status: test.status,\n duration: test.duration,\n };\n\n // Include steps if requested\n if (includeSteps && test.steps.length > 0) {\n resultObj.steps = test.steps.map((step) => ({\n name: step.name,\n status: step.status,\n duration: step.duration,\n error: step.error?.message,\n }));\n }\n\n // Include error if present\n if (test.error) {\n resultObj.error = {\n message: test.error.message,\n stack: includeStacks ? test.error.stack : undefined,\n };\n }\n\n // Include accessibility results if present\n if (test.accessibility) {\n resultObj.accessibility = {\n violations: test.accessibility.violations.length,\n passes: test.accessibility.passes,\n details: test.accessibility.violations.map((v) => ({\n id: v.id,\n impact: v.impact,\n description: v.description,\n elements: v.nodes.length,\n })),\n };\n }\n\n // Include retry info if applicable\n if (test.retryAttempt) {\n resultObj.retryAttempt = test.retryAttempt;\n }\n\n return resultObj;\n }),\n })),\n };\n}\n","/**\n * Watch mode - file watcher with selective re-run\n */\n\nimport { watch } from 'node:fs';\nimport { resolve, relative } from 'node:path';\nimport pc from 'picocolors';\nimport type { SegmentsConfig } from '../core/index.js';\nimport { discoverSegmentFiles } from '../core/node.js';\nimport type { TestCase, RunnerOptions, TestReporter } from './types.js';\nimport { discoverTests } from './discovery.js';\nimport { runTests } from './runner.js';\n\nexport interface WatchOptions {\n /** Debounce delay in milliseconds */\n debounceMs?: number;\n /** Clear console on each run */\n clearConsole?: boolean;\n /** Run all tests initially */\n runOnStart?: boolean;\n}\n\n/**\n * Start watch mode\n */\nexport async function startWatchMode(\n config: SegmentsConfig,\n configDir: string,\n runnerOptions: RunnerOptions,\n reporters: TestReporter[],\n options: WatchOptions = {}\n): Promise<void> {\n const { debounceMs = 300, clearConsole = true, runOnStart = true } = options;\n\n let debounceTimer: NodeJS.Timeout | null = null;\n let isRunning = false;\n let pendingFiles = new Set<string>();\n\n // Get files to watch\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n const watchPaths = new Set<string>();\n\n for (const file of segmentFiles) {\n watchPaths.add(file.absolutePath);\n }\n\n // Also watch the directories containing segment files\n const watchDirs = new Set<string>();\n for (const path of watchPaths) {\n const dir = resolve(path, '..');\n watchDirs.add(dir);\n }\n\n console.log();\n console.log(pc.cyan(pc.bold('Segments Test Runner - Watch Mode')));\n console.log(pc.dim(`Watching ${watchPaths.size} files in ${watchDirs.size} directories`));\n console.log(pc.dim('Press Ctrl+C to stop'));\n console.log();\n\n // Function to run tests\n const runTestsForFiles = async (changedFiles: string[]): Promise<void> => {\n if (isRunning) {\n // Queue up changed files for next run\n for (const file of changedFiles) {\n pendingFiles.add(file);\n }\n return;\n }\n\n isRunning = true;\n\n try {\n if (clearConsole) {\n console.clear();\n }\n\n console.log(pc.cyan('Changes detected, running tests...'));\n console.log(pc.dim(`Changed: ${changedFiles.map((f) => relative(configDir, f)).join(', ')}`));\n console.log();\n\n // Discover tests (filter to changed files if possible)\n const allTests = await discoverTests(config, configDir, {});\n\n // Filter to tests from changed files\n const changedRelativePaths = changedFiles.map((f) => relative(configDir, f));\n const testsToRun = changedRelativePaths.length > 0\n ? allTests.filter((t) => changedRelativePaths.some((p) => t.sourceFile.includes(p)))\n : allTests;\n\n if (testsToRun.length === 0) {\n console.log(pc.yellow('No tests found in changed files'));\n console.log();\n return;\n }\n\n // Run the tests\n await runTests(testsToRun, runnerOptions, reporters);\n } catch (error) {\n console.error(pc.red('Error running tests:'), error);\n } finally {\n isRunning = false;\n\n // Check if there are pending files to run\n if (pendingFiles.size > 0) {\n const files = Array.from(pendingFiles);\n pendingFiles.clear();\n await runTestsForFiles(files);\n }\n }\n };\n\n // Run initial tests if configured\n if (runOnStart) {\n const allTests = await discoverTests(config, configDir, {});\n if (allTests.length > 0) {\n await runTests(allTests, runnerOptions, reporters);\n } else {\n console.log(pc.yellow('No tests with play functions found'));\n }\n console.log();\n console.log(pc.dim('Watching for changes...'));\n console.log();\n }\n\n // Set up file watchers\n const watchers: ReturnType<typeof watch>[] = [];\n\n for (const dir of watchDirs) {\n try {\n const watcher = watch(dir, { recursive: false }, (eventType, filename) => {\n if (!filename) return;\n\n const fullPath = resolve(dir, filename);\n\n // Check if this is a segment file we care about\n if (!watchPaths.has(fullPath)) return;\n\n // Debounce the run\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n pendingFiles.add(fullPath);\n\n debounceTimer = setTimeout(() => {\n const files = Array.from(pendingFiles);\n pendingFiles.clear();\n runTestsForFiles(files);\n }, debounceMs);\n });\n\n watchers.push(watcher);\n } catch (error) {\n console.warn(pc.yellow(`Warning: Could not watch directory ${dir}`), error);\n }\n }\n\n // Handle process termination\n const cleanup = () => {\n console.log();\n console.log(pc.dim('Stopping watch mode...'));\n\n for (const watcher of watchers) {\n watcher.close();\n }\n\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n\n process.exit(0);\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n // Keep process alive\n await new Promise(() => {\n // This promise never resolves, keeping the process alive\n // until terminated\n });\n}\n\n/**\n * Interactive watch mode with keyboard controls\n */\nexport async function startInteractiveWatchMode(\n config: SegmentsConfig,\n configDir: string,\n runnerOptions: RunnerOptions,\n reporters: TestReporter[]\n): Promise<void> {\n let lastFailedTests: TestCase[] = [];\n\n // Start basic watch mode\n await startWatchMode(config, configDir, runnerOptions, reporters, {\n runOnStart: true,\n clearConsole: true,\n });\n}\n"],"mappings":"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","names":["resolve","join","mkdir","pc","timeout","resolve","mkdir","writeFile","join","writeFile","mkdir","dirname","pc","pc","resolve","pc","mkdir","join"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
parseTokenFiles
|
|
4
|
+
} from "./chunk-MUZ6CM66.js";
|
|
5
|
+
import {
|
|
6
|
+
loadConfig
|
|
7
|
+
} from "./chunk-OAENNG3G.js";
|
|
8
|
+
import "./chunk-LY2CFFPY.js";
|
|
9
|
+
import {
|
|
10
|
+
BRAND
|
|
11
|
+
} from "./chunk-XHNKNI6J.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/tokens.ts
|
|
14
|
+
import pc from "picocolors";
|
|
15
|
+
async function tokens(options) {
|
|
16
|
+
const errors = [];
|
|
17
|
+
try {
|
|
18
|
+
console.log(pc.cyan(`
|
|
19
|
+
${BRAND.name} Token Discovery
|
|
20
|
+
`));
|
|
21
|
+
const { config, configDir } = await loadConfig(options.config);
|
|
22
|
+
if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {
|
|
23
|
+
console.log(pc.yellow("No token configuration found.\n"));
|
|
24
|
+
console.log(pc.dim("Add 'tokens' config to fragments.config.ts:"));
|
|
25
|
+
console.log(pc.dim(`
|
|
26
|
+
tokens: {
|
|
27
|
+
include: ['src/styles/theme.scss', 'src/styles/variables.css'],
|
|
28
|
+
themeSelectors: {
|
|
29
|
+
':root': 'default',
|
|
30
|
+
'[data-theme="dark"]': 'dark',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
`));
|
|
34
|
+
return { success: false, tokenCount: 0, errors: ["No token configuration"] };
|
|
35
|
+
}
|
|
36
|
+
console.log(pc.dim(`Scanning files: ${config.tokens.include.join(", ")}
|
|
37
|
+
`));
|
|
38
|
+
const parseResult = await parseTokenFiles(config.tokens, configDir);
|
|
39
|
+
if (parseResult.errors.length > 0) {
|
|
40
|
+
console.log(pc.yellow("Parse errors:"));
|
|
41
|
+
for (const err of parseResult.errors) {
|
|
42
|
+
console.log(pc.red(` ${err.file}: ${err.message}`));
|
|
43
|
+
errors.push(`${err.file}: ${err.message}`);
|
|
44
|
+
}
|
|
45
|
+
console.log();
|
|
46
|
+
}
|
|
47
|
+
if (parseResult.warnings.length > 0 && options.verbose) {
|
|
48
|
+
console.log(pc.yellow("Warnings:"));
|
|
49
|
+
for (const warning of parseResult.warnings) {
|
|
50
|
+
console.log(pc.dim(` ${warning}`));
|
|
51
|
+
}
|
|
52
|
+
console.log();
|
|
53
|
+
}
|
|
54
|
+
let tokens2 = parseResult.tokens;
|
|
55
|
+
if (options.theme) {
|
|
56
|
+
tokens2 = tokens2.filter(
|
|
57
|
+
(t) => t.theme === options.theme || t.theme === "default"
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (options.category) {
|
|
61
|
+
tokens2 = tokens2.filter((t) => t.category === options.category);
|
|
62
|
+
}
|
|
63
|
+
if (tokens2.length === 0) {
|
|
64
|
+
console.log(pc.yellow("No tokens found.\n"));
|
|
65
|
+
console.log(pc.dim("Make sure your CSS files contain CSS custom properties (--token-name: value;)"));
|
|
66
|
+
return { success: true, tokenCount: 0, errors };
|
|
67
|
+
}
|
|
68
|
+
if (options.json) {
|
|
69
|
+
outputJson(tokens2, parseResult.parseTimeMs);
|
|
70
|
+
} else if (options.categories) {
|
|
71
|
+
outputByCategory(tokens2, parseResult.parseTimeMs);
|
|
72
|
+
} else {
|
|
73
|
+
outputList(tokens2, parseResult.parseTimeMs, options.verbose);
|
|
74
|
+
}
|
|
75
|
+
return { success: true, tokenCount: tokens2.length, errors };
|
|
76
|
+
} catch (error) {
|
|
77
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
78
|
+
console.error(pc.red("Error:"), message);
|
|
79
|
+
errors.push(message);
|
|
80
|
+
return { success: false, tokenCount: 0, errors };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function outputJson(tokens2, parseTimeMs) {
|
|
84
|
+
const output = {
|
|
85
|
+
tokens: tokens2,
|
|
86
|
+
meta: {
|
|
87
|
+
totalTokens: tokens2.length,
|
|
88
|
+
parseTimeMs,
|
|
89
|
+
discoveredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
console.log(JSON.stringify(output, null, 2));
|
|
93
|
+
}
|
|
94
|
+
function outputByCategory(tokens2, parseTimeMs) {
|
|
95
|
+
const byCategory = /* @__PURE__ */ new Map();
|
|
96
|
+
for (const token of tokens2) {
|
|
97
|
+
const list = byCategory.get(token.category) || [];
|
|
98
|
+
list.push(token);
|
|
99
|
+
byCategory.set(token.category, list);
|
|
100
|
+
}
|
|
101
|
+
const categories = Array.from(byCategory.keys()).sort();
|
|
102
|
+
for (const category of categories) {
|
|
103
|
+
const categoryTokens = byCategory.get(category) || [];
|
|
104
|
+
console.log(pc.bold(`${category} (${categoryTokens.length})`));
|
|
105
|
+
console.log(pc.dim("\u2500".repeat(40)));
|
|
106
|
+
for (const token of categoryTokens.slice(0, 10)) {
|
|
107
|
+
const levelLabel = token.level === 1 ? "base" : token.level === 2 ? "semantic" : "component";
|
|
108
|
+
console.log(` ${pc.cyan(token.name)}`);
|
|
109
|
+
console.log(` ${pc.dim("Value:")} ${token.resolvedValue}`);
|
|
110
|
+
console.log(` ${pc.dim("Level:")} ${levelLabel} ${pc.dim(`(${token.theme})`)}`);
|
|
111
|
+
}
|
|
112
|
+
if (categoryTokens.length > 10) {
|
|
113
|
+
console.log(pc.dim(` ... and ${categoryTokens.length - 10} more`));
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
}
|
|
117
|
+
console.log(pc.dim("\u2500".repeat(40)));
|
|
118
|
+
console.log(pc.green(`\u2713 Found ${tokens2.length} token(s) in ${categories.length} categories`));
|
|
119
|
+
console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms
|
|
120
|
+
`));
|
|
121
|
+
}
|
|
122
|
+
function outputList(tokens2, parseTimeMs, verbose) {
|
|
123
|
+
const byTheme = /* @__PURE__ */ new Map();
|
|
124
|
+
for (const token of tokens2) {
|
|
125
|
+
const list = byTheme.get(token.theme) || [];
|
|
126
|
+
list.push(token);
|
|
127
|
+
byTheme.set(token.theme, list);
|
|
128
|
+
}
|
|
129
|
+
const themes = Array.from(byTheme.keys()).sort();
|
|
130
|
+
for (const theme of themes) {
|
|
131
|
+
const themeTokens = byTheme.get(theme) || [];
|
|
132
|
+
if (themes.length > 1) {
|
|
133
|
+
console.log(pc.bold(`Theme: ${theme} (${themeTokens.length} tokens)`));
|
|
134
|
+
console.log(pc.dim("\u2500".repeat(50)));
|
|
135
|
+
}
|
|
136
|
+
themeTokens.sort((a, b) => a.name.localeCompare(b.name));
|
|
137
|
+
console.log(
|
|
138
|
+
pc.dim(
|
|
139
|
+
`${"Token Name".padEnd(32)} ${"Value".padEnd(20)} ${"Category".padEnd(12)}`
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
console.log(pc.dim("\u2500".repeat(70)));
|
|
143
|
+
const displayTokens = verbose ? themeTokens : themeTokens.slice(0, 30);
|
|
144
|
+
for (const token of displayTokens) {
|
|
145
|
+
const name = token.name.length > 30 ? token.name.slice(0, 27) + "..." : token.name;
|
|
146
|
+
const value = token.resolvedValue.length > 18 ? token.resolvedValue.slice(0, 15) + "..." : token.resolvedValue;
|
|
147
|
+
console.log(
|
|
148
|
+
`${pc.cyan(name.padEnd(32))} ${value.padEnd(20)} ${pc.dim(token.category.padEnd(12))}`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
if (!verbose && themeTokens.length > 30) {
|
|
152
|
+
console.log(pc.dim(`
|
|
153
|
+
... and ${themeTokens.length - 30} more (use --verbose to show all)`));
|
|
154
|
+
}
|
|
155
|
+
console.log();
|
|
156
|
+
}
|
|
157
|
+
console.log(pc.dim("\u2500".repeat(50)));
|
|
158
|
+
console.log(pc.green(`\u2713 Found ${tokens2.length} token(s)`));
|
|
159
|
+
const categoryCounts = {};
|
|
160
|
+
for (const token of tokens2) {
|
|
161
|
+
categoryCounts[token.category] = (categoryCounts[token.category] || 0) + 1;
|
|
162
|
+
}
|
|
163
|
+
const breakdown = Object.entries(categoryCounts).sort((a, b) => b[1] - a[1]).map(([cat, count]) => `${cat}: ${count}`).join(", ");
|
|
164
|
+
console.log(pc.dim(` ${breakdown}`));
|
|
165
|
+
console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms
|
|
166
|
+
`));
|
|
167
|
+
}
|
|
168
|
+
var tokens_default = tokens;
|
|
169
|
+
export {
|
|
170
|
+
tokens_default as default,
|
|
171
|
+
tokens
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=tokens-HSGMYK64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/tokens.ts"],"sourcesContent":["/**\n * CLI Tokens Command\n *\n * Discover and list design tokens from CSS/SCSS files.\n *\n * Usage:\n * fragments tokens # List all tokens\n * fragments tokens --json # Output as JSON\n * fragments tokens --categories # Group by category\n * fragments tokens --theme dark # Filter by theme\n */\n\nimport pc from \"picocolors\";\nimport { BRAND } from \"../core/index.js\";\nimport type { DesignToken, TokenCategory, TokenConfig } from \"../core/index.js\";\nimport { loadConfig } from \"../core/node.js\";\nimport { parseTokenFiles, createTokenRegistry } from \"../service/index.js\";\n\nexport interface TokensCommandOptions {\n config?: string;\n json?: boolean;\n categories?: boolean;\n theme?: string;\n category?: string;\n verbose?: boolean;\n}\n\nexport interface TokensCommandResult {\n success: boolean;\n tokenCount: number;\n errors: string[];\n}\n\n/**\n * Run the tokens command\n */\nexport async function tokens(\n options: TokensCommandOptions\n): Promise<TokensCommandResult> {\n const errors: string[] = [];\n\n try {\n console.log(pc.cyan(`\\n${BRAND.name} Token Discovery\\n`));\n\n // Load config\n const { config, configDir } = await loadConfig(options.config);\n\n // Check for token configuration\n if (!config.tokens || !config.tokens.include || config.tokens.include.length === 0) {\n console.log(pc.yellow(\"No token configuration found.\\n\"));\n console.log(pc.dim(\"Add 'tokens' config to fragments.config.ts:\"));\n console.log(pc.dim(`\n tokens: {\n include: ['src/styles/theme.scss', 'src/styles/variables.css'],\n themeSelectors: {\n ':root': 'default',\n '[data-theme=\"dark\"]': 'dark',\n },\n },\n`));\n return { success: false, tokenCount: 0, errors: [\"No token configuration\"] };\n }\n\n console.log(pc.dim(`Scanning files: ${config.tokens.include.join(\", \")}\\n`));\n\n // Parse token files\n const parseResult = await parseTokenFiles(config.tokens, configDir);\n\n if (parseResult.errors.length > 0) {\n console.log(pc.yellow(\"Parse errors:\"));\n for (const err of parseResult.errors) {\n console.log(pc.red(` ${err.file}: ${err.message}`));\n errors.push(`${err.file}: ${err.message}`);\n }\n console.log();\n }\n\n if (parseResult.warnings.length > 0 && options.verbose) {\n console.log(pc.yellow(\"Warnings:\"));\n for (const warning of parseResult.warnings) {\n console.log(pc.dim(` ${warning}`));\n }\n console.log();\n }\n\n let tokens = parseResult.tokens;\n\n // Filter by theme if specified\n if (options.theme) {\n tokens = tokens.filter(\n (t) => t.theme === options.theme || t.theme === \"default\"\n );\n }\n\n // Filter by category if specified\n if (options.category) {\n tokens = tokens.filter((t) => t.category === options.category);\n }\n\n if (tokens.length === 0) {\n console.log(pc.yellow(\"No tokens found.\\n\"));\n console.log(pc.dim(\"Make sure your CSS files contain CSS custom properties (--token-name: value;)\"));\n return { success: true, tokenCount: 0, errors };\n }\n\n // Output based on format\n if (options.json) {\n outputJson(tokens, parseResult.parseTimeMs);\n } else if (options.categories) {\n outputByCategory(tokens, parseResult.parseTimeMs);\n } else {\n outputList(tokens, parseResult.parseTimeMs, options.verbose);\n }\n\n return { success: true, tokenCount: tokens.length, errors };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(pc.red(\"Error:\"), message);\n errors.push(message);\n return { success: false, tokenCount: 0, errors };\n }\n}\n\n/**\n * Output tokens as JSON\n */\nfunction outputJson(tokens: DesignToken[], parseTimeMs: number): void {\n const output = {\n tokens,\n meta: {\n totalTokens: tokens.length,\n parseTimeMs,\n discoveredAt: new Date().toISOString(),\n },\n };\n\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Output tokens grouped by category\n */\nfunction outputByCategory(tokens: DesignToken[], parseTimeMs: number): void {\n // Group by category\n const byCategory = new Map<TokenCategory, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byCategory.get(token.category) || [];\n list.push(token);\n byCategory.set(token.category, list);\n }\n\n // Sort categories alphabetically\n const categories = Array.from(byCategory.keys()).sort();\n\n for (const category of categories) {\n const categoryTokens = byCategory.get(category) || [];\n console.log(pc.bold(`${category} (${categoryTokens.length})`));\n console.log(pc.dim(\"─\".repeat(40)));\n\n for (const token of categoryTokens.slice(0, 10)) {\n const levelLabel = token.level === 1 ? \"base\" : token.level === 2 ? \"semantic\" : \"component\";\n console.log(` ${pc.cyan(token.name)}`);\n console.log(` ${pc.dim(\"Value:\")} ${token.resolvedValue}`);\n console.log(` ${pc.dim(\"Level:\")} ${levelLabel} ${pc.dim(`(${token.theme})`)}`);\n }\n\n if (categoryTokens.length > 10) {\n console.log(pc.dim(` ... and ${categoryTokens.length - 10} more`));\n }\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(40)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s) in ${categories.length} categories`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\n/**\n * Output tokens as a simple list\n */\nfunction outputList(tokens: DesignToken[], parseTimeMs: number, verbose?: boolean): void {\n // Group by theme first\n const byTheme = new Map<string, DesignToken[]>();\n\n for (const token of tokens) {\n const list = byTheme.get(token.theme) || [];\n list.push(token);\n byTheme.set(token.theme, list);\n }\n\n const themes = Array.from(byTheme.keys()).sort();\n\n for (const theme of themes) {\n const themeTokens = byTheme.get(theme) || [];\n\n if (themes.length > 1) {\n console.log(pc.bold(`Theme: ${theme} (${themeTokens.length} tokens)`));\n console.log(pc.dim(\"─\".repeat(50)));\n }\n\n // Sort tokens by name\n themeTokens.sort((a, b) => a.name.localeCompare(b.name));\n\n // Table header\n console.log(\n pc.dim(\n `${\"Token Name\".padEnd(32)} ${\"Value\".padEnd(20)} ${\"Category\".padEnd(12)}`\n )\n );\n console.log(pc.dim(\"─\".repeat(70)));\n\n const displayTokens = verbose ? themeTokens : themeTokens.slice(0, 30);\n\n for (const token of displayTokens) {\n const name = token.name.length > 30 ? token.name.slice(0, 27) + \"...\" : token.name;\n const value = token.resolvedValue.length > 18 ? token.resolvedValue.slice(0, 15) + \"...\" : token.resolvedValue;\n\n console.log(\n `${pc.cyan(name.padEnd(32))} ${value.padEnd(20)} ${pc.dim(token.category.padEnd(12))}`\n );\n }\n\n if (!verbose && themeTokens.length > 30) {\n console.log(pc.dim(`\\n ... and ${themeTokens.length - 30} more (use --verbose to show all)`));\n }\n\n console.log();\n }\n\n // Summary\n console.log(pc.dim(\"─\".repeat(50)));\n console.log(pc.green(`✓ Found ${tokens.length} token(s)`));\n\n // Category breakdown\n const categoryCounts: Record<string, number> = {};\n for (const token of tokens) {\n categoryCounts[token.category] = (categoryCounts[token.category] || 0) + 1;\n }\n\n const breakdown = Object.entries(categoryCounts)\n .sort((a, b) => b[1] - a[1])\n .map(([cat, count]) => `${cat}: ${count}`)\n .join(\", \");\n\n console.log(pc.dim(` ${breakdown}`));\n console.log(pc.dim(` Parsed in ${parseTimeMs.toFixed(1)}ms\\n`));\n}\n\nexport default tokens;\n"],"mappings":"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","names":["tokens"]}
|